秋霞电影网午夜鲁丝片无码,真人h视频免费观看视频,囯产av无码片毛片一级,免费夜色私人影院在线观看,亚洲美女综合香蕉片,亚洲aⅴ天堂av在线电影猫咪,日韩三级片网址入口

基于ARM9和μCOSII嵌入式系統(tǒng)設(shè)計(jì)

上傳人:zhu****ei 文檔編號:252990051 上傳時(shí)間:2024-11-27 格式:PPT 頁數(shù):130 大?。?41KB
收藏 版權(quán)申訴 舉報(bào) 下載
基于ARM9和μCOSII嵌入式系統(tǒng)設(shè)計(jì)_第1頁
第1頁 / 共130頁
基于ARM9和μCOSII嵌入式系統(tǒng)設(shè)計(jì)_第2頁
第2頁 / 共130頁
基于ARM9和μCOSII嵌入式系統(tǒng)設(shè)計(jì)_第3頁
第3頁 / 共130頁

下載文檔到電腦,查找使用更方便

14.9 積分

下載資源

還剩頁未讀,繼續(xù)閱讀

資源描述:

《基于ARM9和μCOSII嵌入式系統(tǒng)設(shè)計(jì)》由會員分享,可在線閱讀,更多相關(guān)《基于ARM9和μCOSII嵌入式系統(tǒng)設(shè)計(jì)(130頁珍藏版)》請?jiān)谘b配圖網(wǎng)上搜索。

1、,,第二級,,第三級,,第四級,,第五級,,第4章 基于ARM9和μC/OS-II嵌入式系統(tǒng)設(shè)計(jì),第4章 基于ARM9和μC/OS-II嵌入式系統(tǒng)設(shè)計(jì),,4.1 μC/OS-II的內(nèi)核,,4.2 μC/OS-II的API函數(shù),,4.3 μC/OS-II的應(yīng)用程序開發(fā),,4.4 μC/OS-II在S3C2410X上的移植,,4.5 μC/OS-II的API應(yīng)用,,4.6 基于μC/OS-II操作系統(tǒng)的開發(fā)案例,4.1 μC/OS-II的內(nèi)核,,多任務(wù)系統(tǒng)中,內(nèi)核負(fù)責(zé)管理各個(gè)任務(wù),或者說為每個(gè)任務(wù)分配CPU時(shí)間,并且負(fù)責(zé)任務(wù)之間的通訊。內(nèi)核提供的基本服務(wù)是任務(wù)切換。之所以使用實(shí)時(shí)內(nèi)核可

2、以大大簡化應(yīng)用系統(tǒng)的設(shè)計(jì),是因?yàn)閷?shí)時(shí)內(nèi)核允許將應(yīng)用分成若干個(gè)任務(wù),由實(shí)時(shí)內(nèi)核來管理它們。內(nèi)核本身也增加了應(yīng)用程序的額外負(fù)荷,代碼空間增加ROM的用量,內(nèi)核本身的數(shù)據(jù)結(jié)構(gòu)增加了RAM的用量。但更主要的是,每個(gè)任務(wù)要有自己的棧空間,這一塊吃起內(nèi)存來是相當(dāng)厲害的。內(nèi)核本身對CPU的占用時(shí)間一般在2到5個(gè)百分點(diǎn)之間。,,UC/OS-II有一個(gè)精巧的內(nèi)核調(diào)度算法,實(shí)時(shí)內(nèi)核精小,執(zhí)行效率高,算法巧妙,代碼空間很少。,4.1.1 μC/OS-II內(nèi)核調(diào)度特點(diǎn),,μC/OS-II內(nèi)核調(diào)度主要有如下特點(diǎn):,,●,只支持基于優(yōu)先級的搶占式調(diào)度算法,不支持時(shí)間片輪訓(xùn)。,,●,64個(gè)優(yōu)先級,只能創(chuàng)建64個(gè)任務(wù),用戶

3、只能創(chuàng)建56個(gè)任務(wù)。,,●,每個(gè)任務(wù)優(yōu)先級都不相同。,,●,不支持優(yōu)先級逆轉(zhuǎn)。,,●,READY隊(duì)列通過內(nèi)存映射表實(shí)現(xiàn)快速查詢。效率非常高。,,●,支持時(shí)鐘節(jié)拍。,,●,支持信號量,消息隊(duì)列,事件控制塊,事件標(biāo)志組,消息郵箱任務(wù)通訊機(jī)制。,●,支持中斷嵌套,中斷嵌套層數(shù)可達(dá)255層,中斷使用當(dāng)前任務(wù)的堆棧保存上下文。,,●,每個(gè)任務(wù)有自己的堆棧,堆棧大小用戶自己設(shè)定。,,●,支持動態(tài)修改任務(wù)優(yōu)先級。,,●,任務(wù)TCB為靜態(tài)數(shù)組,建立任務(wù)只是從中獲得一個(gè)TCB,不用動態(tài)分配,釋放內(nèi)存。,,●,任務(wù)堆棧為用戶靜態(tài)或者動態(tài)創(chuàng)建,在任務(wù)創(chuàng)建外完成,任務(wù)創(chuàng)建本身不進(jìn)行動態(tài)內(nèi)存分配。,,●,任務(wù)的總個(gè)數(shù)(

4、OS_MAX_TASKS)由用戶決定。,,●,0優(yōu)先級最高,63優(yōu)先級最低;,,●,有一個(gè)優(yōu)先級最低的空閑任務(wù),在沒有用戶任務(wù)運(yùn)行時(shí)運(yùn)行。,4.1.2 任務(wù)控制塊 OS_TCB描述,,UC/OS-II的TCB數(shù)據(jù)結(jié)構(gòu)簡單,內(nèi)容容易理解,保存最基本的任務(wù)信息,同時(shí)還支持裁減來減小內(nèi)存消耗,TCB是事先根據(jù)用戶配置,靜態(tài)分配內(nèi)存的結(jié)構(gòu)數(shù)組,通過優(yōu)先級序號進(jìn)行添加,查找,刪除等功能。減少動態(tài)內(nèi)存分配和釋放。因?yàn)橐揽績?yōu)先級進(jìn)行TCB分配,每個(gè)任務(wù)必須有自己的優(yōu)先級,不能和其他任務(wù)具有相同的優(yōu)先級。,typedef struct os_tcb,,{,,OS_STK *OSTCBStkPt

5、r;,,#if OS_TASK_CREATE_EXT_EN > 0,,void *OSTCBExtPtr;,,OS_STK *OSTCBStkBottom;,,INT32U OSTCBStkSize;,,INT16U OSTCBOpt;,,INT16U OSTCBId;,,#endif,,struct os_tcb *OSTCBNext;,,struct os_tcb *OSTCBPrev;,,#if ((OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_S

6、EM_EN),,OS_EVENT *OSTCBEventPtr;,,#endif,,#if ((OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN),,void *OSTCBMsg;,,#endif,,INT16U OSTCBDly;,,INT8U OSTCBStat;,,INT8U OSTCBPrio;,,INT8U OSTCBX;,INT8U OSTCBY;,,INT8U OSTCBBitX;,,INT8U O

7、STCBBitY;,,#if OS_TASK_DEL_EN,,BOOLEAN OSTCBDelReq;,,#endif,,} OS_TCB;,其中:,,OSTCBStkPtr,是指向當(dāng)前任務(wù)棧頂?shù)闹羔槨?,*OSTCBExtPtr,是任務(wù)擴(kuò)展模塊使用;,,*OSTCBStkBottom,指向任務(wù)堆棧棧底的指針;,,OSTCBStkSize,存有棧中可容納的指針元數(shù)目;,,OSTCBOpt,把“選擇項(xiàng)”傳給函數(shù)OSTashCreaktExt( )。只有當(dāng)用戶將,OS_CFG.H,文件中的OS_TASK_CREATE_EXT設(shè)為1時(shí),這個(gè)變量才有效;,,OSTCBId,用于存儲任務(wù)的

