上班Day2
目前都還蠻好玩的
學到很多東西 發現以之前所學還是太淺了
繼續努力:)
void OSTimeTick (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
OSTimeTickHook(); /* Call user definable hook */
#if OS_TIME_GET_SET_EN > 0
OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */
OSTime++;
OS_EXIT_CRITICAL();
#endif
if (OSRunning == TRUE) {
ptcb = OSTCBList;
while (ptcb->OSTCBPrio != OS_IDLE_PRIO) {
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0) {
if (--ptcb->OSTCBDly == 0) {
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
} else {
ptcb->OSTCBDly = 1;
}
}
}
ptcb = ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
}
今天拿RTOS的source code來當範例
每一個系統都一定會有時間中斷
而中斷又以時間中斷為重任, 排程會由時間中斷來計數行程可執行的週期是否結束, 並且不管是在waiting queue或是睡覺中的任務只要時間中斷進來發現該你run了, 任務就會被設為running.
以代碼為例,
可以看到TimeTick()為前面的中斷處理後會呼叫的function, 必須知道每一次的中斷CPU都勢必需要保留前一個任務所留存的值, 在複雜的系統中, 有太多優化的方式可以加速這個操作. 但在嵌入式系統, 大多都是full context switch, 保留所有寄存器的值進stack. 所以中斷越多次所消耗掉的效能也越多. 這也是為什麼排程演算法也如此重要, 要是沒有寫好 preemption太常發生, 效能就直接下去了 甚至造成任務延時.
這一段代碼最重要的點是TCBList的結構,
他會走訪每一個行程的TCB並且查看狀態是否Ready, 如果行程睡飽了, 那這邊就會把他設成standby
離開TimeTick的時候會在reschedule一次, 這時就會依據排程性來執行下一個行程
結論就是, 時間中斷跟任務排程息息相關. 所以後面再看排程演算法的代碼或是公式解時都會有這項參數呢
晚安