/* --------------------------------------------------------------------------- | Filename: sema_pre.c | | Author : Thomas Braunl | | | Description: | This is a RoBiOS demo program demonstrating thread and semaphore usage | for PREEMPTIVE Multitasking | ------------------------------------------------------------------------- */ #include "eyebot.h" #define SLAVES 3 #define SSIZE 8192 /** pointer to thread control blocks */ struct tcb *slave_p[SLAVES], *master_p; /** semaphores */ struct sem sema[SLAVES]; struct sem lcd; /* ----------------------------------------------------------------------- */ /**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); OSSemP(&lcd); LCDPrintf("slave %d start\n", id); OSSemV(&lcd); while(1) { OSSemP(&sema[id]); /* occupy semaphore */ OSSemP(&lcd); for (i=0; i<2*id; i++) LCDPrintf("-"); /* space for easy reading */ LCDPrintf("slave %d:%d\n", id, count); OSSemV(&lcd); count = (count+1) % 100; /* max count 99 */ OSSemV(&sema[id]); /* free semaphore */ } } /* end slave */ /* ----------------------------------------------------------------------- */ int ord(int key) { switch(key) { case KEY1: return 0; case KEY2: return 1; case KEY3: return 2; case KEY4: return 3; } return 0; /* error */ } /* ----------------------------------------------------------------------- */ /**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,k; int block[SLAVES] = {1,1,1}; /* start status: all slaves blocked */ OSSemP(&lcd); LCDPrintf("master start\n"); LCDMenu("V.0", "V.1", "V.2", "END"); OSSemV(&lcd); while(1) { k = ord(KEYGet()); if (k!=3) { block[k] = !block[k]; OSSemP(&lcd); if (block[k]) LCDMenuI(k+1,"V"); else LCDMenuI(k+1,"P"); OSSemV(&lcd); if (block[k]) OSSemP(&sema[k]); else OSSemV(&sema[k]); } else /* kill both slaves and then exit master itself */ { for (i=0; i