8、識別碼(ID)。這個(gè)變量現(xiàn)在沒有用,保留給將來擴(kuò)展用;,OSTCBNext,和,OSTCBPrev,用于任務(wù)控制塊OS_TCBs的雙向鏈表的前后鏈接,該鏈表在時(shí)鐘節(jié)拍函數(shù)OSTimerTick( )中使用;,,OSTCBEventPtr,是指向事件控制塊的指針;,,OSTCBMsg,是指向傳給任務(wù)的消息的指針;,,OSTCBDly,當(dāng)需要把任務(wù)延時(shí)若干時(shí)鐘節(jié)拍時(shí)要用到這個(gè)變量,或者需要把任務(wù)掛起一段時(shí)間以等待某事件的發(fā)生;,,OSTCBStat,是任務(wù)的狀態(tài)字;,,OSTCBPrio,是任務(wù)優(yōu)先級,高優(yōu)先級任務(wù)的OSTCBPrio值??;,OSTCBDelReq,是一個(gè)布爾量,用于表示該任務(wù)是否

9、需要刪除;,,OSTCBX, OSTCBY, OSTCBBitX和 OSTCBBitY,用于加速任務(wù)進(jìn)入就緒態(tài)的過程或進(jìn)入等待事件發(fā)生狀態(tài)的過程。這些值是在任務(wù)建立時(shí)算好的,或者是在改變?nèi)蝿?wù)優(yōu)先級時(shí)算出的。這些值的算法可由下面程序?qū)崿F(xiàn)。,,OSTCBY = priority >> 3;,,OSTCBBitY = OSMapTbl[priority >> 3];,,OSTCBX = priority & 0x07;,,OSTCBBitX = OSMapTbl[priority & 0x07];,4.1.3 就緒表(Ready List),,,UC/OS-II采用內(nèi)存映射的方式來實(shí)現(xiàn)READY隊(duì)

10、列的加入,查找,刪除功能,效率非常高。但是也因此只能支持64個(gè)任務(wù),每個(gè)任務(wù)都有自己的優(yōu)先級,不能和其他任務(wù)優(yōu)先級相同。,,每個(gè)任務(wù)的就緒態(tài)標(biāo)志都放入就緒表中的,就緒表中有兩個(gè)變量OSRdyGrp和OSRdyTbl[]。在OSRdyGrp中,任務(wù)按優(yōu)先級分組,8個(gè)任務(wù)為一組。OSRdyGrp中的每一位表示8組任務(wù)中每一組中是否有進(jìn)入就緒態(tài)的任務(wù)。任務(wù)進(jìn)入就緒態(tài)時(shí),就緒表OSRdyTbl[]中的相應(yīng)元素的相應(yīng)位也置為1。就緒表OSRdyTbl[]數(shù)組的大小取決于OS_LOWEST_PRIO(見文件OS_CFG..H)。,為確定下次該哪個(gè)優(yōu)先級的任務(wù)運(yùn)行了,UC/OS-II中的內(nèi)核調(diào)度器總是將最低

11、優(yōu)先級的任務(wù)在就緒表中相應(yīng)字節(jié)的相應(yīng)位置1,即OS_LOWEST_PRIO=1。OSRdyGrp和OSRdyTbl[]的關(guān)系是按以下規(guī)則給出的:,,當(dāng)OSRdyTbl[i]中的任何一位是1時(shí),OSRdyGrp的第i位置1。i從0到7。,,可用下面句使任務(wù)進(jìn)入就緒態(tài):,,OSRdyGrp |= OSMapTbl[prio >> 3];,,OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];,任務(wù)優(yōu)先級的低三位用于確定任務(wù)在總就緒表OSRdyTbl[]中的所在位。接下去的三位用于確定是在OSRdyTbl[]數(shù)組的第幾個(gè)元素。OSMapTbl[]

12、是在ROM中的(見文件OS_CORE.C)屏蔽字,用于限制OSRdyTbl[]數(shù)組的元素下標(biāo)在0到7之間。下面程序從就緒表中刪除一個(gè)任務(wù)。,,,if ((OSRdyTbl[prio >> 3] &=,,~OSMapTbl[prio & 0x07]) == 0),,OSRdyGrp &= ~OSMapTbl[prio >> 3];,以上代碼將就緒任務(wù)表數(shù)組OSRdyTbl[]中相應(yīng)元素的相應(yīng)位清0,而對于OSRdyGrp,只有當(dāng)被刪除任務(wù)所在任務(wù)組中全組任務(wù)一個(gè)都沒有進(jìn)入就緒態(tài)時(shí),才將相應(yīng)位清零。也就是說OSRdyTbl[prio>>3]所有的位都是0時(shí),OSRdyGrp的相應(yīng)位才清零。為了找到

13、那個(gè)進(jìn)入就緒態(tài)的優(yōu)先級最高的任務(wù),并不需要從OSRdyTbl[0]開始掃描整個(gè)就緒任務(wù)表,只需要查另外一張表,即優(yōu)先級判定表OSUnMapTbl([256])(見文件OS_CORE.C)。,OSRdyTbl[]中每個(gè)字節(jié)的8位代表這一組的8個(gè)任務(wù)哪些進(jìn)入就緒態(tài)了,低位的優(yōu)先級高于高位。利用這個(gè)字節(jié)為下標(biāo)來查OSUnMapTbl這張表,返回的字節(jié)就是該組任務(wù)中就緒態(tài)任務(wù)中優(yōu)先級最高的那個(gè)任務(wù)所在的位置。這個(gè)返回值在0到7之間。,確定進(jìn)入就緒態(tài)的優(yōu)先級最高的任務(wù)是用以下代碼完成的。,,,y = OSUnMapTbl[OSRdyGrp];,,x = OSUnMapTbl[OSRdyTbl

14、[y]];,,prio = (y << 3) + x;,,4.1.4 任務(wù)狀態(tài),,,UC/OS-II主要有,五種任務(wù)狀態(tài),,,睡眠態(tài),就是掛起態(tài),,阻塞態(tài)和延時(shí)態(tài),這里統(tǒng)一為等待狀態(tài)。增加了一個(gè)被,中斷狀態(tài),。UC/OS-Ⅱ總是建立一個(gè),空閑任務(wù),,這個(gè)任務(wù)在沒有其它任務(wù)進(jìn)入就緒態(tài)時(shí)投入運(yùn)行。這個(gè)空閑任務(wù)[OSTaskIdle()]永遠(yuǎn)設(shè)為最低優(yōu)先級空閑任務(wù)OSTaskIdle()什么也不做,只是在不停地給一個(gè)32位的名叫OSIdleCtr的計(jì)數(shù)器加1,統(tǒng)計(jì)任務(wù)使用這個(gè)計(jì)數(shù)器以確定現(xiàn)行應(yīng)用軟件實(shí)際消耗的CPU時(shí)間??臻e任務(wù)不可能被應(yīng)用軟件刪除。,,睡眠態(tài)(DORMANT),指任務(wù)駐留在程序空

