ESAHomeSpace EngineeringSystems
   
About us
Software Engineering and Standardisation
Software life cycle
Software building blocks
Software standardisation
Archive
Services
Useful linksContact us
FOR SECURITY REASONS, ALL LINKS TO THE ftp.estec.esa.int SERVER ARE DISABLED. YOU MAY REQUEST RELATED DOCUMENTS TO bssc@esa.int
 
 
 
 
 
printer friendly page
tcdemo.c
 
/*

/*

* Thermal Control Demonstration - POSIX Threads Version

*

* Copyright (c) 1997, ESTEC

*

* Written by Marizio Martignano, ESTEC

* Changes for POSIX Threads Version by Chris Nettleton

*/

#include <pthread.h>

#include <stddef.h>

#include <assert.h>

#include <time.h>

#ifndef M_1750

#include <fcntl.h>

#include <sched.h>

#endif

#define TM_DELAY 1

#define T1_LC 10

#define T1_LW 15

#define T1_HW 25

#define T1_HC 30

#define T1_DELAY 4

#define T1_STEP 2

#define T2_LC 0

#define T2_LW 10

#define T2_HW 40

#define T2_HC 50

#define T2_DELAY 3

#define T2_STEP 3

#define T3_LC 6

#define T3_LW 10

#define T3_HW 16

#define T3_HC 30

#define T3_DELAY 2

#define T3_STEP 1

#define TMIN 0

#define TMAX 60

#define BLEN 256

static int istat;

void

delay (void)

{

time_t now;

time_t wakeup;

now = time(NULL);

wakeup = now;

#ifdef M_1750

while (1) {

now = time(NULL);

if (now != wakeup) {

break;

}

sched_yield();

}

#else

sleep (secs);

#endif

}

/*

* Global data, each object protected by a mutex

*/

static struct tc

{

pthread_mutex_t m;

int temp;

int automatic;

int on;

int lw;

int hw;

int step;

int period;

}

t1, t2, t3;

char timebuf [BLEN + 1];

pthread_mutex_t timebuf_m;

char inputline [BLEN + 1];

pthread_mutex_t inputline_m;

int p_tele = 1;

pthread_mutex_t p_tele_m;

void

tc_init (struct tc *t, int low, int high, int _step, int _period)

{

pthread_mutex_init (&t->m, NULL);

t->temp = 0;

t->automatic = 0;

t->on = 0;

t->lw = low;

t->hw = high;

t->step = _step;

t->period = _period;

}

// Set the standard input,

// when needed

int

set_input (void)

{

#ifndef M_1750

int stat;

stat = fcntl (0, F_GETFL);

fcntl (0, F_SETFL, O_NDELAY);

return stat;

#else

return 0;

#endif

}

// Reset the standard input,

// when needed

void

reset_input (int stat)

{

#ifndef M_1750

fcntl (0, F_SETFL, stat);

#endif

}

/*

* Get a character from the standard input,

* without suspending

*/

int

nodelay_getchar (void)

{

int res;

char ch;

#ifndef M_1750

res = read (0, &ch, 1);

if (res)

{

return (int) ch;

}

else

{

return 0;

}

#endif

#ifdef M_1750

asm volatile ("xio %0,0x8501":"=r" (res));

if (res & 0x02)

{

asm volatile ("xio %0,0x8500":"=r" (ch));

return ch & 0xff;

}

else

return 0;

#endif

}

/*

* Body of the telemetry thread

* Print telemetry every TM_DELAY seconds

*/

void *

telemetry_body (void *arg)

{

for (;;)

{

int i, temp, automatic, on;

for (i = 0; i < TM_DELAY; i++) {

delay();

}

pthread_mutex_lock (&t1.m);

temp = t1.temp;

automatic = t1.automatic;

on = t1.on;

pthread_mutex_unlock (&t1.m);

printf ("T1:%d:%d:%d\n", temp, automatic, on);

pthread_mutex_lock (&t2.m);

temp = t2.temp;

automatic = t2.automatic;

on = t2.on;

pthread_mutex_unlock (&t2.m);

printf ("T2:%d:%d:%d\n", temp, automatic, on);

pthread_mutex_lock (&t3.m);

temp = t3.temp;

automatic = t3.automatic;

on = t3.on;

pthread_mutex_unlock (&t3.m);

printf ("T3:%d:%d:%d\n", temp, automatic, on);

pthread_mutex_lock (&timebuf_m);

printf ("TIME:%s\n", timebuf);

pthread_mutex_unlock (&timebuf_m);

pthread_mutex_lock (&inputline_m);

printf ("INPUT:%s\n", inputline);

pthread_mutex_unlock (&inputline_m);

}

}

/*

* Body for Thermal_control Threads:

*/

void *

thermal_control_body (void *tc_ptr)

{

struct tc *t = (struct tc *) tc_ptr;

for (;;) {

int i;

for (i = 0; i < t->period; i++) {

delay();

}

/****

printf("l = %d, h = %d, a = %d, s = %d, o = %d, t = %d\n",

t->lw, t->hw, t->automatic, t->step, t->on, t->temp);

****/

if (t->automatic) {

if (t->temp < t->lw) {

if (t->on == 0) {

t->on = 1;

continue;

}

}

if (t->temp > t->hw) {

if (t->on == 1) {

t->on = 0;

continue;

}

}

}

if (t->on) {

t->temp += t->step;

if (t->temp > TMAX) {

t->temp = TMAX;

}

} else {

t->temp -= t->step;

if (t->temp < TMIN) {

t->temp = TMIN;

}

}

}

}

