int OS_AddThread(void(*task)(void), unsigned long stackSize, unsigned long priority) { uint32_t status; status = OS_StartCritical(); //we will take the first thread from the dead pool if(DeadPt == '\0') { OS_DisableInterrupts(); while(1){} } (DeadPt)->id = uniqueId; //unique id (DeadPt)->active = 1; (DeadPt)->sleepState = 0; //flag (DeadPt)->priority = priority; (DeadPt)->blockedState = 0; //flag (DeadPt)->needToWakeUp = 0; //flag SetInitialStack(DeadPt, stackSize); (DeadPt)->stack[stackSize - 2] = (uint32_t)task; //push PC uniqueId++; addDeadToScheduler(&DeadPt); if(higherPriorityAdded == 1) { OS_Suspend(); } OS_EndCritical(status); return 1; }
// ******** OS_bSignal ************ // Lab2 spinlock, set to 1 // Lab3 wakeup blocked thread if appropriate // input: pointer to a binary semaphore // output: none void OS_bSignal(Sema4Type *semaPt) { int32_t status; status = OS_StartCritical(); (*semaPt).Value = 1; if((*semaPt).blockedThreads != '\0') { (*(*semaPt).blockedThreads).active = 1; (*(*semaPt).blockedThreads).blockedState = 0; addDeadToScheduler(&(*semaPt).blockedThreads); //addDead is similar to what we want to do. Just takes first element of linked list and adds to scheduler } EndCritical(status ); }
int OS_AddPeriodicThread(void(*task)(void), unsigned long period, unsigned long priority){ int32_t status; status = OS_StartCritical(); //now need to add to linked list if(DeadPeriodicPt == '\0') //cant add this thread { OS_DisableInterrupts(); while(1){}; } removeAndAddToSingleList(&DeadPeriodicPt, period, task, priority); EndCritical(status ); return 0; //added sucesfully }
// ******** OS_bWait ************ // Lab2 spinlock, set to 0 // Lab3 block if less than zero // input: pointer to a binary semaphore // output: none void OS_bWait(Sema4Type *semaPt) { int32_t status; status = OS_StartCritical(); while((*semaPt).Value == 0) { OS_Block(semaPt); //block and put into semaphore blocked list OS_Suspend(); OS_EnableInterrupts(); OS_DisableInterrupts(); } //while someone has the semaphor (*semaPt).Value = 0; //take the semaphore EndCritical(status ); }
// ******** OS_Wait ************ // decrement semaphore // Lab2 spinlock // Lab3 block if less than zero // input: pointer to a counting semaphore // output: none void OS_Wait(Sema4Type *semaPt) { uint32_t status; status = OS_StartCritical(); (*semaPt).Value--; //decrease count if((*semaPt).Value < 0) { OS_Block(semaPt); //block and put into semaphore blocked list OS_Suspend(); OS_EnableInterrupts(); OS_DisableInterrupts(); } OS_EndCritical(status); }
CANmsgType BCAN_get(void) { long sr; CANmsgType data; OS_Wait(&CANmessagesReceived); sr = OS_StartCritical(); while(!CAN_RX_FIFOFifo_Get(&data)) //keep checking if the FIFO has data { #ifdef OS_COOP_SPINLOCK //if the interrupt fires and stuffs the FIFO OS_Suspend(); //before the systick triggers a threadswitch #endif //it will get its data faster (but other threads will have to wait) } OS_EndCritical(sr); return data; }
//this will be run by the time set in OS_Launch //Right now initialized to 1ms //ASSUMING .5 MS UNITS FOR PERIODIC THREADS void Timer1A_Handler(){ TIMER1_ICR_R = TIMER_ICR_TATOCINT; // acknowledge timer1A timeout int32_t status; status = OS_StartCritical(); //need to traverse linked list of peridoc threads struct PeriodicThread * tempTraversal = PeriodPt; if(PeriodPt != '\0') //at least one periodic thread has been added { while(tempTraversal != '\0') { (*tempTraversal).timeLeft --; //decrease 1ms if((*tempTraversal).timeLeft == 0) //need to run! { (*tempTraversal).timeLeft = (*tempTraversal).period; //reset time left (*(*tempTraversal).task)(); //run the task } tempTraversal = (*tempTraversal).nextPeriodicThread; //finished running or checking, go to next node } } OS_EndCritical(status); }