15、間之中,還沒有交給μC/OS-Ⅱ管理,把任務(wù)交給μC/OS-Ⅱ是通過調(diào)用下述兩個(gè)函數(shù)之一:,OSTaskCreate(),或,OSTaskCreateExt(),。當(dāng)任務(wù)一旦建立,這個(gè)任務(wù)就進(jìn)入就緒態(tài)準(zhǔn)備運(yùn)行。任務(wù)的建立可以是在多任務(wù)運(yùn)行開始之前,也可以是動態(tài)地被一個(gè)運(yùn)行著的任務(wù)建立。如果一個(gè)任務(wù)是被另一個(gè)任務(wù)建立的,而這個(gè)任務(wù)的優(yōu)先級高于建立它的那個(gè)任務(wù),則這個(gè)剛剛建立的任務(wù)將立即得到CPU的控制權(quán)。一個(gè)任務(wù)可以通過調(diào)用,OSTaskDel(),返回到睡眠態(tài),或通過調(diào)用該函數(shù)讓另一個(gè)任務(wù)進(jìn)入睡眠態(tài)。,,調(diào)用,OSStart(),可以啟動多任務(wù)。,OSStart(),函數(shù)運(yùn)行進(jìn)入就緒態(tài)的優(yōu)先級

16、最高的任務(wù)。就緒的任務(wù)只有當(dāng)所有優(yōu)先級高于這個(gè)任務(wù)的任務(wù)轉(zhuǎn)為等待狀態(tài),或者是被刪除了,才能進(jìn)入運(yùn)行態(tài)。,,正在運(yùn)行的任務(wù)可以通過調(diào)用兩個(gè)函數(shù)之一將自身延遲一段時(shí)間,這兩個(gè)函數(shù)是,OSTimeDly(),或,OSTimeDlyHMSM(),。這個(gè)任務(wù)于是進(jìn)入等待狀態(tài),等待這段時(shí)間過去,下一個(gè)優(yōu)先級最高的、并進(jìn)入了就緒態(tài)的任務(wù)立刻被賦予了CPU的控制權(quán)。等待的時(shí)間過去以后,系統(tǒng)服務(wù)函數(shù),OSTimeTick(),使延遲了的任務(wù)進(jìn)入就緒態(tài)(詳見時(shí)鐘節(jié)拍)。,正在運(yùn)行的任務(wù)期待某一事件的發(fā)生時(shí)也要等待,手段是調(diào)用以下3個(gè)函數(shù)之一:,OSSemPend(),,,OSMboxPend(),,或,OSQPe

17、nd(),。調(diào)用后任務(wù)進(jìn)入了等待狀態(tài)(WAITING)。當(dāng)任務(wù)因等待事件被掛起(Pend),下一個(gè)優(yōu)先級最高的任務(wù)立即得到了CPU的控制權(quán)。當(dāng)事件發(fā)生了,被掛起的任務(wù)進(jìn)入就緒態(tài)。事件發(fā)生的報(bào)告可能來自另一個(gè)任務(wù),也可能來自中斷服務(wù)子程序。,正在運(yùn)行的任務(wù)是可以被中斷的,除非該任務(wù)將中斷關(guān)了,或者μC/OS-Ⅱ?qū)⒅袛嚓P(guān)了。被中斷了的任務(wù)就進(jìn)入了中斷服務(wù)態(tài),(ISR),。響應(yīng)中斷時(shí),正在執(zhí)行的任務(wù)被掛起,中斷服務(wù)子程序控制了CPU的使用權(quán)。中斷服務(wù)子程序可能會報(bào)告一個(gè)或多個(gè)事件的發(fā)生,而使一個(gè)或多個(gè)任務(wù)進(jìn)入就緒態(tài)。在這種情況下,從中斷服務(wù)子程序返回之前,μC/OS-Ⅱ要判定,被中斷的任務(wù)是否還是就

18、緒態(tài)任務(wù)中優(yōu)先級最高的。如果中斷服務(wù)子程序使一個(gè)優(yōu)先級更高的任務(wù)進(jìn)入了就緒態(tài),則新進(jìn)入就緒態(tài)的這個(gè)優(yōu)先級更高的任務(wù)將得以運(yùn)行,否則原來被中斷了的任務(wù)才能繼續(xù)運(yùn)行。,,當(dāng)所有的任務(wù)都在等待事件發(fā)生或等待延遲時(shí)間結(jié)束,μC/OS-Ⅱ執(zhí)行空閑任務(wù),(idle task),,執(zhí)行,OSTaskIdle(),函數(shù)。,4.1.5 任務(wù)切換,,,任務(wù)切換(ontext Switch)又稱上下文切換,或CPU寄存器內(nèi)容切換。,,當(dāng)多任務(wù)內(nèi)核決定運(yùn)行另外的任務(wù)時(shí),它保存正在運(yùn)行任務(wù)的當(dāng)前狀態(tài)(Context),即CPU寄存器中的全部內(nèi)容。這些內(nèi)容保存在任務(wù)的當(dāng)前狀況保存區(qū)(Task’s Context Sto

19、rage area),即任務(wù)自己的棧區(qū)之中。,,把將要運(yùn)行的任務(wù)的當(dāng)前狀況從該任務(wù)的棧中重新裝入CPU的寄存器,并開始下一個(gè)任務(wù)的運(yùn)行。這個(gè)過程叫做任務(wù)切換。,4.1.6 任務(wù)調(diào)度分析,,,μC/OS-Ⅱ只支持,優(yōu)先級搶占任務(wù)調(diào)度,,不支持,時(shí)間片輪訓(xùn)調(diào)度算法,,也不支持,優(yōu)先級逆轉(zhuǎn),。,,μC/OS-Ⅱ總是運(yùn)行進(jìn)入就緒態(tài)任務(wù)中優(yōu)先級最高的那一個(gè)。確定哪個(gè)任務(wù)優(yōu)先級最高,下面該哪個(gè)任務(wù)運(yùn)行的工作是由調(diào)度器(Scheduler)完成的。,,任務(wù)級的調(diào)度函數(shù):OSSched(),,中斷級的調(diào)度函數(shù):OSIntExt(),OSTCBHighRdy,指向優(yōu)先級最高的那個(gè)任務(wù)控制塊,OS_TCB,,是

20、將以,OSPrioHighRdy,為下標(biāo)的,OSTCBPrioTbl[],數(shù)組中的那個(gè)元素賦給OSTCBHighRdy來實(shí)現(xiàn)的。,,調(diào)用,OS_TASK_SW(),來完成任務(wù)切換。,,任務(wù)切換由以下兩步完成:,,將被掛起任務(wù)的,微處理器寄存器推入堆棧,,然后將較高優(yōu)先級的任務(wù)的,寄存器值從棧中恢復(fù)到寄存器中,。,,在μC/OS-Ⅱ中,就緒任務(wù)的棧結(jié)構(gòu)總是看起來跟剛剛發(fā)生過中斷一樣,所有微處理器的寄存器都保存在棧中。,換句話說,μC/OS-Ⅱ運(yùn)行就緒態(tài)的任務(wù)所要做的一切,只是,恢復(fù)所有的CPU寄存器,并運(yùn)行中斷返回指令。,,為了做到任務(wù)切換,運(yùn)行OS_TASK_SW(),人為模仿了一次中斷。多數(shù)

21、微處理器有軟中斷指令或者陷阱指令TRAP來實(shí)現(xiàn)上述操作。中斷服務(wù)子程序或陷阱處理(Trap hardler),也稱作事故處理(exception handler),必須提供中斷向量給匯編語言函數(shù)OSCtxSw()。OSCtxSw()除了需要OS_TCBHighRdy指向即將被掛起的任務(wù),還需要讓當(dāng)前任務(wù)控制塊OSTCBCur指向即將被掛起的任務(wù)。,OSSched()的所有代碼都屬,臨界段代碼,。在尋找進(jìn)入就緒態(tài)的優(yōu)先級最高的任務(wù)過程中,為防止中斷服務(wù)子程序把一個(gè)或幾個(gè)任務(wù)的就緒位置位,,中斷是被關(guān)掉的,。為縮短切換時(shí)間,OSSched()的代碼可用匯編語言寫。為增加可讀性,可移植性和將匯編語言

