uC/OS應用的簡(jiǎn)單剖析
一.uC/OS-II的移植
本文引用地址:http://dyxdggzs.com/article/149125.htm移植uC/OS對目標處理器有一定要求,這個(gè)可以參照
整個(gè)嵌入式系統分為兩大層:硬件層和軟件層.這里主要研究軟件層的架構.
軟件層主要分為四個(gè)部分:實(shí)時(shí)操作系統內核,與處理器相關(guān)部分,與應用相關(guān)部分,用戶(hù)的應用系統.
l實(shí)時(shí)操作系統內核
實(shí)時(shí)操作系統對系統資源進(jìn)行管理。主要包括任務(wù)分配和調度、系統時(shí)鐘服務(wù)、內存管理、消息機制、異常處理等等。uC/OS所有系統服務(wù)均由內核提供。內核將應用系統和底層硬件結合成一個(gè)完整的實(shí)時(shí)系統。
移植的時(shí)候內核是不變的,開(kāi)發(fā)者根據自己應用系統的需要來(lái)選擇實(shí)時(shí)操作系統內核,開(kāi)發(fā)者不能對內核隨意訪(fǎng)問(wèn),只能使用內核提供的功能服務(wù)來(lái)開(kāi)發(fā)自己的應用系統。內核確定,那么所提供的系統管理能力,系統服務(wù)也就得到了限定。開(kāi)發(fā)者只能在規定的范圍內對系統作些改動(dòng).
2與處理器相關(guān)的代碼
這是移植中最關(guān)鍵的部分.內核將應用系統和底層硬件有機的結合成一個(gè)實(shí)時(shí)系統,要使同一個(gè)內核能適用于不同的硬件體系,就需要在內核和硬件之間有一個(gè)中間層,這就是與處理器相關(guān)的代碼.處理器不同,這部分代碼也不同.
我們在移植時(shí)需要自己處理這部分代碼,可以自己編寫(xiě),也可以直接使用已經(jīng)成功移植的代碼.
在uC/OS中這一部分代碼分成三個(gè)文件:OS_CPU.H,OS_CPU_A.ASM,OS_CPU_C.C
1)OS_CPU.H
包括了用#define定義的與處理器相關(guān)的常量,宏和類(lèi)型定義.
具體來(lái)講有系統數據類(lèi)型定義,棧增長(cháng)方向定義,關(guān)中斷和開(kāi)中斷定義,系統軟中斷的定義等等.
2)OS_CPU_A.ASM
這部分需要對處理器的寄存器進(jìn)行操作,所以必須用匯編語(yǔ)言來(lái)編寫(xiě).包括四個(gè)子函數:OSStartHighRdy(),OSCtxSw(),OSIntCtxSw(),OSTickISR().
OSStartHighRdy()在多任務(wù)系統啟動(dòng)函數OSStart()中調用.完成的功能是:設置系統運行標志位OSRunning=
TRUE;將就緒表中最高優(yōu)先級任務(wù)的棧指針Load到SP中,并強制中斷返回.這樣就緒的最高優(yōu)先級任務(wù)就如同從中斷里返回到運行態(tài)一樣,使得整個(gè)系統得以運轉.
OSCtxSw()在任務(wù)級任務(wù)切換函數中調用的.任務(wù)級切換是通過(guò)SWI或者TRAP人為制造的中斷來(lái)實(shí)現的.ISR的向量地址必須指向OSCtxSw().這一中斷完成的功能:保存任務(wù)的環(huán)境變量(主要是寄存器的值,通過(guò)入棧來(lái)實(shí)現),將當前SP存入任務(wù)TCB中,載入就緒最高優(yōu)先級任務(wù)的SP,恢復就緒最高優(yōu)先級任務(wù)的環(huán)境變量,中斷返回.這樣就完成了任務(wù)級的切換.
OSIntCtxSw()在退出中斷服務(wù)函數OSIntExit()中調用,實(shí)現中斷級任務(wù)切換.由于是在中斷里調用,所以處理器的寄存器入棧工作已經(jīng)做完,就不用作這部分工作了.具體完成的任務(wù):調整棧指針(因為調用函數會(huì )使任務(wù)棧結構與系統任務(wù)切換時(shí)堆棧標準結構不一致),保存當前任務(wù)SP,載入就緒最高優(yōu)先級任務(wù)的SP,恢復就緒最高優(yōu)先級任務(wù)的環(huán)境變量,中斷返回.這樣就完成了中斷級任務(wù)切換.
OSTickISR()系統時(shí)鐘節拍中斷服務(wù)函數,這是一個(gè)周期性中斷,為內核提供時(shí)鐘節拍.頻率越高系統負荷越重.其周期的大小決定了內核所能給應用系統提供的最小時(shí)間間隔服務(wù).一般只限于ms級(跟MCU有關(guān)),對于要求更加苛刻的任務(wù)需要用戶(hù)自己建立中斷來(lái)解決.該函數具體內容:保存寄存器(如果硬件自動(dòng)完成就可以省略),調用OSIntEnter(),調用OSTimeTick(),調用OSIntExit(),恢復寄存器,中斷返回.
3)OS_CPU_C.C
UC/OS中共定義了6個(gè)函數在該文件中.但是最重要的是OSTaskStkInit().其他都是對系統內核的擴展時(shí)用的.
OSTaskStkInit()是在用戶(hù)建立任務(wù)時(shí)系統內部自己調用的,對用戶(hù)任務(wù)的堆棧進(jìn)行初始化.使建立好的進(jìn)入就緒態(tài)任務(wù)的堆棧與系統發(fā)生中斷并且將環(huán)境變量保存完畢時(shí)的棧結構一致.這樣就可以用中斷返回指令使就緒的任務(wù)運行起來(lái).
具體的入棧方式要根據不同mcu而定.需要參考用戶(hù)使用的mcu說(shuō)明書(shū).同時(shí)還要考慮mcu的棧生成方式.這需要根據具體問(wèn)題來(lái)分析,在此不做過(guò)多論述.
3與應用相關(guān)的代碼
這一部分是用戶(hù)根據自己的應用系統來(lái)定制合適的內核服務(wù)功能.包括兩個(gè)文件:OS_CFG.H,INCLUDES.H.
OS_CFG.H來(lái)配置內核,用戶(hù)根據需要對內核進(jìn)行定制,留下需要的部分,去掉不需要的部分,設置系統的基本情況.比如系統可提供的最大任務(wù)數量,是否定制郵箱服務(wù),是否需要系統提供任務(wù)掛起功能,是否提供任務(wù)優(yōu)先級動(dòng)態(tài)改變功能等等.
INCLUDES.H系統頭文件,整個(gè)實(shí)時(shí)系統程序所需要的文件,包括了內核和用戶(hù)的頭文件.
4用戶(hù)應用系統
這是整個(gè)實(shí)時(shí)系統的最高層,用戶(hù)通過(guò)利用實(shí)時(shí)操作系統提供的服務(wù)來(lái)開(kāi)發(fā)自己的具體程序.
二.用戶(hù)應用系統編寫(xiě)的模式
kernel提供給用戶(hù)一些功能函數,使得用戶(hù)的系統建立更加方便,但是kernel內部不會(huì )處理用戶(hù)的工作,對于整個(gè)系統的具體應用工作還得需要用戶(hù)自己去考慮,如何利用好這些功能服務(wù)函數就成為一個(gè)比較重要的問(wèn)題.
1.main函數的結構
voidmain(void)
{
初始化系統的硬件;
OSInit();
任務(wù)的建立,消息機制的建立;
OSStart();
}
這里需要的是在OSStart()執行之前不得啟動(dòng)中斷,硬件系統還不能工作.必須先讓軟件系統進(jìn)入工作狀態(tài)后才行.
2.中斷的結構
ISR:
{
保存處理器寄存器的值;
調用OSIntEnter();
執行用戶(hù)的工作;
調用OSIntExit();
恢復處理器寄存器的值;
RTI;
}
用戶(hù)的中斷形式和以前一樣,沒(méi)有什么大的變化,僅僅是在原來(lái)用戶(hù)ISR的基礎上在固定的位置加了兩個(gè)函數:OSIntEnter(),
OSIntExit().
3.各個(gè)任務(wù)的結構
voidYourTask(void)
{
for(;;)
{
用戶(hù)代碼
調用的系統服務(wù)
}
}
在任務(wù)啟動(dòng)函數執行完后,系統會(huì )切換到最高優(yōu)先級的任務(wù)去執行,此時(shí),可以將系統硬件部分的啟動(dòng)放在該任務(wù)的最前邊,僅僅是啟動(dòng)時(shí)執行一次,主要是啟動(dòng)系統的節拍中斷,或者一些必須在多任務(wù)系統調度后才能初始化的部分,使系統的真正開(kāi)始工作,達到軟件硬件的基本同步.
VoidHighestPrioTask(void)
{
OSStartHardware();
For(;;)
{
用戶(hù)代碼
調用的系統服務(wù)
}
}
用戶(hù)可以按照這些格式去編寫(xiě)自己的任務(wù),建立自己的應用系統.
評論