版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、移植μC/OS-Ⅱ,μC/OS-Ⅱ的移植,移植就是使一個實(shí)時內(nèi)核能在某個微處理器或微控制器上運(yùn)行。為了方便移植,大部分的μC/OS-Ⅱ代碼是用C語言寫的;但仍需要用C和匯編語言寫一些與處理器相關(guān)的代碼,這是因?yàn)棣藽/OS-Ⅱ在讀寫處理器寄存器時只能通過匯編語言來實(shí)現(xiàn)。由于μC/OS-Ⅱ在設(shè)計(jì)時就已經(jīng)充分考慮了可移植性,所以μC/OS-Ⅱ的移植相對來說是比較容易的。,μC/OS-Ⅱ的移植,要使μC/OS-Ⅱ正常運(yùn)行,處理器必須滿足以下
2、要求:1.處理器的C編譯器能產(chǎn)生可重入代碼。2. 用C語言就可以打開和關(guān)閉中斷。3. 處理器支持中斷,并且能產(chǎn)生定時中斷(通常在10至100Hz之間)。4. 處理器支持能夠容納一定量數(shù)據(jù)(可能是幾千字節(jié))的硬件堆棧。5. 處理器有將堆棧指針和其它CPU寄存器讀出和存儲到堆棧或內(nèi)存中的指令。像Motorola 6805系列的處理器不能滿足上面的第4條和第5條要求,所以μC/OS-Ⅱ不能在這類處理器上運(yùn)行。
3、,μC/OS-Ⅱ的結(jié)構(gòu)以及與硬件的關(guān)系,μC/OS-Ⅱ的移植,移植工作包括以下幾個內(nèi)容:用#define設(shè)置一個常量的值(OS_CPU.H)聲明10個數(shù)據(jù)類型(OS_CPU.H)用#define聲明三個宏(OS_CPU.H)用C語言編寫六個簡單的函數(shù)(OS_CPU_C.C)編寫四個匯編語言函數(shù)(OS_CPU_A.ASM)根據(jù)處理器的不同,一個移植實(shí)例可能需要編寫或改寫50至300行的代碼。,μC/OS-Ⅱ的移植,一旦代碼移植
4、結(jié)束,下一步工作就是測試。測試一個象μC/OS-Ⅱ一樣的多任務(wù)實(shí)時內(nèi)核并不復(fù)雜。甚至可以在沒有應(yīng)用程序的情況下測試,就是讓內(nèi)核自己測試自己。這樣做有兩個好處:第一,避免使本來就復(fù)雜的事情更加復(fù)雜;第二,如果出現(xiàn)問題,可以知道問題出在內(nèi)核代碼上而不是應(yīng)用程序。開始測試的時候可以運(yùn)行一些簡單的任務(wù)和時鐘節(jié)拍中斷服務(wù)例程。一旦多任務(wù)調(diào)度成功地運(yùn)行了,再添加應(yīng)用程序的任務(wù)就是非常簡單的工作了。,移植開發(fā)工具,移植μC/OS-Ⅱ需要一個C編
5、譯器,并且是針對用戶用的CPU的。因?yàn)棣藽/OS-Ⅱ是一個可剝奪型內(nèi)核,用戶只有通過C編譯器來產(chǎn)生可重入代碼;C編譯器還要支持匯編語言程序。絕大部分的C編譯器都是為嵌入式系統(tǒng)設(shè)計(jì)的,它包括匯編器、連接器和定位器。連接器用來將不同的模塊(編譯過和匯編過的文件)連接成目標(biāo)文件,定位器則允許用戶將代碼和數(shù)據(jù)放置在目標(biāo)處理器的指定內(nèi)存映射空間中。所用的C編譯器還必須提供一個機(jī)制來從C中打開和關(guān)閉中斷。,移植目錄結(jié)構(gòu)和文件,各個微處理器的移
6、植源代碼必須在以下兩個或三個文件中找到:OS_CPU.H,OS_CPU_C.C,OS_CPU_A.ASM。匯編語言文件OS_CPU_A.ASM是可選擇的,因?yàn)槟承〤編譯器允許用戶在C語言中插入?yún)R編語言,所以用戶可以將所需的匯編語言代碼直接放到OS_CPU_C.C中。一個放置移植實(shí)例的目錄結(jié)構(gòu)如表所示。這樣的目錄結(jié)構(gòu),使用戶更容易找到目標(biāo)處理器的文件。,INCLUDES.H文件,INCLUDES.H是一個頭文件,它在所有.C文件的第一
7、行被包含。#include "includes.h" INCLUDES.H使得用戶項(xiàng)目中的每個.C文件不用分別去考慮它實(shí)際上需要哪些頭文件。使用INCLUDES.H的唯一缺點(diǎn)是它可能會包含一些實(shí)際不相關(guān)的頭文件,這樣每個文件的編譯時間可能會增加,但是它增強(qiáng)了代碼的可移植性。用戶可以通過編輯INCLUDES.H來增加自己的頭文件,但是用戶的頭文件必須添加在頭文件列表的最后。,OS_CPU.H文件,#i
8、fdef OS_CPU_GLOBALS#define OS_CPU_EXT#else#define OS_CPU_EXT extern#endif /************************************ 數(shù)據(jù)類型 (與編譯器相關(guān))************************************/ typedef unsigned char BOOLEAN
9、;typedef unsigned char INT8U; /* 無符號8位整數(shù) (1)/整型數(shù)據(jù)結(jié)構(gòu)既是可移植的又是直觀的 typedef signed char INT8S; /* 有符號8位整數(shù)typedef unsigned int INT16U; /* 無符號16位整數(shù)typedef signed int INT16S; /* 有符號16位整數(shù)typedef
10、 unsigned long INT32U; /* 無符號32位整數(shù)typedef signed long INT32S; /* 有符號32位整數(shù)typedef float FP32; /* 單精度浮點(diǎn)數(shù) (2)/浮點(diǎn)數(shù)據(jù)類型 typedef double FP64; /* 雙精度浮點(diǎn)數(shù) typedef unsigned int
11、 OS_STK; /* 堆棧入口寬度為16位,用戶所必須要做的就是查看編譯器手冊,并找到對應(yīng)于μC/OS-Ⅱ的標(biāo)準(zhǔn)C數(shù)據(jù)類型。,OS_CPU.H文件(續(xù)),/************************** 與處理器相關(guān)的代碼*************************/ #define OS_ENTER_CRITICAL() ??? /* 禁止中斷 */ (3)#define
12、 OS_EXIT_CRITICAL() ??? /* 允許中斷 */ #define OS_STK_GROWTH 1 /* 定義堆棧的增長方向: 1=向下, 0=向上 */(4) /絕大多數(shù)的微處理器和微控制器的堆棧是從上往下長的,但是某些處理器是用另外一種方式工作的。μC/OS-Ⅱ被設(shè)計(jì)成兩種情況都可以處理。#define OS_TASK_SW() ??? (5)/μC/O
13、S-Ⅱ從低優(yōu)先級任務(wù)切換到最高優(yōu)先級任務(wù)時調(diào)用OS_TASK_SW() 。任務(wù)切換只是簡單的將處理器寄存器保存到將被掛起的任務(wù)的堆棧中,并且將更高優(yōu)先級的任務(wù)從堆棧中恢復(fù)出來。,上述代碼中的???部分,對于不同的微處理器來說,都不一樣。例如通過執(zhí)行STI命令在Intel 80186上禁止中斷,并用CLI命令來允許中斷。#define OS_ENTER_CRITICAL() asm CLI#define OS_EXIT_CRIT
14、ICAL() asm STI,OS_CPU_A.ASM文件,μC/OS-Ⅱ的移植實(shí)例要求用戶編寫四個簡單的匯編語言函數(shù):OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OSTickISR()如果用戶的編譯器支持插入?yún)R編語言代碼的話,用戶就可以將所有與處理器相關(guān)的代碼放到OS_CPU_C.C文件中,而不必再擁有一些分散的匯編語言文件。,OSStartHighRdy(),void OSStartHi
15、ghRdy (void){ Call user definable OSTaskSwHook(); Get the stack pointer of the task to resume: Stack pointer = OSTCBHighRdy->OSTCBStkPtr;
16、 OSRunning = TRUE; Restore all processor registers from the new task's stack; Execute a return from interrupt instruction; },要想運(yùn)行最高優(yōu)先級任務(wù),用戶所要做的是將所有處理器寄存器按順序從任務(wù)堆棧中恢復(fù)出來,并且執(zhí)行中斷的返回。,注意:OSStart
17、HighRdy()必須調(diào)用OSTaskSwHook(),因?yàn)橛脩粽谶M(jìn)行任務(wù)切換的部分工作——用戶在恢復(fù)最高優(yōu)先級任務(wù)的寄存器。而OSTaskSwHook()可以通過檢查OSRunning來知道是OSStartHighRdy()在調(diào)用它(OSRunning為FALSE)還是正常的任務(wù)切換在調(diào)用它(OSRunning為TRUE)。OSStartHighRdy()還必須在最高優(yōu)先級任務(wù)恢復(fù)之前和調(diào)用OSTaskSwHook()之后設(shè)置OS
18、Running為TRUE。,OSCtxSw(),任務(wù)級的切換問題是通過發(fā)軟中斷命令或依靠處理器執(zhí)行陷阱指令來完成的。中斷服務(wù)例程,陷阱或異常處理例程的向量地址必須指向OSCtxSw()。如果當(dāng)前任務(wù)調(diào)用μC/OS-Ⅱ提供的系統(tǒng)服務(wù),并使得更高優(yōu)先級任務(wù)處于就緒狀態(tài),μC/OS-Ⅱ就會借助上面提到的向量地址找到OSCtxSw()。在系統(tǒng)服務(wù)調(diào)用的最后,μC/OS-Ⅱ會調(diào)用OSSched(),并由此來推斷當(dāng)前任務(wù)不再是要運(yùn)行的最重要的任
19、務(wù)了。OSSched()先將最高優(yōu)先級任務(wù)的地址裝載到OSTCBHighRdy中,再通過調(diào)用OS_TASK_SW()來執(zhí)行軟中斷或陷阱指令。注意:變量OSTCBCur早就包含了指向當(dāng)前任務(wù)的任務(wù)控制塊(OS_TCB)的指針。軟中斷 (或陷阱) 指令會強(qiáng)制一些處理器寄存器(比如返回地址和處理器狀態(tài)字)到當(dāng)前任務(wù)的堆棧中,并使處理器執(zhí)行OSCtxSw()。,OSCtxSw()的原型程序,void OSCtxSw(void){ 保存處
20、理器寄存器; 將當(dāng)前任務(wù)的堆棧指針保存到當(dāng)前任務(wù)的OS_TCB中: OSTCBCur->OSTCBStkPtr = Stack pointer; 調(diào)用用戶定義的OSTaskSwHook(); OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; 得到需要恢復(fù)的任務(wù)的堆棧指針: Stack poi
21、nter = OSTCBHighRdy->OSTCBStkPtr; 將所有處理器寄存器從新任務(wù)的堆棧中恢復(fù)出來; 執(zhí)行中斷返回指令; },上述這些代碼必須寫在匯編語言中,因?yàn)橛脩舨荒苤苯訌腃中訪問CPU寄存器。注意在OSCtxSw()和用戶定義的函數(shù)OSTaskSwHook()的執(zhí)行過程中,中斷是禁止的。,OSIntCtxSw(),OSIntExit()通過調(diào)用OSIntCtxSw()來從ISR中執(zhí)行切換功能
22、,所有的處理器寄存器都被正確地保存到了被中斷的任務(wù)的堆棧之中。實(shí)際上除了我們需要的東西外,堆棧結(jié)構(gòu)中還有其它的一些東西。OSIntCtxSw()必須要清理堆棧,這樣被中斷的任務(wù)的堆棧結(jié)構(gòu)內(nèi)容才能滿足我們的需要。,在ISR執(zhí)行過程中的堆棧內(nèi)容,當(dāng)中斷來臨的時候,處理器會結(jié)束當(dāng)前的指令,識別中斷并且初始化中斷處理過程,包括將處理器的狀態(tài)寄存器和返回被中斷的任務(wù)的地址保存到堆棧中(1)。接著,CPU會調(diào)用正確的ISR,要求用戶的ISR在開
23、始時要保存剩下的處理器寄存器(2)。μC/OS-Ⅱ要求用戶的ISR在完成中斷服務(wù)的時候調(diào)用OSIntExit(),導(dǎo)致調(diào)用者的返回地址被保存到被中斷的任務(wù)的堆棧中(3)。處理器的狀態(tài)寄存器會被保存到被中斷的任務(wù)的堆棧中(4)。調(diào)用OSIntCtxSw()使返回地址被保存到被中斷的任務(wù)的堆棧中(5)。,OSIntCtxSw()的原型程序,void OSIntCtxSw(void){ 調(diào)整堆棧指針來去掉在調(diào)用:
24、OSIntExit(), OSIntCtxSw()過程中壓入堆棧的多余內(nèi)容; 將當(dāng)前任務(wù)堆棧指針保存到當(dāng)前任務(wù)的OS_TCB中: OSTCBCur->OSTCBStkPtr = 堆棧指針; 調(diào)用用戶定義的OSTaskSwHook(); OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; 得到需要恢復(fù)的任務(wù)的堆棧
25、指針: 堆棧指針 = OSTCBHighRdy->OSTCBStkPtr; 將所有處理器寄存器從新任務(wù)的堆棧中恢復(fù)出來; 執(zhí)行中斷返回指令; },這些代碼必須寫在匯編語言中,因?yàn)橛脩舨荒苤苯訌腃語言中訪問CPU寄存器。,OSTickISR(),μC/OS-Ⅱ要求用戶提供一個時鐘資源來實(shí)現(xiàn)時間的延時和期滿功能。時鐘節(jié)拍應(yīng)該每秒鐘發(fā)生10-100次??梢允褂糜布r鐘,也可以從交流電中獲得50/60
26、Hz的時鐘頻率。用戶必須在開始多任務(wù)調(diào)度后(調(diào)用OSStart()后)允許時鐘節(jié)拍中斷。即用戶應(yīng)該在OSStart()運(yùn)行后,μC/OS-Ⅱ啟動運(yùn)行的第一個任務(wù)中初始化節(jié)拍中斷。,時鐘節(jié)拍ISR的原型程序,void OSTickISR(void){保存處理器寄存器; 調(diào)用OSIntEnter()或者直接將 OSIntNesting加1; 調(diào)用OSTimeTick(); 調(diào)用OSIntE
27、xit(); 恢復(fù)處理器寄存器; 執(zhí)行中斷返回指令; },這些代碼必須寫在匯編語言中,因?yàn)橛脩舨荒苤苯訌腃語言中訪問CPU寄存器。,OS_CPU_C.C文件,μC/OS-Ⅱ的移植實(shí)例要求用戶編寫六個簡單的C函數(shù):OSTaskStkInit()、OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OSTaskStatHook()、OSTimeTickHook()唯一必要
28、的函數(shù)是OSTaskStkInit(),其它五個函數(shù)必須得聲明但沒必要包含代碼。,OSTaskStkInit(),OSTaskCreate()和OSTaskCreateExt()通過調(diào)用OSTaskStkInit()來初始化任務(wù)的堆棧結(jié)構(gòu),因此,堆??雌饋砭拖駝偘l(fā)生過中斷并將所有的寄存器保存到堆棧中的情形一樣。,假定pdata會被編譯器保存到堆棧中,OSTaskStkInit()就會簡單的模仿編譯器的這種動作,將pdata保存到堆棧中(
29、1)。處理器至少得將程序計(jì)數(shù)器的值(中斷返回地址)和處理器的狀態(tài)字存入堆棧(2)。接著,用戶需要將剩下的處理器寄存器保存到堆棧中(3)。一旦用戶初始化了堆棧,OSTaskStkInit()就需要返回堆棧指針?biāo)傅牡刂?4)。,OSTaskCreateHook(),當(dāng)用OSTaskCreate()或OSTaskCreateExt()建立任務(wù)的時候就會調(diào)用OSTaskCreateHook(),該函數(shù)允許用戶或使用用戶的移植實(shí)例的用戶擴(kuò)
30、展μC/OS-Ⅱ的功能。當(dāng)μC/OS-Ⅱ設(shè)置完了自己的內(nèi)部結(jié)構(gòu)后,會在調(diào)用任務(wù)調(diào)度程序之前調(diào)用OSTaskCreateHook()。該函數(shù)被調(diào)用的時候中斷是禁止的,因此用戶應(yīng)盡量減少該函數(shù)中的代碼以縮短中斷的響應(yīng)時間。,OSTaskDelHook(),當(dāng)任務(wù)被刪除的時候就會調(diào)用OSTaskDelHook()。該函數(shù)在把任務(wù)從μC/OS-Ⅱ的內(nèi)部任務(wù)鏈表中解開之前被調(diào)用。當(dāng)OSTaskDelHook()被調(diào)用的時候,它會收到指向正被刪
31、除任務(wù)的OS_TCB的指針,這樣它就可以訪問所有的結(jié)構(gòu)成員了。,OSTaskSwHook(),當(dāng)發(fā)生任務(wù)切換的時候調(diào)用OSTaskSwHook()。不管任務(wù)切換是通過OSCtxSw()還是OSIntCtxSw()來執(zhí)行的都會調(diào)用該函數(shù)。OSTaskSwHook()可以直接訪問OSTCBCur 和OSTCBHighRdy,因?yàn)樗鼈兪侨肿兞?。OSTCBCur指向被切換出去的任務(wù)的OS_TCB,而OSTCBHighRdy指向新任務(wù)的OS_
32、TCB。注意在調(diào)用OSTaskSwHook()期間中斷一直是被禁止的。因?yàn)榇a的多少會影響到中斷的響應(yīng)時間,所以用戶應(yīng)盡量使代碼簡化。,OSTaskStatHook(),OSTaskStatHook()每秒鐘都會被OSTaskStat()調(diào)用一次。用戶可以用OSTaskStatHook()來擴(kuò)展統(tǒng)計(jì)功能。例如,用戶可以保持并顯示每個任務(wù)的執(zhí)行時間,每個任務(wù)所用的CPU份額,以及每個任務(wù)執(zhí)行的頻率等等。,OSTimeTickHook(
33、),OSTaskTimeHook()在每個時鐘節(jié)拍都會被OSTaskTick()調(diào)用。實(shí)際上,OSTaskTimeHook()是在節(jié)拍被μC/OS-Ⅱ真正處理,并通知用戶的移植實(shí)例或應(yīng)用程序之前被調(diào)用的。,OSTaskCreateHook(),void OSTaskCreateHook(OS_TCB *ptcb),,OSTaskDelHook(),void OSTaskDelHook(OS_TCB *ptcb),,OSTaskSwHo
溫馨提示
- 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- LwIP在μCOS-Ⅱ平臺上的移植與應(yīng)用.pdf
- 基于arm9的μcos-ⅱ嵌入式系統(tǒng)移植
- dsp數(shù)字信號處理課程設(shè)計(jì)報告--- µcos-ⅱ移植實(shí)驗(yàn)
- μCOS-Ⅱ操作系統(tǒng)內(nèi)核研究及其工程應(yīng)用.pdf
- 基于μCos-Ⅱ的水聲通信調(diào)制系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn).pdf
- 基于USB接口和μCOS-Ⅱ的數(shù)據(jù)采集系統(tǒng)設(shè)計(jì).pdf
- 基于μCOS-Ⅱ的微機(jī)保護(hù)裝置的設(shè)計(jì)與實(shí)現(xiàn).pdf
- 嵌入式實(shí)時操作系統(tǒng)μCOS-Ⅱ的研究與應(yīng)用.pdf
- 基于μCOS-Ⅲ的整車式動態(tài)稱重儀表的研究與設(shè)計(jì).pdf
- 基于μCOS-Ⅱ的嵌入式微機(jī)保護(hù)裝置的研究.pdf
- 基于ARM和μCOS-Ⅱ的功率控制系統(tǒng)軟件開發(fā).pdf
- CoS-,2-材料的制備、表征及電化學(xué)性能研究.pdf
- 基于μCOS-Ⅱ和ARM微控制器的下棋機(jī)器人設(shè)計(jì).pdf
- 基于ARM和μCOS-Ⅱ的電力參數(shù)實(shí)時監(jiān)測系統(tǒng)的研究和設(shè)計(jì).pdf
- 基于ARM和μCOS-Ⅱ的工業(yè)繡花機(jī)控制器的設(shè)計(jì)與實(shí)現(xiàn).pdf
- 水熱溶劑熱法制備CoS-,2-、NiS-,2-粉體的研究.pdf
- 移植cos-ii中英文翻譯資料
- 基于ARM和μCOS-Ⅱ的半導(dǎo)體制冷器溫度控制系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn).pdf
- μcos-ii操作系統(tǒng)基礎(chǔ)及其移植開發(fā)初步
- 嵌入式操作系統(tǒng)μCOS的移植與測試.pdf
評論
0/150
提交評論