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_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); }