program.c
Go to the documentation of this file.
1 
6 /*
7  * The contents of this file are subject to the Mozilla Public License
8  * Version 1.0 (the "License"); you may not use this file except in
9  * compliance with the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS"
13  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
14  * License for the specific language governing rights and limitations
15  * under the License.
16  *
17  * The Original Code is legOS code, released October 17, 1999.
18  *
19  * The Initial Developer of the Original Code is Markus L. Noga.
20  * Portions created by Markus L. Noga are Copyright (C) 1999
21  * Markus L. Noga. All Rights Reserved.
22  *
23  * Contributor(s): Markus L. Noga <markus@noga.de>
24  * Frank Cremer <frank@demon.holly.nl>
25  */
26 
27 /*
28  * 2000.05.01 - Paolo Masetti <paolo.masetti@itlug.org>
29  *
30  * - Added "CMDirmode" for changing via LNP IR mode
31  *
32  * 2001.05.10 - Matt Ahrens <mahrens@acm.org>
33  *
34  * - Added free memory and batter life display
35  * Press "view" repeatedly while no programs are running to see
36  *
37  * 2002.4.23 - Ted Hess <thess@kitschensync.net>
38  *
39  * - Added Remote key handler
40  */
41 
42 #include <sys/program.h>
43 
44 #ifdef CONF_PROGRAM
45 
46 #include <sys/tm.h>
47 #include <string.h>
48 #include <semaphore.h>
49 #include <unistd.h>
50 #include <stdlib.h>
51 
52 #include <sys/lnp.h>
53 #include <sys/lnp-logical.h>
54 #include <sys/dmotor.h>
55 #include <sys/dsensor.h>
56 #include <sys/mm.h>
57 #include <sys/battery.h>
58 #include <dsound.h>
59 #include <remote.h>
60 
61 #include <conio.h>
62 
64 //
65 // Global Variables
66 //
68 
69 volatile unsigned cprog;
70 
72 //
73 // Internal Variables
74 //
76 
77 const unsigned char min_length[]={
78  1, // CMDacknowledge
79  2, // CMDdelete
80  13, // CMDcreate
81  8, // CMDoffsets
82  4, // CMDdata
83  2, // CMDrun
84  2, // CMDirmode
85  2 // CMDsethost
86 };
87 
88 static program_t programs[PROG_MAX];
89 
90 static unsigned char* buffer_ptr;
91 volatile unsigned char packet_len;
92 volatile unsigned char packet_src;
93 
94 static sem_t packet_sem;
95 
96 #if 0
97 #define debugs(a) { cputs(a); msleep(500); }
98 #define debugw(a) { cputw(a); msleep(500); }
99 #else
100 #define debugs(a)
101 #define debugw(a)
102 #endif
103 
104 // Forward ref
105 int lrkey_handler(unsigned int etype, unsigned int key);
106 
108 //
109 // Functions
110 //
112 
114 
115 int program_valid(unsigned nr) {
116  program_t *prog=programs+nr;
117 
118  return (nr < PROG_MAX) &&
119  (prog->text_size>0) &&
120  (prog->text_size+prog->data_size==prog->downloaded);
121 }
122 
124 static void program_run(unsigned nr) {
125  if(program_valid(nr)) {
126  program_t *prog=programs+nr;
127 
128  // initialize data segments
129  //
130  memcpy(prog->data,prog->data_orig,prog->data_size);
131  memset(prog->bss,0,prog->bss_size);
132 
133  execi((void*) (((char*)prog->text)
134  + prog->start ),
135  0,0,prog->prio,prog->stack_size);
136  }
137 }
138 
140 
142 static void packet_producer(const unsigned char *data,
143  unsigned char length,
144  unsigned char src) {
145  // old packet still unhandled or empty packet?
146  //
147  if(packet_len>0 || length==0)
148  return;
149 
150  if (buffer_ptr != 0)
151  return;
152 
153  buffer_ptr = malloc(length);
154  memcpy(buffer_ptr,data,length);
155  packet_len=length;
156  packet_src=src;
157  sem_post(&packet_sem);
158 }
159 
161 static int packet_consumer(int argc, char *argv[]) {
162  packet_cmd_t cmd;
163  unsigned char nr=0;
164  program_t *prog=programs; // to avoid a silly warning
165  const static unsigned char acknowledge=CMDacknowledge;
166  char msg[8];
167 
168  while (!shutdown_requested()) {
169  // wait for new packet
170  //
171  packet_len=0;
172  free(buffer_ptr);
173  buffer_ptr = 0;
174  if (sem_wait(&packet_sem) != -1) {
175  if (buffer_ptr == 0)
176  continue;
177 
178  debugw(*(size_t*)buffer_ptr);
179 
180  // handle trivial errors
181  //
182  cmd=buffer_ptr[0];
183  if (cmd>=CMDlast || packet_len<min_length[cmd])
184  continue;
185 
186  // handle IR CMDs
187  if (cmd==CMDirmode) {
188  if (buffer_ptr[1]==0) {
189  debugs("nearmodeIR");
191  debugs("OK");
192  lnp_addressing_write(&acknowledge,1,packet_src,0);
193  } else {
194  debugs("farmodeIR");
196  debugs("OK");
197  lnp_addressing_write(&acknowledge,1,packet_src,0);
198  }
199  continue;
200  }
201 
202  // Is this a request to change host address
203  if (cmd == CMDsethost) {
204  // ACK before we change our address
205  lnp_addressing_write(&acknowledge,1,packet_src,0);
206  lnp_set_hostaddr(buffer_ptr[1]);
207  continue;
208  }
209 
210  // Get program number, validate value
211  if((cmd > CMDacknowledge) && (cmd <= CMDrun)) {
212  nr = buffer_ptr[1];
213  if(nr > PROG_MAX)
214  continue;
215 #ifndef CONF_VIS
216  cputc_hex_0(nr+1);
217 #endif
218  }
219 
220  debugw(nr);
221  prog = programs+nr;
222 
223  switch( cmd ) {
224  case CMDdelete:
225  debugs("dele");
226 
227  if(nb_tasks <= nb_system_tasks) {
228  if(prog->text)
229  free(prog->text);
230  memset(prog,0,sizeof(program_t));
231 
232 #ifndef CONF_VIS
233  if(nr == cprog)
234  cputc_0('-');
235 #endif
236  debugs("OK");
237 
238  lnp_addressing_write(&acknowledge,1,packet_src,0);
239  }
240  break;
241 
242  case CMDcreate:
243  debugs("crea");
244  if(!prog->text) {
245  memcpy(&(prog->text_size),buffer_ptr+2,11);
246 
247  if((prog->text=malloc(prog->text_size+
248  2*prog->data_size+
249  prog->bss_size ))) {
250  prog->data=prog->text+prog->text_size;
251  prog->bss=prog->data+prog->data_size;
252  prog->data_orig=prog->bss +prog->bss_size;
253  prog->downloaded=0;
254 
255  debugs("OK");
256 
257  cputw(0);
258  cprog = nr;
259 
260  msg[0]=CMDacknowledge;
261  msg[1]=nr;
262  memcpy(msg+2,prog,6);
263  lnp_addressing_write(msg,8,packet_src,0);
264  } else
265  memset(prog,0,sizeof(program_t));
266  }
267  break;
268 
269  case CMDdata:
270  debugs("data");
271  if(prog->text && !program_valid(nr)) {
272  size_t offset=*(size_t*)(buffer_ptr+2);
273  if(offset<=prog->downloaded) {
274  if(offset==prog->downloaded) {
275  memcpy(prog->text+offset,buffer_ptr+4,packet_len-4);
276  prog->downloaded+=packet_len-4;
277 
278  if(program_valid(nr)) {
279  // copy original data segment and we're done.
280  //
281  memcpy(prog->data_orig,prog->data,prog->data_size);
282  cls();
283  } else
284  cputw(prog->downloaded);
285  debugs("OK");
286  } else
287  debugs("OLD");
288 
289  lnp_addressing_write(&acknowledge,1,packet_src,0);
290  }
291  }
292  break;
293 
294  case CMDrun:
295  debugs("run");
296  if(program_valid(nr)) {
297  cprog = nr;
298  program_stop(0);
299  program_run(nr);
300 
301  debugs("OK");
302  lnp_addressing_write(&acknowledge,1,packet_src,0);
303  }
304  break;
305 
306  default:
307  debugs("error");
308  }
309  }
310  }
311  free(buffer_ptr);
312  return 0;
313 }
314 
316 void program_stop(int flag) {
317  int count_down = 40;
318 
319  // Kindly request that all user tasks shutdown
321  // Wait a bit
322  while (--count_down && (nb_tasks > nb_system_tasks)) {
323  if (flag)
324  cputs("STOP");
325  msleep(100);
326  }
327 
328  if (nb_tasks > nb_system_tasks) {
329  // Wait no longer.
330  if (flag) {
331  cputs("KILL");
332  // display immediately
333  lcd_refresh();
334  }
336  }
337 
338  // Reset motors, sensors, sound & LNP as
339  // programs may have motors running,
340  // sensors active or handlers set.
341  //
342  // Programs that exit on their own
343  // are assumed to take the necessary
344  // actions themselves.
345  //
346 #ifdef CONF_DSOUND
347  dsound_stop();
348 #endif
349 #ifdef CONF_DMOTOR
350  dm_init();
351 #endif
352 #ifdef CONF_DSENSOR
353  ds_init();
354 #endif
355  lnp_init();
356 #ifdef CONF_LR_HANDLER
357  // Reset remote button handler
358  lr_init();
359  lr_set_handler(lrkey_handler);
360 #endif
361 }
362 
364 int key_handler(int argc, char *argv[]) {
365  int c;
366 
367 #ifndef CONF_VIS
368  cputc_0('-');
369 #endif
370 
371  while (!shutdown_requested()) {
372  int clear=0;
373  c=getchar();
374 
375 gotkey:
376 
377  debugs("key "); debugw(c);
378  debugs("task"); debugw(nb_tasks);
379 
380  switch(c) {
381  case KEY_ONOFF:
382  cputs("OFF");
383  // Kindly request all tasks shutdown
385  // Except for key_handler
386  ctid->tflags &= (~T_SHUTDOWN);
387  // Wait a bit
388  clear = 50;
389  while (--clear && (nb_tasks > 2))
390  msleep(100);
391  // Wait no longer.
392  if (nb_tasks > 2)
394  // Now key_handler should shutdown
395  ctid->tflags |= T_SHUTDOWN;
396  break;
397 
398  case KEY_RUN:
399  // toggle: start/stop program
400  if(nb_tasks > nb_system_tasks) {
401  // if program running, stop it
402  clear=1;
403  program_stop(1);
404  } else if(program_valid(cprog)) {
405  program_stop(0);
406  program_run(cprog);
407  } else {
408  cputs("NONE");
409  clear=1;
410  }
411  break;
412 
413  case KEY_PRGM:
414  // works only if no programs are running.
415  if(nb_tasks <= nb_system_tasks) {
416  int i;
417  for(i=0; i<PROG_MAX; i++) {
418  if( (++cprog)>=PROG_MAX)
419  cprog=0;
420  if(program_valid(cprog))
421  break;
422  }
423  if(i==PROG_MAX) {
424  cputs("NONE");
425  clear=1;
426 #ifndef CONF_VIS
427  cputc_0('-');
428  }
429  else
430  cputc_hex_0(cprog+1);
431 #else
432  }
433 #endif
434 
435  }
436  break;
437  case KEY_VIEW:
438  // works only if no programs are running.
440  break;
441  /*
442  * pressing the "view" button cycles through a display of the
443  * amount of the amount of free memory (in decimal and
444  * hexadecimal) and battery power. If a button other than "view"
445  * is pressed while cycling through, we handle that button
446  * ("goto gotkey").
447  */
448  cputs("addr");
449  if ((c = getchar()) != KEY_VIEW) goto gotkey;
451  while ((c = getchar()) == KEY_PRGM) {
452  lnp_hostaddr += 0x10;
455  }
456  if (c != KEY_VIEW) goto gotkey;
457  if (program_valid(cprog)) {
458  cputs("dele");
459  if ((c = getchar()) != KEY_VIEW && c != KEY_PRGM) goto gotkey;
460  if (c == KEY_PRGM) {
461  program_t *prog=programs+cprog;
462  if (prog->text)
463  free(prog->text);
464  memset(prog,0,sizeof(program_t));
465  cputc_0('-');
466  }
467  }
468 
469  cputs("free");
470  if ((c = getchar()) != KEY_VIEW) goto gotkey;
471  lcd_int(mm_free_mem());
472  if ((c = getchar()) != KEY_VIEW) goto gotkey;
473  cputw(mm_free_mem());
474  if ((c = getchar()) != KEY_VIEW) goto gotkey;
475 
476 #if defined(CONF_DSENSOR)
477  cputs("batt");
478  if ((c = getchar()) != KEY_VIEW) goto gotkey;
480  if ((c = getchar()) != KEY_VIEW) goto gotkey;
481 #endif // CONF_DSENSOR
482 
483  clear=1;
484  break;
485  }
486 
487  if(clear) {
489  cls();
490  }
491  }
492  return 0;
493 }
494 
495 #if defined(CONF_LR_HANDLER)
496 int lrkey_handler(unsigned int etype, unsigned int key) {
498  unsigned char pnr = 0;
499 
500  // If a program is running, stop it
501  // NOTE: this LRKEY is allowed while a program is running!
502  if(key == LRKEY_STOP && etype == LREVT_KEYON && nb_tasks > nb_system_tasks) {
503  program_stop(1);
504  return 1; // we consumed key
505  }
506 
507  // Only interested if no program is running
508  if(nb_tasks <= nb_system_tasks) {
509  // Keydown events dispatched here
510  if (etype == LREVT_KEYON) {
511  switch (key) {
512 #ifdef CONF_DSOUND
513  case LRKEY_BEEP:
514  // Need high pitched beep-beep
515  dsound_system(0);
516  break;
517 #endif // CONF_DSOUND
518 
519  case LRKEY_P5:
520  pnr++;
521  // ... Fallthru
522  case LRKEY_P4:
523  pnr++;
524  // ... Fallthru
525  case LRKEY_P3:
526  pnr++;
527  // ... Fallthru
528  case LRKEY_P2:
529  pnr++;
530  // ... Fallthru
531  case LRKEY_P1:
532  // Start something?
533  if(program_valid(pnr))
534  {
535  cprog = pnr;
536  // Reset things
537  program_stop(0);
538 #ifdef CONF_VIS
539  cputc_hex_0(pnr+1);
540 #ifndef CONF_LCD_REFRESH
541  lcd_refresh();
542 #endif
543 #endif
544  // launch Program(n)
545  program_run(pnr);
546  } else {
547  // no such program downloaded
548  cputs("NONE");
549  }
550  break;
551 
552 #if defined(CONF_DMOTOR)
553  // Motor on commands
554  case LRKEY_A1:
555  // A Motor fwd
556  motor_a_dir(fwd);
557  break;
558  case LRKEY_A2:
559  // A Motor rev
560  motor_a_dir(rev);
561  break;
562  case LRKEY_B1:
563  // B Motor fwd
564  motor_b_dir(fwd);
565  break;
566  case LRKEY_B2:
567  // B Motor rev
568  motor_b_dir(rev);
569  break;
570  case LRKEY_C1:
571  // C Motor fwd
572  motor_c_dir(fwd);
573  break;
574  case LRKEY_C2:
575  // C Motor rev
576  motor_c_dir(rev);
577  break;
578 #endif // CONF_DMOTOR
579  default:
580  // Not consumed
581  return 0;
582  }
583 #ifndef CONF_LCD_REFRESH
584  lcd_refresh();
585 #endif
586  // Key consumed
587  return 1;
588  }
589 
590  // Keyup events dispatched here
591  if (etype == LREVT_KEYOFF) {
592  switch (key) {
593 #if defined(CONF_DMOTOR)
594  case LRKEY_A1:
595  case LRKEY_A2:
596  // Shut off A motor
598  break;
599  case LRKEY_B1:
600  case LRKEY_B2:
601  // Shut off B motor
603  break;
604  case LRKEY_C1:
605  case LRKEY_C2:
606  // Shut off C motor
608  break;
609 #endif // CONF_DMOTOR
610  case LRKEY_P1:
611  case LRKEY_P2:
612  case LRKEY_P3:
613  case LRKEY_P4:
614  case LRKEY_P5:
615  case LRKEY_STOP:
616  // remove the STOP (or NONE) message
617  cls();
618  break;
619  default:
620  return 0;
621  }
622  // Used the key
623  return 1;
624  }
625  }
626 
627 #ifndef CONF_LCD_REFRESH
628  lcd_refresh();
629 #endif
630  // Didn't eat the key
631  return 0;
632 }
633 #endif
634 
636 
638 void program_init() {
639  packet_len=0;
640  sem_init(&packet_sem,0,0);
641  execi(&packet_consumer,0,0,PRIO_HIGHEST,DEFAULT_STACK_SIZE);
642  execi(&key_handler,0,0,PRIO_HIGHEST,DEFAULT_STACK_SIZE);
643 
644 #ifdef CONF_LR_HANDLER
645  // Setup kernel remote callback handler and dispatch thread
646  lr_startup();
647  lr_set_handler(lrkey_handler);
648 #endif
649 
650  lnp_addressing_set_handler(0,&packet_producer);
651  buffer_ptr = 0;
652 }
653 
655 
657 void program_shutdown() {
659  sem_destroy(&packet_sem);
660 
661 #ifdef CONF_LR_HANDLER
662  lr_shutdown();
663 #endif
664 }
665 
666 #endif // CONF_PROGRAM
int mm_free_mem(void)
how many bytes of memory are free?
void cls()
clear user portion of LCD
#define KEY_PRGM
the program key is pressed
Definition: dkey.h:47
#define KEY_RUN
the run key is pressed
Definition: dkey.h:45
a key on the remote was released
Definition: remote.h:72
int program_valid(unsigned nr)
check if a given program is valid.
#define LRKEY_BEEP
Beep Key.
Definition: remote.h:67
#define LNP_DUMMY_ADDRESSING
dummy addressing layer packet handler
Definition: lnp.h:61
int getchar()
wait for keypress and return key code.
#define LRKEY_B2
Motor-B reverse (down)
Definition: remote.h:51
#define CONF_LNP_HOSTMASK
LNP host mask.
Definition: config.h:58
Interface: string functions.
#define LRKEY_P5
Run Program 5.
Definition: remote.h:63
void lr_set_handler(lr_handler_t handler)
set a new handler for LEGO IR Remote messages
Definition: remote.h:97
int get_battery_mv()
get current battery voltage
void * data
origin of data segment (imm. after text)
Definition: program.h:54
void free(void *ptr)
return the allocated memory to memory management.
size_t start
offset from text segment to start into.
Definition: program.h:62
void motor_b_dir(MotorDirection dir)
set motor B direction to dir
?
Definition: program.h:82
size_t downloaded
number of bytes downloaded so far.
Definition: program.h:65
Interface: console input / output.
void dsound_stop(void)
stop playing sound
Internal Interface: direct motor control.
Internal Interface: direct sensor access.
volatile unsigned int nb_tasks
number of tasks
void lnp_set_hostaddr(unsigned char host)
set new LNP host address
Definition: lnp.h:115
#define LRKEY_STOP
Stop key.
Definition: remote.h:65
void program_init()
initialize program support
#define LRKEY_P1
Run Program 1.
Definition: remote.h:55
volatile unsigned cprog
the current program
int sem_wait(sem_t *sem)
Wait for semaphore (blocking)
volatile unsigned int nb_system_tasks
void cputc_0(unsigned c)
write ASCII char to position 0 of LCD
Definition: conio.h:174
void lnp_addressing_set_handler(unsigned char port, lnp_addressing_handler_t handler)
set an addressing layer packet handler for a port.
Definition: lnp.h:107
int sem_destroy(sem_t *sem)
We're done with the semaphore, destroy it.
Definition: semaphore.h:147
Internal LNP Interface: link networking protocol logical layer.
void * text
origin of text segment
Definition: program.h:53
Internal Interface: battery handling.
a key on the remote was pressed
Definition: remote.h:71
wakeup_t dkey_released(wakeup_t data)
wakeup if all of the given keys are released.
#define T_USER
user task
Definition: tm.h:76
#define LRKEY_A1
Motor-A forward (up)
Definition: remote.h:43
void shutdown_tasks(tflags_t flags)
void program_shutdown()
shutdown program support
size_t bss_size
bss segment size in bytes
Definition: program.h:60
Internal Interface: program data structures and functions.
void motor_c_dir(MotorDirection dir)
set motor C direction to dir
int lnp_addressing_write(const unsigned char *data, unsigned char length, unsigned char dest, unsigned char srcport)
send a LNP addressing layer packet of given length
atomic_t sem_t
the semaphore data-type
Definition: semaphore.h:46
#define LRKEY_A2
Motor-A reverse (down)
Definition: remote.h:49
Internal Interface: task management.
void lr_init(void)
initialize the LEGO IR Remote subsystem
size_t text_size
text segment size in bytes
Definition: program.h:58
void * bss
origin of bss segment (imm. after data)
Definition: program.h:55
void cputs(char *s)
Write string s to LCD (Only first 5 chars)
Interface: reduced UNIX standard library.
packet_cmd_t
Definition: program.h:71
void killall(priority_t p)
#define KEY_VIEW
the view key is pressed
Definition: dkey.h:46
void lr_shutdown(void)
stop the LEGO IR Remote subsystem
#define PRIO_HIGHEST
The highest possible task priority.
Definition: tm.h:55
Internal Interface: memory management.
#define LRKEY_P2
Run Program 2.
Definition: remote.h:57
#define lcd_int(i)
display an integer in decimal
Definition: lcd.h:123
tdata_t * ctid
ptr to current process data
reverse
Definition: dmotor.h:47
tflags_t tflags
task flags
Definition: tm.h:109
#define T_KERNEL
task flags
Definition: tm.h:75
priority_t prio
priority to run this program at
Definition: program.h:63
#define LRKEY_C1
Motor-C forward (up)
Definition: remote.h:47
tid_t execi(int(*code_start)(int, char **), int argc, char **argv, priority_t priority, size_t stack_size)
void motor_a_dir(MotorDirection dir)
set motor A direction to dir
hold current position
Definition: dmotor.h:48
#define PROG_MAX
maximum number of programs
Definition: program.h:45
The program control structure.
Definition: program.h:52
unsigned char lnp_hostaddr
LNP host address.
void lnp_init(void)
Initialise protocol handlers.
void * memcpy(void *dest, const void *src, size_t size)
copy memory block from src to dest.
void lnp_logical_range(int far)
Set the IR transmitter range.
Definition: lnp-logical.h:62
void * malloc(size_t size)
allocate and return pointer to uninitialized memory
Interface: POSIX 1003.1b semaphores for task synchronization.
1+ 1: b[0=near/1=far]
Definition: program.h:80
1+ 1: b[nr]
Definition: program.h:79
void ds_init(void)
initialize sensor a/d conversion
void lcd_refresh(void)
refresh the entire LCD display
Definition: lcd.c:254
void lr_startup(void)
start the LEGO IR Remote subsystem
Interface: LEGO Infrared Remote Control.
int sem_post(sem_t *sem)
Post a semaphore.
Definition: semaphore.h:123
#define KEY_ONOFF
the on/off key is pressed
Definition: dkey.h:44
void dm_init(void)
initialize motors
#define KEY_ANY
any of the keys
Definition: dkey.h:49
#define T_SHUTDOWN
shutdown requested
Definition: tm.h:78
size_t data_size
data segment size in bytes
Definition: program.h:59
#define LRKEY_B1
Motor-B forward (up)
Definition: remote.h:45
static void dsound_system(unsigned nr)
play a system sound
Definition: dsound.h:240
Interface: reduced standard C library.
unsigned int msleep(unsigned int msec)
1+>3: b[nr] s[offset] array[data]
Definition: program.h:78
void * memset(void *s, int c, size_t n)
fill memory block with a byte value.
#define LRKEY_C2
Motor-C reverse (down)
Definition: remote.h:53
Internal LNP Interface: link networking protocol.
1+12: b[nr] s[textsize] s[datasize]
Definition: program.h:74
forward
Definition: dmotor.h:46
wakeup_t wait_event(wakeup_t(*wakeup)(wakeup_t), wakeup_t data)
#define shutdown_requested()
test to see if task has been asked to shutdown
Definition: tm.h:134
void cputc_hex_0(unsigned nibble)
write HEX digit to position 0 of LCD
Definition: conio.h:128
void cputw(unsigned word)
Write a HEX word to LCD.
#define LRKEY_P4
Run Program 4.
Definition: remote.h:61
1+ 1: b[hostaddr]
Definition: program.h:81
size_t stack_size
stack segment size in bytes
Definition: program.h:61
void * data_orig
origin of backup copy of data segment
Definition: program.h:56
1+ 1: b[nr]
Definition: program.h:73
#define LRKEY_P3
Run Program 3.
Definition: remote.h:59
void program_stop(int flag)
stop program
int sem_init(sem_t *sem, int pshared, unsigned int value)
Initialize a semaphore.
Definition: semaphore.h:64
#define DEFAULT_STACK_SIZE
that's enough.
Definition: tm.h:81

brickOS is released under the Mozilla Public License.
Original code copyright 1998-2005 by the authors.

Generated for brickOS Kernel Developer by doxygen 1.8.9.1