22、代碼最少化,OSSched()是用C寫的。,,任務(wù)切換的相關(guān)函數(shù)是與CPU體系相關(guān),用匯編語言編寫完成。,任務(wù)切換的相關(guān)函數(shù)如下:,,,,●,OSStartHighRdy() 執(zhí)行優(yōu)先級最高的任務(wù),,,●,OSCtxSw() 完成任務(wù)的上下文切換,,,●,OSIntCtxSw() 中斷后的上下文切換,,,●,OSTickISR() 中斷服務(wù)程序啟動,,4.1.7 UC/OS-II的初始化,,,OSInit()建立空閑任務(wù)idle task,這個(gè)任務(wù)總是處于就緒態(tài)的??臻e任務(wù)OSTaskIdle()的優(yōu)先級總是設(shè)成最低。,,這兩個(gè)任務(wù)的任務(wù)控制塊(OS_TCBs)是用雙向鏈表鏈接在

23、一起的。OSTCBList指向這個(gè)鏈表的起始處。當(dāng)建立一個(gè)任務(wù)時(shí),這個(gè)任務(wù)總是被放在這個(gè)鏈表的起始處。換句話說,OSTCBList總是指向最后建立的那個(gè)任務(wù)。鏈的終點(diǎn)指向空字符NULL(也就是零)。,因?yàn)檫@兩個(gè)任務(wù)都處在就緒態(tài),在就緒任務(wù)表OSRdyTbl[]中的相應(yīng)位是設(shè)為1的。還有,因?yàn)檫@兩個(gè)任務(wù)的相應(yīng)位是在OSRdyTbl[]的同一行上,即屬同一組,故OSRdyGrp中只有1位是設(shè)為1的。,,μC/OS-Ⅱ還初始化了4個(gè)空數(shù)據(jù)結(jié)構(gòu)緩沖區(qū),每個(gè)緩沖區(qū)都是單向鏈表,允許μC/OS-Ⅱ從緩沖區(qū)中迅速得到或釋放一個(gè)緩沖區(qū)中的元素??刂茐KOS_TCB的數(shù)目也就自動確定了。當(dāng)然,包括足夠的任務(wù)控制塊

24、分配給統(tǒng)計(jì)任務(wù)和空閑任務(wù)。,,4.2 μC/OS-II的API函數(shù),,,任何一個(gè)操作系統(tǒng)都會提供大量的API供程序員使用,uC/OS-II也不例外。由于uC/OS-II面向的是嵌入式開發(fā),并不要求大而全,所以內(nèi)核提供的API也就大多和多任務(wù)息息相關(guān)。主要的有以下幾類:,,1)任務(wù)類,,2)消息類,,3)同步類,,4)時(shí)間類,,5)臨界區(qū)與內(nèi)存類,4.2.1 任務(wù)類,1) OSTaskCreate( ),,在OSInit函數(shù)調(diào)用之后調(diào)用。作用是創(chuàng)建一個(gè)任務(wù)。,,有四個(gè)參數(shù):任務(wù)的入口地址,任務(wù)的參數(shù),任務(wù)堆棧的首地址、任務(wù)的優(yōu)先級。,,調(diào)用本函數(shù)后,系統(tǒng)會首先從TCB空閑列表內(nèi)申請一個(gè)空的T

25、CB指針,然后將會根據(jù)用戶給出參數(shù)初始化任務(wù)堆棧,并在內(nèi)部的任務(wù)就緒表內(nèi)標(biāo)記該任務(wù)為就緒狀態(tài)。最后返回,即可成功創(chuàng)建一個(gè)任務(wù)。,2) OSTaskSuspend( ),,,這個(gè)函數(shù)可以將指定的任務(wù)掛起。如果掛起的是當(dāng)前任務(wù)將會引發(fā)系統(tǒng)執(zhí)行任務(wù)切換先導(dǎo)函數(shù)OSShed來進(jìn)行一次任務(wù)切換。,這個(gè)函數(shù)只有一個(gè)參數(shù),是指定任務(wù)的優(yōu)先級。,事實(shí)上在μC/OS-II內(nèi)部,優(yōu)先級除了表示一個(gè)任務(wù)執(zhí)行的先后次序外,還起著分辨每一個(gè)任務(wù)的作用,換句話說,優(yōu)先級也就是任務(wù)的ID。所以uC/OS-II不允許出現(xiàn)相同優(yōu)先級的任務(wù)。,3) OSTaskResume( ),,,這個(gè)函數(shù)和上面的函數(shù)作用相反,它用于將指定的

26、已經(jīng)掛起的函數(shù)恢復(fù)成就緒狀態(tài)。如果恢復(fù)任務(wù)的優(yōu)先級高于當(dāng)前任務(wù)將會引發(fā)一次任務(wù)切換。其,參數(shù)類似OSTaskSuspend函數(shù),為指定任務(wù)的優(yōu)先級,。需要特別說明是,本函數(shù)并不要求和OSTaskSuspend函數(shù)成對使用。,4.2.2 消息類,,4) OSMboxCreate( ),,這個(gè)函數(shù)用于創(chuàng)建消息郵箱,消息郵箱是操作系統(tǒng)的任務(wù)間通信的一種方式,一個(gè)任務(wù)可以阻塞或者不阻塞地等待另外一個(gè)任務(wù)發(fā)送到它的郵箱的郵箱消息,而根據(jù)消息的內(nèi)容進(jìn)行動作。,,5)OSMboxPost( ),,這個(gè)函數(shù)用于一個(gè)任務(wù)向另一個(gè)任務(wù)的郵箱發(fā)郵箱消息,消息的內(nèi)容在參數(shù)中指定。,,6)OSMboxPend( ),

27、,這個(gè)函數(shù)用于一個(gè)任務(wù)獲取本任務(wù)郵箱中的消息,如果郵箱中沒有消息,則等待,任務(wù)處于阻塞狀態(tài)。,4.2.3 同步類,,7)OSSemCreate( ),,這個(gè)函數(shù)用于創(chuàng)建信號量,信號量是操作系統(tǒng)的任務(wù)間同步的一種方式,兩個(gè)或者多個(gè)任務(wù)可以獲知信號量的狀態(tài)并根據(jù)之進(jìn)行動作從而實(shí)現(xiàn)同步。,,8)OSSemPost( ),,這個(gè)函數(shù)用于一個(gè)任務(wù)對一個(gè)信號量進(jìn)行設(shè)置,設(shè)置的內(nèi)容在參數(shù)中指定。,,9)OSSemPend ( ),,這個(gè)函數(shù)用于一個(gè)任務(wù)獲取本信號量的狀態(tài),如果信號量不為零則成功獲取信號量并將信號量減去1,如果信號量為零,則等待,任務(wù)處于阻塞狀態(tài)。,4.2.4 時(shí)間類,,10) OSTim

28、eDly( ),,,這應(yīng)該是程序員們調(diào)用最多的一個(gè)函數(shù)了,這個(gè)函數(shù)完成功能很簡單,就是先掛起當(dāng)起當(dāng)前任務(wù),然后進(jìn)行任務(wù)切換,在指定的時(shí)間到來之后,將當(dāng)前任務(wù)恢復(fù)為就緒狀態(tài),但是并不一定運(yùn)行,如果恢復(fù)后是優(yōu)先級最高就緒任務(wù)的話,那么運(yùn)行之。簡單點(diǎn)說,就是可以任務(wù)延時(shí)一定時(shí)間后再次執(zhí)行它,或者說,暫時(shí)放棄CPU的使用權(quán)。一個(gè)任務(wù)可以不顯式的調(diào)用這些可以導(dǎo)致放棄CPU使用權(quán)的API,但那樣多任務(wù)性能會大大降低,因?yàn)榇藭r(shí)僅僅依靠時(shí)鐘機(jī)制在進(jìn)行任務(wù)切換。,4.2.5 內(nèi)存操作類,,11)OSMemCreate( ),,這個(gè)函數(shù)用于創(chuàng)建一個(gè)內(nèi)存分區(qū),μC/OS-II對內(nèi)存進(jìn)行統(tǒng)一管理,這樣利于消除簡單采