// Body for command interpreter thread

//

void *

reader_body (void *arg)

{

int pos = 0;

char ch;

for (;;)

{

// Get character

ch = nodelay_getchar ();

// Process character

if (ch)

{

// Exit program, if requested

if (ch == '~')

{

// Reset standard input

reset_input (istat);

// Gracefully exit

exit (0);

}

if ((ch != '\n') && (ch != '\r') && (pos < BLEN))

{

// Store character in input buffer

pthread_mutex_lock (&inputline_m);

inputline[pos++] = ch;

inputline[pos] = '\0';

pthread_mutex_unlock (&inputline_m);

}

else if ((ch == '\n') || (ch == '\r'))

{

pos = 0;

pthread_mutex_lock (&inputline_m);

/* act on command */

// If there's some input

if (strlen (inputline))

{

// Activate automatic control

if (strcmp (inputline, "T1_AUTO") == 0)

{

if (t1.automatic == 0)

{

t1.automatic = 1;

t1.on = 0;

}

}

if (strcmp (inputline, "T2_AUTO") == 0)

{

if (t2.automatic == 0)

{

t2.automatic = 1;

t2.on = 0;

}

}

if (strcmp (inputline, "T3_AUTO") == 0)

{

if (t3.automatic == 0)

{

t3.automatic = 1;

t3.on = 0;

}

}

// Activate manual control

if (strcmp (inputline, "T1_MAN") == 0)

{

if (t1.automatic == 1)

{

t1.automatic = 0;

t1.on = 0;

}

}

if (strcmp (inputline, "T2_MAN") == 0)

{

if (t2.automatic == 1)

{

t2.automatic = 0;

t2.on = 0;

}

}

if (strcmp (inputline, "T3_MAN") == 0)

{

if (t3.automatic == 1)

{

t3.automatic = 0;

t3.on = 0;

}

}

// Heater on

if (strcmp (inputline, "T1_ON") == 0)

{

if (t1.automatic == 0)

{

t1.on = 1;

}

}

if (strcmp (inputline, "T2_ON") == 0)

{

if (t2.automatic == 0)

{

t2.on = 1;

}

}

if (strcmp (inputline, "T3_ON") == 0)

{

if (t3.automatic == 0)

{

t3.on = 1;

}

}

// Heater off

if (strcmp (inputline, "T1_OFF") == 0)

{

if (t1.automatic == 0)

{

t1.on = 0;

}

}

if (strcmp (inputline, "T2_OFF") == 0)

{

if (t2.automatic == 0)

{

t2.on = 0;

}

}

if (strcmp (inputline, "T3_OFF") == 0)

{

if (t3.automatic == 0)

{

t3.on = 0;

}

}

}

pthread_mutex_unlock (&inputline_m);

}

}

sched_yield ();

}

}

/*

* Clock_task:

* Update the time buffer once a second

*/

void *

clock_task (void *arg)

{

static short hour = 0;

static short min = 0;

static short sec = 1;

time_t t, ot = 0;

for (;;)

{

t = time(NULL);

if (t != ot) {

ot = t;

} else {

sched_yield();

continue;

}

sprintf (timebuf, "%02d:%02d:%02d", hour, min, sec);

sec++;

if (sec > 59)

{

sec = 0;

min++;

if (min > 59)

{

min = 0;

hour++;

}

}

}

}

void

main ()

{

int ans;

pthread_t telemetry_thread;

pthread_t t1_control;

pthread_t t2_control;

pthread_t t3_control;

pthread_t reader_thread;

pthread_t clock_thread;

int status;

#ifdef M_1750

pthread_init ();

#endif

/* intitialize global data */

tc_init (&t1, T1_LW, T1_HW, T1_STEP, T1_DELAY);

tc_init (&t2, T2_LW, T2_HW, T2_STEP, T2_DELAY);

tc_init (&t3, T3_LW, T3_HW, T3_STEP, T3_DELAY);

pthread_mutex_init (&timebuf_m, NULL);

sprintf (timebuf, "00:00:00");

pthread_mutex_init (&inputline_m, NULL);

strcpy (inputline, "");

printf ("\nThermal Control Demo\n");

printf ("M. Martignano - ESA/ESTEC/WME\n");

printf ("Copyright (C) 1997 ESTEC - ESA\n\n");

printf ("Strike '~' to exit...\n");

istat = set_input ();

/* create the threads */

ans = pthread_create (&telemetry_thread, NULL, telemetry_body, NULL);

assert (ans >= 0);

ans = pthread_create (&t1_control, NULL, thermal_control_body, (void *) &t1);

assert (ans >= 0);

ans = pthread_create (&t2_control, NULL, thermal_control_body, (void *) &t2);

assert (ans >= 0);

ans = pthread_create (&t3_control, NULL, thermal_control_body, (void *) &t3);

assert (ans >= 0);

ans = pthread_create (&reader_thread, NULL, reader_body, NULL);

assert (ans >= 0);

ans = pthread_create (&clock_thread, NULL, clock_task, NULL);

assert (ans >= 0);

pthread_join (telemetry_thread, (void *) &status);

}

 
 
Last update: 2 August 2006
 


 
 
 
   Copyright 2000 - 2017 © European Space Agency. All rights reserved.