我知道的ucos的任務切換方式一般有兩種:時鐘節拍中斷服務函數OSTickISR()進行切換,任務中調用時間延遲函數OSTimeDly()進行切換。
1.延遲函數OSTimeDly()進行切換:
y = OSTCBCur->OSTCBY;
OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;//清除準備優先級中的X標記量
if (OSRdyTbl[y] == 0) {
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;//如果對應的Y優先級中沒有X的優先級標記了,則把Y優先級也清除
}
OSTCBCur->OSTCBDly = ticks;//把對應的延時時間賦值給任務控制塊,在系統滴答中斷中會自動減
OS_SchedNew();//從準備好的任務中找到優先級最高的,賦值給OSPrioHighRdy,然後通過OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];從任務的鏈表中找出對應的任務控制塊, OS_TASK_SW();實際切換任務的函數,一般由彙編代碼完成。
2.中斷服務函數進行切換:
OS_CPU_SysTickHandler (void)位系統滴答中斷函數。
上面內容爲OSTimeTick()函數的主要內容,if (ptcb->OSTCBDly != 0) 和 if (--ptcb->OSTCBDly == 0) 判斷該任務塊中的設定的延時是否到了,OSRdyGrp |= ptcb->OSTCBBitY; OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;延時時間到後將該任務的優先級重新加入到優先級準備變量中。
OSIntExit()該函數和上面的內容差不多,是中斷函數中真正切換任務的地方。
3.有什麼不準確的地方請大神指出,謝謝!