μC/OS-II的內(nèi)核結(jié)構(gòu)
程序清單 L3.18Motorola68HC11中的中斷服務(wù)子程序
本文引用地址:http://2s4d.com/article/201610/305744.htmM68HC11_ISR:/* 快中斷服務(wù)程序,必須禁止中斷*/
所有寄存器被CPU自動保存;
執(zhí)行用戶代碼以響應(yīng)中斷;
執(zhí)行中斷返回指令;
3.10 時(shí)鐘節(jié)拍
μC/OS需要用戶提供周期性信號源,用于實(shí)現(xiàn)時(shí)間延時(shí)和確認(rèn)超時(shí)。節(jié)拍率應(yīng)在每秒
10次到100次之間,或者說10到100Hz。時(shí)鐘節(jié)拍率越高,系統(tǒng)的額外負(fù)荷就越重。時(shí)鐘
節(jié)拍的實(shí)際頻率取決于用戶應(yīng)用程序的精度。時(shí)鐘節(jié)拍源可以是專門的硬件定時(shí)器,也可
以是來自50/60Hz交流電源的信號。
用戶必須在多任務(wù)系統(tǒng)啟動以后再開啟時(shí)鐘節(jié)拍器,也就是在調(diào)用OSStart()之后。
換句話說,在調(diào)用OSStart()之后做的第一件事是初始化定時(shí)器中斷。通常,容易犯的錯(cuò)
誤是將允許時(shí)鐘節(jié)拍器中斷放在系統(tǒng)初始化函數(shù)OSInit()之后,在調(diào)啟動多任務(wù)系統(tǒng)啟動
函數(shù)OSStart()之前,如程序清單L3.19所示。
程序清單L3.19啟動時(shí)鐘就節(jié)拍器的不正確做法.
voidmain(void)
{
.
.
OSInit();/* 初始化uC/OS-II*/
.
.
/* 應(yīng)用程序初始化代碼 ...*/
/*... 通過調(diào)用OSTaskCreate()創(chuàng)建至少一個(gè)任務(wù) */
.
.
允許時(shí)鐘節(jié)拍(TICKER)中斷;/* 千萬不要在這里允許時(shí)鐘節(jié)拍中斷!!! */
.
.
OSStart();/* 開始多任務(wù)調(diào)度 */
}
這里潛在地危險(xiǎn)是,時(shí)鐘節(jié)拍中斷有可能在μC/OS-Ⅱ啟動第一個(gè)任務(wù)之前發(fā)生,此時(shí)μC/OS-Ⅱ是處在一種不確定的狀態(tài)之中,用戶應(yīng)用程序有可能會崩潰。
μC/OS-Ⅱ中的時(shí)鐘節(jié)拍服務(wù)是通過在中斷服務(wù)子程序中調(diào)用OSTimeTick()實(shí)現(xiàn)的。
時(shí)鐘節(jié)拍中斷服從所有前面章節(jié)中描述的規(guī)則。時(shí)鐘節(jié)拍中斷服務(wù)子程序的示意代碼如程序清單L3.20所示。這段代碼必須用匯編語言編寫,因?yàn)樵贑語言里不能直接處理CPU的寄存器。
程序清單L3.20時(shí)鐘節(jié)拍中斷服務(wù)子程序的示意代碼
voidOSTickISR(void)
{
保存處理器寄存器的值;
調(diào)用OSIntEnter()或是將OSIntNesting加1;
調(diào)用OSTimeTick();
調(diào)用OSIntExit();
恢復(fù)處理器寄存器的值;
執(zhí)行中斷返回指令;
}
時(shí)鐘節(jié)拍函數(shù)OSTimeTick()的代碼如程序清單3.21所示。OSTimtick()以調(diào)用可由用戶定義的時(shí)鐘節(jié)拍外連函數(shù)OSTimTickHook()開始,這個(gè)外連函數(shù)可以將時(shí)鐘節(jié)拍函數(shù)OSTimtick()予以擴(kuò)展[L3.2(1)]。筆者決定首先調(diào)用OSTimTickHook()是打算在時(shí)鐘節(jié)拍中斷服務(wù)一開始就給用戶一個(gè)可以做點(diǎn)兒什么的機(jī)會,因?yàn)橛脩艨赡軙幸恍r(shí)間要求苛刻的工作要做。OSTimtick()中量大的工作是給每個(gè)用戶任務(wù)控制塊OS_TCB中的時(shí)間延時(shí)項(xiàng)OSTCBDly減1(如果該項(xiàng)不為零的話)。OSTimTick()從OSTCBList開始,沿著OS_TCB鏈表做,一直做到空閑任務(wù)[L3.21(3)]。當(dāng)某任務(wù)的任務(wù)控制塊中的時(shí)間延時(shí)項(xiàng)OSTCBDly減到了零,這個(gè)任務(wù)就進(jìn)入了就緒態(tài)[L3.21(5)]。而確切被任務(wù)掛起的函數(shù)OSTaskSuspend()掛起的任務(wù)則不會進(jìn)入就緒態(tài)[L3.21(4)]。OSTimTick()的執(zhí)行時(shí)間直接與應(yīng)用程序中建立了多少個(gè)任務(wù)成正比。
程序清單L3.21時(shí)鐘節(jié)拍函數(shù)OSTimtick()的一個(gè)節(jié)拍服務(wù)
voidOSTimeTick(void)
{
OS_TCB*ptcb;
OSTimeTickHook();(1)
ptcb=OSTCBList;(2)
while(ptcb->OSTCBPrio!=OS_IDLE_PRIO){(3)
OS_ENTER_CRITICAL();
if(ptcb->OSTCBDly!=0){
if(--ptcb->OSTCBDly==0){
if(!(ptcb->OSTCBStatOS_STAT_SUSPEND)){(4)
OSRdyGrp|=ptcb->OSTCBBitY;(5)
OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;
}else{
ptcb->OSTCBDly=1;
}
}
}
ptcb=ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
}
OS_ENTER_CRITICAL();(6)
OSTime++; (7)
OS_EXIT_CRITICAL();
}
OSTimeTick()還通過調(diào)用OSTime()[L3.21(7)]累加從開機(jī)以來的時(shí)間,用的是一個(gè)無符號32位變量。注意,在給OSTime加1之前使用了關(guān)中斷,因?yàn)槎鄶?shù)微處理器給32位數(shù)加1的操作都得使用多條指令。
中斷服務(wù)子程序似乎就得寫這么長,如果用戶不喜歡將中斷服務(wù)程序?qū)戇@么長,可以從任務(wù)級調(diào)用OSTimeTick(),如程序清單L3.22所示。要想這么做,得建立一個(gè)高于應(yīng)用程序中所有其它任務(wù)優(yōu)先級的任務(wù)。時(shí)鐘節(jié)拍中斷服務(wù)子程序利用信號量或郵箱發(fā)信號給這個(gè)高優(yōu)先級的任務(wù)。
程序清單L3.22時(shí)鐘節(jié)拍任務(wù)TickTask()作時(shí)鐘節(jié)拍服務(wù).
voidTickTask(void*pdata)
{
pdata=pdata;
for(;;){
OSMboxPend(...);/* 等待從時(shí)鐘節(jié)拍中斷服務(wù)程序發(fā)來的信號 */
OSTimeTick();
}
}
用戶當(dāng)然需要先建立一個(gè)郵箱(初始化成NULL)用于發(fā)信號給上述任何告知時(shí)鐘節(jié)拍中斷已經(jīng)發(fā)生了(程序清單L3.23)。
程序清單L3.23時(shí)鐘節(jié)拍中斷服務(wù)函數(shù)OSTickISR()做節(jié)拍服務(wù)。
voidOSTickISR(void)
{
保存處理器寄存器的值;
調(diào)用OSIntEnter()或是將OSIntNesting加1;
發(fā)送一個(gè)‘空’消息(例如, (void*)1)到時(shí)鐘節(jié)拍的郵箱;
調(diào)用OSIntExit();
恢復(fù)處理器寄存器的值;
執(zhí)行中斷返回指令;
}
3.11 μC/OS-Ⅱ初始化
在調(diào)用μC/OS-Ⅱ的任何其它服務(wù)之前,μC/OS-Ⅱ要求用戶首先調(diào)用系統(tǒng)初始化函數(shù)OSIint()。OSIint()初始化μC/OS-Ⅱ所有的變量和數(shù)據(jù)結(jié)構(gòu)(見OS_CORE.C)。
OSInit()建立空閑任務(wù)idle task,這個(gè)任務(wù)總是處于就緒態(tài)的??臻e任務(wù)OSTaskIdle()的優(yōu)先級總是設(shè)成最低,即OS_LOWEST_PRIO。如果統(tǒng)計(jì)任務(wù)允許OS_TASK_STAT_EN和任務(wù)建立擴(kuò)展允許都設(shè)為1,則OSInit()還得建立統(tǒng)計(jì)任務(wù)OSTaskStat()并且讓其進(jìn)入就緒態(tài)。OSTaskStat的優(yōu)先級總是設(shè)為OS_LOWEST_PRIO-1。
圖F3.7表示調(diào)用OSInit()之后,一些μC/OS-Ⅱ變量和數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系。其解釋是基于以下假設(shè)的:
評論