/************************************************************************ * Term: Fall 2003 * Course: ECE 473 * Name: Olamide Adabonyan / Philip Lechowicz * E-mail: o_mide@yahoo.com / phillech@aol.com * * Date Submitted: 11/27/02 * Demo Approval: ________ ************************************************************************/ #include #include "vectors.c" //locate TOC1 jmp addi from EEPROM #define stacksize 150 #define switchtime 20000 #define endProg() asm("swi") #define enableInt() asm("cli") #define disableInt() asm("sei") int displayFree; //Semaphore used to share Display char t1_iteration; void Program01(void); void Program02(void); void Program03(void); void Message1(char *NamePt, unsigned int num); void Message2(char *NamePt, char *NamePt2); void Message3(char *NamePt); //===========================[.c header files] #include "spin.c" #include "fifo.c" #include "lab3sci.c" //============================ /******************************************************* Name: TCB (Thread Control Block)... Purpose: - data structure for TCB ********************************************************/ 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]; /* 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 */ /******************************************************* Name: Threads 1, 2 & 3 Purpose: - create structure and initialize theads 1, 2, & 3 ********************************************************/ TCBType sys[3]= { { &sys[1], /* Pointer to Next */ &sys[0].MoreStack[stacksize-1], /* Initial SP */ 1, /* Id */ { 0}, 0x40,0,0,0,0, /* CCR,B,A,X,Y */ Program01, /* Initial PC */ }, { &sys[2], /* Pointer to Next */ &sys[1].MoreStack[stacksize-1], /* Initial SP */ 2, /* Id */ { 0}, 0x40,0,0,0,0, /* CCR,B,A,X,Y */ Program02, /* Initial PC */ }, { &sys[0], /* Pointer to Next */ &sys[2].MoreStack[stacksize-1], /* Initial SP */ 3, /* Id */ { 0}, 0x40,0,0,0,0, /* CCR,B,A,X,Y */ Program03, /* Initial PC */ } }; /******************************************************* Name: Programs 1, 2 & 3 Purpose: - output messages to screen depending on thread running Inputs: none Outputs: none ********************************************************/ void Program01(void) { //myId=RunPt->Id; //debugger char i, flag, temp, dummy, dummy1, dummy2; char t1_msg1[] = "T1 has executed "; char t1_msg2[] = " times"; while(1) { t1_iteration++; Message1("Thread 1 Iteration #", t1_iteration); for(i=0; i<16; i++) { flag = PutFifo(t1_msg1[i]); if (flag == 0) i--; } //convert # of T1 iterations to ascii if (t1_iteration >= 10) { if(t1_iteration >=100) { temp = (t1_iteration/10); dummy = (temp/10) + 0x30; dummy1 = (temp%10) + 0x30; dummy2 = (t1_iteration%10) + 0x30; do flag = PutFifo(dummy); while(flag == 0); //FIFO full do flag = PutFifo(dummy1); while(flag == 0); //FIFO full do flag = PutFifo(dummy2); while(flag == 0); //FIFO full } else { dummy = 0x30; dummy1 = (t1_iteration/10) + 0x30; dummy2 = (t1_iteration%10) + 0x30; do flag = PutFifo(dummy); while(flag == 0); //FIFO full do flag = PutFifo(dummy1); while(flag == 0); //FIFO full do flag = PutFifo(dummy2); while(flag == 0); //FIFO full } } else { dummy = dummy1 = 0x30; dummy2 = t1_iteration + 0x30; do flag = PutFifo(dummy); while(flag == 0); //FIFO full do flag = PutFifo(dummy1); while(flag == 0); //FIFO full do flag = PutFifo(dummy2); while(flag == 0); //FIFO full } for(i=0; i<6; i++) { flag = PutFifo(t1_msg2[i]); if (flag == 0) //FIFO full i--; } } } void Program02(void) { //myId=RunPt->Id; //debugger char i, flag; char t1_msg1[25]; while(1) { for(i=0; i<25; i++) { flag = GetFifo(t1_msg1+i); if(flag == 0) //FIFO empty i--; } Message2("Thread 2 recieved: ", t1_msg1); } } void Program03(void) { //myId=RunPt->Id; //debugger char i; while(1) { Message3("Thread 3 is printing"); for (i=0; i<150; i++) asm("nop"); } } /******************************************************* Name: Message Purpose: - output proper message to screen depending on which thread is calling it Inputs: none Outputs: none ********************************************************/ void Message1(char *NamePt, unsigned int num) { Wait(&displayFree); OutString(NamePt); OutUDec(num); OutString("\n\r"); Signal(&displayFree); } void Message2(char *NamePt, char *NamePt2) { Wait(&displayFree); OutString(NamePt); OutString(NamePt2); OutString("\n\r"); Signal(&displayFree); } void Message3(char *NamePt) { Wait(&displayFree); OutString(NamePt); OutString("\n\r"); Signal(&displayFree); } /******************************************************* Name: ThreadSwitcher Purpose: - Switch threads in a round-robin manner Inputs: none Outputs: none ********************************************************/ #pragma interrupt_handler ThreadSwitcher() void ThreadSwitcher() { //OutString("switch..."); //debugger asm(" ldx _RunPt\n" " sts 2,x"); RunPt = RunPt->Next; asm(" ldx _RunPt\n" " lds 2,x"); TOC1 = TCNT + switchtime; // Thread runs for 10 ms (i.e. if switchtime is 20000) TFLG1 = 0x80; } /******************************************************* Name: Main Purpose: - initializes system - runs first thread Inputs: none Outputs: none ********************************************************/ main() { disableInt(); //disable interrupts //init vars and FIFO... OutString("\n\r\n\r::[473 lab3-start]:: .:mide & phil:. \n\r\n\r"); OutString("Initializing Variables and FIFO...\n\r"); t1_iteration = 0; InitFifo(); //SCI config... OutString("Initializing SCI...\n\r"); SCCR1=0; SCCR2=0x0c; // enable SCI BAUD=0x30; //OC1 config... OutString("Initializing Thread Swithcher...\n\r"); //TOC1vector = &ThreadSwitcher; //not needed here because we are using EEPROM TMSK1 = 0x80; TFLG1 = 0x80; TOC1 = TCNT + (switchtime*2); //Thread & Semaphore config... OutString("Initializing Threads & Semaphore...\n\r"); displayFree = 1; RunPt=&sys[0]; //Specify first thread to run asm(" ldx _RunPt\n" " lds 2,x\n"); OutString("\n\r::[System Initialization Complete]::\n\r\n\r"); enableInt(); //enable interrupts asm("rti"); //launch first thread }