/* File **********THREAD2.C*********** Statically allocated thread example with spinlock semaphores PortB bits 0,1,2,3 specify which thread is running PortC bit program 0 Put 1 Get 2 Producer 3 Consumer 4 Wait 5 Signal Jonathan W. Valvano */ #include #include #include "SERIAL.H" #include "SPIN.H" #include "SFIFO.H" int DisplayFree; /* Semaphore used to share Display */ #define timeslice 20000 #define stacksize 100 struct TCB { struct TCB *Next; /* Link to Next TCB */ unsigned char *SP; /* Stack Pointer */ unsigned char Id; /* 1,2 or 4 */ unsigned char MoreStack[stacksize-9]; /* additional stack */ unsigned char CCR; /* Initial CCR */ unsigned char RegB; /* Initial RegB */ unsigned char RegA; /* Initial RegA */ unsigned int RegX; /* Initial RegX */ unsigned int RegY; /* Initial RegY */ void (*PC)(void); /* Initial Program Counter */ }; typedef struct TCB TCBType; typedef TCBType * TCBPtr; TCBPtr RunPt; /* Pointer to thread currently running */ unsigned int last; unsigned int CreateData(void){ unsigned int i; // will generate the data stream 1,2,3,4,...,99 asm(" sei"); // read modify write nonreentrant code if((last++)==100){ OutString("done\n"); asm(" swi");} // go to BUFFALO asm(" cli"); return(last);} void pseudo(unsigned int loopcnt){ unsigned int i,j; for(i=0;iId; while(1) { PORTC=4; x=CreateData(); pseudo(x); Message("The data Put by producer",myId,x); Put(x); } } void Consumer(){ unsigned int x; unsigned int myId; myId=RunPt->Id; while(1) { PORTC=8; x=Get(); pseudo(x); Message("The data Get by consumer",myId,x); }} TCBType sys[4]={ { &sys[1], /* Pointer to Next */ &sys[0].MoreStack[stacksize-10], /* Initial SP */ 1, /* Id */ { 0}, 0x40,0,0,0,0, /* CCR,B,A,X,Y */ Producer, }, /* Initial PC */ { &sys[2], /* Pointer to Next */ &sys[1].MoreStack[stacksize-10], /* Initial SP */ 2, /* Id */ { 0}, 0x40,0,0,0,0, /* CCR,B,A,X,Y */ Producer, }, /* Initial PC */ { &sys[3], /* Pointer to Next */ &sys[2].MoreStack[stacksize-10], /* Initial SP */ 4, /* Id */ { 0}, 0x40,0,0,0,0, /* CCR,B,A,X,Y */ Consumer, }, /* Initial PC */ { &sys[0], /* Pointer to Next */ &sys[3].MoreStack[stacksize-10], /* Initial SP */ 8, /* Id */ { 0}, 0x40,0,0,0,0, /* CCR,B,A,X,Y */ Consumer, }}; /* Initial PC */ #pragma interrupt_handler ThreadSwitch() void ThreadSwitch(){ asm(" ldx _RunPt\n" " sts 2,x"); RunPt=RunPt->Next; PORTB=RunPt->Id; /* PortB shows which thread is running */ asm(" ldx _RunPt\n" " lds 2,x"); TOC3=TCNT+timeslice; /* Thread runs for 10 ms */ TFLG1=0x20; } /* acknowledge by clearing TOC3F */ main(){ DDRC=0xFF; DisplayFree=1; last=0; OutString("Starting fixed allocation spinlock semaphore system\n"); RunPt=&sys[0]; /* Specify first thread to run */ asm(" sei"); InitFifo(); TOC3vector=&ThreadSwitch; TFLG1 = 0x20; /* Clear OC3F */ TMSK1 = 0x20; /* Arm TOC3 */ TOC3=TCNT+timeslice; // time slice for first thread PORTB=RunPt->Id; asm(" ldx _RunPt\n" " lds 2,x\n" " cli\n" " rti");} /* Launch First Thread */ #include "SERIAL.C" #include "SPIN.C" #include "SFIFO.C"