29、用malloc函數(shù)和free函數(shù)對內(nèi)存操作產(chǎn)生的內(nèi)存碎片。,,12)OSMemGet( ),,從一個(gè)指定的的內(nèi)存區(qū)中分配一個(gè)內(nèi)存塊。,,13)OSMemPut( ),,釋放一個(gè)內(nèi)存塊。,,μC/OS-II具有約的50個(gè)API函數(shù),除了上述列出的外,其他的在本章后面以附錄的方式給出。,4.3 μC/OS-II的應(yīng)用程序開發(fā),,應(yīng)用uC/OS-II,自然要為它開發(fā)應(yīng)用程序,下面論述基于uC/OS-II的應(yīng)用程序的基本結(jié)構(gòu)以及注意事項(xiàng)。,,每一個(gè)uC/OS-II應(yīng)用至少要有一個(gè)任務(wù)。而每一個(gè)任務(wù)必須被寫成無限循環(huán)的形式。以下是推薦的結(jié)構(gòu):,,void task ( void* pdata ),,{

30、 INT8U err;,,InitTimer(); // 可選,,For( ;; ),,{,,// 你的應(yīng)用程序代碼,,……,,……,,OSTimeDly(1); // 可選,,},,},以上就是基本結(jié)構(gòu),至于為什么要寫成無限循環(huán)的形式呢?那是因?yàn)橄到y(tǒng)會為每一個(gè)任務(wù)保留一個(gè)堆??臻g,由系統(tǒng)在任務(wù)切換的時(shí)候恢復(fù)上下文,并執(zhí)行一條 reti 指令返回。如果允許任務(wù)執(zhí)行到最后一個(gè)花括號(那一般都意味著一條ret指令)的話,很可能會破壞系統(tǒng)堆??臻g從而使應(yīng)用程序的執(zhí)行不確定。所以,每一個(gè)任務(wù)必須被寫成無限循環(huán)的形式。,程序中的,InitTimer()函數(shù),由系統(tǒng)提供,需要,在優(yōu)先級最高的任務(wù)內(nèi)調(diào)用,它

31、,,不能在for循環(huán)內(nèi)調(diào)用,。,,注意:這個(gè),函數(shù)是和所使用的CPU相關(guān)的,。,,在uC/OS –II中,不能在OSInit()或OSStart()內(nèi)調(diào)用Timer初始化程序,那樣會破壞系統(tǒng)的可移植性同時(shí)帶來性能上的損失。,4.4 μC/OS-II在S3C2410X上的移植,,4.4.1 移植原理,,所謂移植,指的是一個(gè)操作系統(tǒng)可以在某個(gè)微處理器或者微控制器上運(yùn)行。,,uCOS-II的大部分源代碼是用C 語言寫成的,仍需要用C 語言和匯編語言完成一些與處理器相關(guān)的代碼。,,比如:uCOS-II 在讀寫處理器、寄存器時(shí)只能通過匯編語言來實(shí)現(xiàn)。因?yàn)閡COS-II 在設(shè)計(jì)的時(shí)候就已經(jīng)充分考慮了可

32、移植性,所以,uCOS-II 的移植還是比較容易的。,,要使uCOS-II 可以正常工作,處理器必須滿足以下要求:,,1.處理器的C 編譯器能產(chǎn)生可重入代碼,,可重入的代碼指的是一段代碼(如一個(gè)函數(shù))可以被多個(gè)任務(wù)同時(shí)調(diào)用,而不必?fù)?dān)心會破壞數(shù)據(jù)。,,例:可以比較可重入型函數(shù)和非可重入型函數(shù):,程序1:可重入型函數(shù),,void swap(int *x, int *y),,{,,int temp;,,temp=*x;,,*x=*y;,,*y=temp;,,},程序2:非可重入型函數(shù),,int temp;,,void swap(int *x, int *y),,{,,temp=*x;,,*x=*y;

33、,,*y=temp;,,},程序1 中使用的是局部變量temp 作為變量。通常的C 編譯器,把局部變量分配在棧中。所以,多次調(diào)用同一個(gè)函數(shù),可以保證每次的temp 互不受影響。而程序2 中temp 定義的是全局變量,多次調(diào)用函數(shù)的時(shí)候,必然受到影響。,,代碼的可重入性是保證完成多任務(wù)的基礎(chǔ),除了在C 程序中使用局部變量以外,還需要C 編譯器的支持。筆者使用的是ARM ADS 的集成開發(fā)環(huán)境,均可以生成可重入的代碼。,2.在程序中可以打開或者關(guān)閉中斷,,OS_ENTER_CRITICAL()關(guān)閉,中斷,,OS_EXIT_CRITICAL() 打開中斷,,,3.處理器支持中斷,并且能產(chǎn)生定時(shí)中斷(

34、通常在10Hz~1000Hz 之間),。,,uCOS-II 是通過處理器產(chǎn)生的定時(shí)器的中斷來實(shí)現(xiàn)多任務(wù)之間的調(diào)度的。在ARM920T 的處理器上可以產(chǎn)生定時(shí)器中斷。,,,4.處理器支持能夠容納一定量數(shù)據(jù)的硬件堆棧。,,,5.處理器有將堆棧指針和其它CPU 寄存器存儲和讀出到堆棧(或者內(nèi)存)的指令。,,uCOS-II 進(jìn)行任務(wù)調(diào)度的時(shí)候,會把當(dāng)前任務(wù)的CPU 寄存器存放到此任務(wù)的堆棧中,然后,再從另一個(gè)任務(wù)的堆棧中恢復(fù)原來的工作寄存器,繼續(xù)運(yùn)行另一個(gè)任務(wù)。所以,寄存器的入棧和出棧是uCOS-II 多任務(wù)調(diào)度的基礎(chǔ)。,,圖4-1 說明了uC/OS 的結(jié)構(gòu)以及它與硬件的關(guān)系。,圖,4.1 Ucos-

35、II,硬件和軟件體系結(jié)構(gòu),,4.4.2 移植實(shí)現(xiàn),,,本書以uCOS-II在博創(chuàng)實(shí)驗(yàn)系統(tǒng)上的例程為中心進(jìn)行移植的說明。,,移植相關(guān)的文件分為兩類,其一是STARTUP 目錄下的系統(tǒng)初始化、配置等文件,其二是uCOS-II 的全部源碼,arch 目錄下的3 個(gè)文件是和處理器架構(gòu)相關(guān)的。下面對移植步驟進(jìn)行描述:,1.設(shè)置os_cpu.h 中與處理器和編譯器相關(guān)的代碼,,typedef unsigned char BOOLEAN;,,typedef unsigned char INT8U;,,typedef signed char INT8S;,,typedef unsigne

36、d int INT16U;,,typedef signed int INT16S;,,typedef unsigned long INT32U;,,typedef signed long INT32S;,,typedef float FP32;,,typedef double FP64;,,typedef unsigned int OS_STK;,,typedef unsigned int OS_CPU_SR;,,extern int INTS_OFF(void);,,extern void INTS_ON(void);,,#define OS_E

