/* --------------------------------------------------------------------------- | Filename: sema_coop.c | | Authors: Thomas Braunl | Thomas Lampart | | Description: | This is a RoBiOS demo program demonstrating thread and semaphore usage | for COOPERATIVE Multitasking | ------------------------------------------------------------------------- */ #include "eyebot.h" #define SLAVES 3 #define SSIZE 4096 /** pointer to thread control blocks */ struct tcb *slave_p[SLAVES], *master_p; /** semaphores */ struct sem sema[SLAVES]; /* ----------------------------------------------------------------------- */ /**Code for task "slave" task is started with id-number (0..SLAVES-1) and does mutual exclusion with the semaphor matching its id-no. semaphor P and V is also controlled by the master task execution is deferred to other processes after each loop iteration */ void slave() { int id, i, count = 0; /** read slave id no. as supplied from main program during spawn op. */ id = OSGetUID(0); LCDPrintf("slave %d start\n", id); while(1) { OSSemP(&sema[id]); /* occupy semaphore */ for (i=0; i<2*id; i++) LCDPrintf(" "); /* space for easy reading */ LCDPrintf("slave %d:%d\n", id, count); count = (count+1) % 100; /* max count 99 */ OSSemV(&sema[id]); /* free semaphore */ OSSleep(70); /* sleep 0.7s --> other threads */ } } /* end slave */ /* ----------------------------------------------------------------------- */ /**Code for task "master" master handles user input via keys to occupy and free semaphores, which in turn enable slave tasks to work or block them */ void master() { int i; /** start with both semaphores and slave tasks blocked */ int block[SLAVES] = {1,1,1}; LCDPrintf("master start\n"); /** display appropr. menu for soft-keys, depend. on slave task status */ LCDMenu("V.0", "V.1", "V.2", "END"); while(1) { switch (KEYRead()) { case KEY1: if (block[0]) { OSSemV(&sema[0]); LCDMenu("P.0", "","",""); } else { OSSemP(&sema[0]); LCDMenu("V.0", "","",""); } block[0] = !block[0]; break; case KEY2: if (block[1]) { OSSemV(&sema[1]); LCDMenu("", "P.1", "",""); } else { OSSemP(&sema[1]); LCDMenu("", "V.1", "",""); } block[1] = !block[1]; break; case KEY3: if (block[2]) { OSSemV(&sema[2]); LCDMenu("","", "P.2", ""); } else { OSSemP(&sema[2]); LCDMenu("","", "V.2", ""); } block[2] = !block[2]; break; case KEY4: /** kill both slaves and then exit master itself */ for (i=0; i