37、NTER_CRITICAL() { cpu_sr = INTS_OFF(); },,#define OS_EXIT_CRITICAL() { if(cpu_sr == 0) INTS_ON(); },,#define OS_STK_GROWTH 1,,1)與編譯器相關(guān)的數(shù)據(jù)類型,,,因?yàn)椴煌奈⑻幚砥饔胁煌淖珠L,所以uCOS-II 的移植包括了一系列的類型定義以確保其可移植性。尤其是uCOS-II 代碼從不使用C 的short,int 和long 等數(shù)據(jù)類型,因?yàn)樗鼈兪桥c編譯器相關(guān)的,不可移植。例如,INT16U 數(shù)據(jù)類型總是代表16 位的無符號整數(shù)?,F(xiàn)在,uCOS-II 和用戶的應(yīng)用

38、程序就可以估計(jì)出聲明為該數(shù)據(jù)類型的變量的取值范圍是0~65535。將uCOS-II 移植到32 位的處理器上也就意味著INT16U 實(shí)際被聲明為無符號短整型數(shù)據(jù)結(jié)構(gòu)而不是無符號整數(shù)數(shù)據(jù)結(jié)構(gòu)。但是,uCOS-II 所處理的仍然是INT16U。,2) OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),,,與所有的實(shí)時(shí)內(nèi)核一樣,uCOS-II 需要先禁止中斷再訪問代碼的臨界區(qū),并且在訪問完畢后重新允許中斷。這就使得uCOS-II 能夠保護(hù)臨界區(qū)代碼免受多任務(wù)或中斷服務(wù)例程(ISR)的破壞。在S3C2410X 上是通過兩個(gè)函數(shù)(OS_CPU_A.S)實(shí)現(xiàn)開關(guān)中斷的。,INT

39、S_OFF,,mrs r0, cpsr ; 當(dāng)前 CSR,,mov r1, r0 ; 復(fù)制屏蔽,,orr r1, r1, #0xC0 ; 屏蔽中斷位,,msr CPSR, r1 ; 關(guān)中斷(IRQ and FIQ),,and r0, r0, #0x80 ;從初始CSR 返回FIQ 位,,mov pc,lr ; 返回,,INTS_ON,,mrs r0, cpsr ; 當(dāng)前 CSR,,bic r0, r0, #0xC0 ; 屏蔽中斷,,msr CPSR, r0 ; 開中斷 (IRQ and FIQ),,mov pc,

40、lr ; 返回,,3)OS_STK_GROWTH,,,絕大多數(shù)的微處理器和微控制器的堆棧是從上往下長的。但是某些處理器是用另外一種方式工作的。uCOS-II 被設(shè)計(jì)成兩種情況都可以處理,只要在結(jié)構(gòu)常量OS_STK_GROWTH 中指定堆棧的生長方式就可以了。,,置OS_STK_GROWTH 為0 表示堆棧從下往上長。,,置OS_STK_GROWTH 為1 表示堆棧從上往下長。,,2.用C 語言編寫6 個(gè)操作系統(tǒng)相關(guān)的函數(shù)(OS_CPU_C.C),1)OSTaskStkInit,,,OSTaskCreate()和OSTaskCreateExt()通過調(diào)用OSTaskStkIn

41、it()來初始化任務(wù)的堆棧結(jié)構(gòu)。因此,堆??雌饋砭拖駝偘l(fā)生過中斷并將所有的寄存器保存到堆棧中的情形一樣。圖4.2 顯示了OSTaskStkInt()放到正被建立的任務(wù)堆棧中的東西。這里我們定義了堆棧是從上往下長的。在用戶建立任務(wù)的時(shí)候,用戶傳遞任務(wù)的地址,pdata 指針,任務(wù)的堆棧棧頂和任務(wù)的優(yōu)先級給OSTaskCreate()和OSTaskCreateExt()。一旦用戶初始化了堆棧,OSTaskStkInit()就需要返回堆棧指針?biāo)傅牡刂?。OSTaskCreate()和OSTaskCreateExt()會獲得該地址并將它保存到任務(wù)控制塊(OS_TCB)中。,圖4.2 堆棧的初始化,OS

42、_STK * OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos,INT16U opt),,{,,unsigned int * stk;,,stk = (unsigned int *)ptos; /* 裝載堆棧指針 */,,opt++;,,/* 為新任務(wù)建立堆棧 */,,*--stk = (unsigned int) task; /* pc */,,*--stk = (unsigned int) task; /* lr */,,*--stk = 12; /* r12 */,,*--s

43、tk = 11; /* r11 */,,*--stk = 10; /* r10 */,*--stk = 9; /* r9 */,,*--stk = 8; /* r8 */,,*--stk = 7; /* r7 */,,*--stk = 6; /* r6 */,,*--stk = 5; /* r5 */,,*--stk = 4; /* r4 */,,*--stk = 3;

44、 /* r3 */,,*--stk = 2; /* r2 */,,*--stk = 1; /* r1 */,,*--stk = (unsigned int) pdata;/* r0 */,,*--stk = (SUPMODE); /* cpsr */,,*--stk = (SUPMODE); /* spsr */,,return ((OS_STK *)stk);,,},,2)OSTaskCreateHook,,,當(dāng)用OSTaskCreate() 和OSTaskCreateExt() 建立任務(wù)的時(shí)候就會調(diào)

45、用OSTaskCreateHook()。該函數(shù)允許用戶或使用移植實(shí)例的用戶擴(kuò)展uCOS-II 功能。當(dāng)uCOS-II設(shè)置完了自己的內(nèi)部結(jié)構(gòu)后,會在調(diào)用任務(wù)調(diào)度程序之前調(diào)用OSTaskCreateHook()。該函數(shù)被調(diào)用的時(shí)候中斷是禁止的。因此用戶應(yīng)盡量減少該函數(shù)中的代碼以縮短中斷的響應(yīng)時(shí)間。,,當(dāng)OSTaskCreateHook()被調(diào)用的時(shí)候,它會收到指向已建立任務(wù)的OS_TCB 的指針,這樣它就可以訪問所有的結(jié)構(gòu)成員了。,,函數(shù)原型:void OSTaskCreateHook (OS_TCB *ptcb),3)OSTaskDelHook,,,當(dāng)任務(wù)被刪除的時(shí)候就會調(diào)用OSTaskDelH

46、ook()。該函數(shù)在把任務(wù)從uCOS-II 的內(nèi)部任務(wù)鏈表中解開之前被調(diào)用。當(dāng)OSTaskDelHook()被調(diào)用的時(shí)候,它會收到指向正被刪除任務(wù)的OS_TCB 的指針,這樣它就可以訪問所有的結(jié)構(gòu)成員了。OSTaskDelHook()可以來檢驗(yàn)TCB擴(kuò)展是否被建立(一個(gè)非空指針)并進(jìn)行一些清除操作。,,函數(shù)原型:void OSTaskDelHook (OS_TCB *ptcb),4)OSTaskSwHook,,,當(dāng)發(fā)生任務(wù)切換的時(shí)候就會調(diào)用OSTaskSwHook() 。OSTaskSwHook()可以直接訪問OSTCBCur 和OSTCBHighRdy,因?yàn)樗鼈兪侨肿兞?。OSTCBCur

47、指向被切換出去的任務(wù)OS_TCB,而OSTCBHighRdy 指向新任務(wù)OS_TCB。注意在調(diào)用OSTaskSwHook()期間中斷一直是被禁止的。因此用戶應(yīng)盡量減少該函數(shù)中的代碼以縮短中斷的響應(yīng)時(shí)間。,,函數(shù)原型:void OSTaskSwHook (void),5)OSTaskStatHook,,,OSTaskStatHook()每秒鐘都會被OSTaskStat()調(diào)用一次。用戶可以用OSTaskStatHook()來擴(kuò)展統(tǒng)計(jì)功能。,,例如,用戶可以保持并顯示每個(gè)任務(wù)的執(zhí)行時(shí)間,每個(gè)任務(wù)所用的CPU 份額,以及每個(gè)任務(wù)執(zhí)行的頻率等。,,函數(shù)原型:void OSTaskStatHook (v

48、oid),6)OSTimeTickHook,,,OSTimeTickHook()在每個(gè)時(shí)鐘節(jié)拍都會被OSTaskTick()調(diào)用。實(shí)際上,OSTimeTickHook()是在節(jié)拍被uCOS-II 真正處理,并通知用戶的移植實(shí)例或應(yīng)用程序之前被調(diào)用的。,,,函數(shù)原型:void OSTimeTickHook (void),,,后5 個(gè)函數(shù)為鉤子函數(shù),可以不加代碼。只有當(dāng)OS_CFG.H 中的OS_CPU_HOOKS_EN 被置為1 時(shí)才會產(chǎn)生這些函數(shù)的代碼。,3.用匯編語言編寫4 個(gè)與處理器相關(guān)的函數(shù),(OS_CPU.ASM),,,1)OSStartHighRdy ();運(yùn)行優(yōu)先級最高的就緒任務(wù)O

49、SStartHighRdy,,LDR r4, addr_OSTCBCur ; 得到當(dāng)前任務(wù)TCB 地址,,LDR r5, addr_OSTCBHighRdy ; 得到最高優(yōu)先級任務(wù)TCB 地址,,LDR r5, [r5] ; 獲得堆棧指針,,LDR sp, [r5] ; 轉(zhuǎn)移到新的堆棧中,,STR r5, [r4] ; 設(shè)置新的當(dāng)前任務(wù)TCB 地址,,LDMFD sp!, {r4} ;,,MSR SPSR, r4,,LDMFD sp!, {r4} ; 從棧頂獲得新的狀態(tài),,MSR CP

50、SR, r4 ; CPSR 處于SVC32Mode 摸式,,LDMFD sp!, {r0-r12, lr, pc } ; 運(yùn)行新的任務(wù),2)OS_TASK_SW ();任務(wù)級的任務(wù)切換函數(shù),,,STMFD sp!, {lr} ; 保存pc,,STMFD sp!, {lr} ; 保存lr,,STMFD sp!, {r0-r12} ; 保存寄存器和返回地址,,MRS r4, CPSR,,STMFD sp!, {r4} ; 保存當(dāng)前的PSR,,MRS r4, SPSR,,STMFD sp!, {r4} ; 保存SPSR

51、,,; OSPrioCur = OSPrioHighRdy,,LDR r4, addr_OSPrioCur,,LDR r5, addr_OSPrioHighRdy,,LDRB r6, [r5],,STRB r6, [r4],; 得到當(dāng)前任務(wù)TCB 地址,,LDR r4, addr_OSTCBCur,,LDR r5, [r4],,STR sp, [r5] ;保存sp 在被占先的任務(wù)的TCB,,; 得到最高優(yōu)先級任務(wù)TCB 地址,,LDR r6, addr_OSTCBHighRdy,,LDR r6, [r6],,LDR sp, [r6] ; 得到新任務(wù)堆棧指針,,; OSTCBCur =

52、 OSTCBHighRdy,,STR r6, [r4]; 設(shè)置新的當(dāng)前任務(wù)的TCB 地址,;保存任務(wù)方式寄存器,,LDMFD sp!, {r4},,MSR SPSR, r4,,LDMFD sp!, {r4},,MSR CPSR, r4,,; 返回到新任務(wù)的上下文,,LDMFD sp!, {r0-r12, lr, pc},,3)OSIntCtxSw(),;中斷級的任務(wù)切換函數(shù)OSIntCtxSw,,Add r7,sp, #16 ; 保存寄存器指針,,LDR sp,=IRQStack ;FIQ_STAC

53、K,,mrs r1,SPSR ; 得到暫停的 PSR,,orr r1,r1, #0xC0 ; 關(guān)閉 IRQ, FIQ。,,Msr CPSR_cxsf, r1,;轉(zhuǎn)換模式 (應(yīng)該是 SVC_MODE),,ldr r0,[r7,#52];從IRQ 堆棧中得到IRQ's LR (任務(wù) PC),,sub r0, r0, #4;當(dāng)前PC 地址是(saved_LR - 4),,STMFD sp!, {r0} ;保存任務(wù) PC,,STMFD sp!, {lr} ;保存 LR,,mov lr, r7,;保存FIQ堆棧 ptr in LR (轉(zhuǎn)到 nuke r7),,ldm

54、fd lr!,{r0-r12};,從FIQ 堆棧中得到保存的寄存器,,STMFD sp!, {r0-r12} ;在任務(wù)堆棧中保存寄存器,,;在任務(wù)堆棧上保存PSR 和任務(wù) PSR,,MRS r4, CPSR,,bic r4, r4, #0xC0 ; 使中斷位處于使能態(tài),,STMFD sp!, {r4} ; 保存任務(wù)當(dāng)前 PSR,,MRS r4, SPSR,,STMFD sp!, {r4} ; SPSR,,; OSPrioCur = OSPrioHighRdy // 改變當(dāng)前程序,,LDR r4, addr_OSPrioCur,,LDR r

55、5, addr_OSPrioHighRdy,,LDRB r6, [r5],,STRB r6, [r4],,; 得到被占先的任務(wù)TCB,,LDR r4, addr_OSTCBCur,,LDR r5, [r4],,STR sp, [r5] ; 保存sp 在被占先的任務(wù)的 TCB,,; 得到新任務(wù) TCB 地址,,LDR r6, addr_OSTCBHighRdy,,LDR r6, [r6],,LDR sp, [r6] ; 得到新任務(wù)堆棧指針,,; OSTCBCur = OSTCBHighRdy,,STR r6, [r4] ;設(shè)置新的當(dāng)前任務(wù)的TCB 地址,,LDM

56、FD sp!, {r4},,MSR SPSR, r4,,LDMFD sp!, {r4},,BIC r4,r4,#0xC0 ;必須退出新任務(wù)通過允許中斷,,MSR CPSR, r4,,LDMFD sp!, {r0-r12, lr, pc},,4)OSTickISR();時(shí)鐘節(jié)拍中斷,,,多任務(wù)操作系統(tǒng)的任務(wù)調(diào)度是基于時(shí)鐘節(jié)拍中斷的,uCOS-II 也需要處理器提供一個(gè)定時(shí)器中斷來產(chǎn)生節(jié)拍,借以實(shí)現(xiàn)時(shí)間的延時(shí)和期滿功能。但在博創(chuàng)實(shí)驗(yàn)系統(tǒng)移植uCOS-II 時(shí),時(shí)鐘節(jié)拍中斷的服務(wù)函數(shù)并非uCOS-II 文獻(xiàn)中提到的OSTickISR(),而直接是C 語言編寫的OSTimeTick()。博創(chuàng)

57、實(shí)驗(yàn)系統(tǒng)uCOS-II 移植時(shí)占用的時(shí)鐘資源是TIMER1。在平臺初始化函數(shù)ARMTargetInit()中,調(diào)用uHALr_InitTimers()函數(shù)初始化TIMER4相關(guān)寄存器; 調(diào)用uHALr_InstallSystemTimer(void) 開始系統(tǒng)時(shí)鐘,其中通過語句SetISR_Interrupt(IRQ_TIMER4, TimerTickHandle, NULL)將TimerTickHandle 函數(shù)設(shè)置為TIMER4 的中斷服務(wù)函數(shù)。這些函數(shù)在文件UHAL.C 以及ISR.C 中。,,程序中必須在開始多任務(wù)調(diào)度之后再允許時(shí)鐘節(jié)拍中斷,即在OSStart()調(diào)用過后,uCOS-I

58、I 運(yùn)行的第一個(gè)任務(wù)中啟動節(jié)拍中斷。如果在調(diào)用OSStart()啟動多任務(wù)調(diào)度之前就啟動時(shí)鐘節(jié)拍中斷,uCOS-II 運(yùn)行狀態(tài)可能不確定而導(dǎo)致崩潰。博創(chuàng)實(shí)驗(yàn)系統(tǒng)是在系統(tǒng)任務(wù)SYS_Task 中調(diào)用uHALr_InstallSystemTimer()函數(shù)設(shè)置TIMER4的IRQ 中斷的,從而啟動時(shí)鐘節(jié)拍。SYS_Task()在文件OSAddTask.C 中定義,用戶不必創(chuàng)建。,4. 編寫一個(gè)簡單的多任務(wù)程序來測試一下移植是否成功。,,,為了使uCOS-II 可以正常運(yùn)行,除了上述必須的移植工作外,硬件初始化和配置文件也是必須的。STARTUP 目錄下的文件還包括中斷處理,時(shí)鐘,串口通信等基本功能

59、函數(shù)。,,在文件main.c 中給出了應(yīng)用程序的基本框架,包括初始化和多任務(wù)的創(chuàng)建,啟動等。,任務(wù)創(chuàng)建方法如下:,,1)在程序開頭定義任務(wù)堆棧,任務(wù)函數(shù)聲明和任務(wù)優(yōu)先級:,,OS_STK TaskName_Stack[STACKSIZE]={0, }; //任務(wù)堆棧,,void TaskName(void *Id); //任務(wù)函數(shù),,#define TaskName_Prio N //任務(wù)優(yōu)先級,,2)在main()函數(shù)中調(diào)用OSStart()函數(shù)之前用下列語句創(chuàng)建任務(wù):,,OSTaskCreate(TaskName,(void*)0,(OS_STK*)&TaskName_Stack[STAC

60、KSIZE-1],,,TaskName_Prio);,,OSTaskCreate()函數(shù)的原型是:,,INT8U OSTaskCreate (void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT8U prio);,需要將任務(wù)函數(shù)TaskName,任務(wù)堆棧TaskName_Stack,任務(wù)優(yōu)先級TaskName_Prio 三個(gè)參數(shù)傳給OSTaskCreate()函數(shù)。根據(jù)任務(wù)函數(shù)的內(nèi)容決定堆棧大小,宏STACKSIZE 定義為4KB,可以在此基數(shù)上乘倍。任務(wù)優(yōu)先級越高,TaskName_Prio 值越?。籾COS-II 可以管理64個(gè)任務(wù),

61、由OSInit()創(chuàng)建的空閑任務(wù)的優(yōu)先級最低為63;uCOS-II 保留4 個(gè)最高和4 個(gè)最低優(yōu)先級,用戶任務(wù)可以使用其余56 個(gè)優(yōu)先級值。,3)編寫任務(wù)函數(shù)內(nèi)容:,,void TaskName(void *Id),,{,,//添入任務(wù)初始化語句,,for(;;),,{ //添入任務(wù)循環(huán)內(nèi)容,,OSTimeDly(SusPendTime);//掛起一定時(shí)間,以使其他任務(wù)可以占用CPU,,},,},,uCOS-II 至少要有一個(gè)任務(wù),這里已經(jīng)創(chuàng)建一個(gè)系統(tǒng)任務(wù)SYS_Task, 啟動系統(tǒng)時(shí)鐘和多任務(wù)切換。為了驗(yàn)證uCOS-II 多任務(wù)切換的進(jìn)行,再編寫兩個(gè)簡單的任務(wù),分別在超級終端上輸出run t

62、ask1 和run task2。可以參考main.c 的結(jié)構(gòu)創(chuàng)建多個(gè)不同功能的任務(wù),觀察個(gè)任務(wù)的切換。,5. 編譯并下載移植后的uCOS-II,,,所有的源代碼都準(zhǔn)備好后就可以進(jìn)行編譯了。在ADS 環(huán)境下需要設(shè)置工程的訪問路徑。從菜單Edit | Debug Settings 進(jìn)入設(shè)置對話框,在Target | Access Paths 中選擇User Paths并選上Always search user paths。然后點(diǎn)Add 按鈕添加路徑ucos-ii 和arch。這主要是設(shè)置編譯器處理文件包含時(shí)的搜索范圍。,,按照映象文件下載方法實(shí)驗(yàn)中的操作方法將編譯后的代碼下載到平臺的flash 中

63、。這個(gè)實(shí)驗(yàn)從結(jié)構(gòu)上看和其他的實(shí)驗(yàn)沒有多大區(qū)別,同樣生成可執(zhí)行文件system.bin。將system.bin 裝載到Flash 中,重啟平臺,然后在超級終端上觀察結(jié)果。,4.5 μC/OS-II的API應(yīng)用,,本節(jié)將以一些簡單的例子針對μC/OS-II的API應(yīng)用進(jìn)行描述。,,4.5.1 任務(wù)相關(guān)函數(shù)的使用,,任務(wù)相關(guān)函數(shù)主要包括:任務(wù)創(chuàng)建,任務(wù)的掛起和恢復(fù),任務(wù)的優(yōu)先級改變,任務(wù)刪除和任務(wù)查詢等。,,在這里我們以一個(gè)最簡單的“helloworld”移動的程序?yàn)槔?,對任?wù)的概念和相關(guān)的API的應(yīng)用進(jìn)行描述。,,例4-1,,#include "includes.h",,#include "d

64、ebug.h",,#define TASK_STK_SIZE 512,,OS_STK Task_1_Stk[TASK_STK_SIZE];,,void Task(void *data);,void main (void),,{,,PC_DispClrScr(DISP_FGND_WHITE +,,DISP_BGND_BLACK);/* 清屏幕*/,,OSInit(); /* 初始化 uC/OS-II */,,PC_DOSSaveReturn();,,PC_VectSet(uCOS, OSCtxSw);

65、,,OSTaskCreate(Task, (void *)0, &Task_1_Stk[TASK_STK_SIZE - 1], 0); /*創(chuàng)建任務(wù)*/,,OSStart(); /* 多任務(wù)啟動*/,,},,void Task (void *pdata),,{,,INT8U x=1;,,INT8U y=1;,,INT8U judge;,,INT8U err;,,INT16S key;,,OS_ENTER_CRITICAL();,,PC_VectSet(0x08, OSTickISR);,,PC_SetTickRate(O

66、S_TICKS_PER_SEC);,,OS_EXIT_CRITICAL();,,for (;;) {,,PC_DispClrScr(DISP_FGND_WHITE +,,DISP_BGND_BLACK); /*清屏幕*/,PC_DispStr(x, y, "helloworld!!", DISP_FGND_WHITE + DISP_BGND_RED + DISP_BLINK);,,x=(x+1)%(80-12);,,y=(y+1)%(25-1);,,,,if (PC_GetKey(&key) == TRUE) {,,if (key == 0x1B) {,,PC_DOSReturn();,,},,},,OSCtxSwCtr = 0;,,OSTimeDlyHMSM(0, 0, 0, 350);,,},,},,OSTaskCreate(Task, (void *)0,,,&Task_1_Stk[TASK_STK_SIZE - 1], 0);,,是創(chuàng)建任務(wù)語句,其中Task是任務(wù)的實(shí)現(xiàn)函數(shù),(void *)0是傳遞給任務(wù)的參數(shù),Task_1_Stk是任務(wù)的堆棧。該程序?qū)崿F(xiàn)的功能是將“hello

展開閱讀全文
溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

相關(guān)資源

更多
正為您匹配相似的精品文檔
關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  sobing.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號:ICP2024067431-1 川公網(wǎng)安備51140202000466號


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng),我們立即給予刪除!