新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > μCOS-II在ARM Cortex-M3處理器上的移植

μCOS-II在ARM Cortex-M3處理器上的移植

作者: 時(shí)間:2010-09-29 來(lái)源:網(wǎng)絡(luò) 收藏

2. 1 OS_CPU.H
OS_CPU.H包含處理器需要的用#defines語(yǔ)句定義的、與處理嘉相關(guān)的常數(shù)、宏以及類(lèi)型。因?yàn)椴煌奶幚砥饔胁煌淖珠L(zhǎng),μC/OS-II的移植包括了一系列的數(shù)據(jù)類(lèi)型定義,以確保其可移植性。μC/OS-II內(nèi)核代碼不使用C語(yǔ)言中的short、int及l(fā)ong等數(shù)據(jù)類(lèi)型,因?yàn)樗鼈兪蔷幾g器相關(guān)的,是不可移植的。Cortex-M3是32位處理器,同時(shí)參照RVMDK編譯器文檔,對(duì)μC/OS-II內(nèi)核中的數(shù)據(jù)類(lèi)型作如下定義:

typedef unsigned int OS_STK;
typedef unsigned int OS_CPU_SR;
OS_STK定義的是32位寬的堆棧入口地址數(shù)據(jù)類(lèi)型,OS_CPU_SR定義的是32位寬的Cortex-M3處理器狀態(tài)寄存器數(shù)據(jù)類(lèi)型。
和所有的實(shí)時(shí)內(nèi)核一樣,μC/OS-II為了訪問(wèn)臨界區(qū)的代碼需要關(guān)閉中斷,訪問(wèn)完,重新使能中斷。為了增加可移植性,μC/OS-II定義了兩個(gè)宏分別關(guān)閉和使能中斷一OS_ENTER_CRITICAL()、OS_EXIT_CRITICAL()。μC/OS-II定義了三種關(guān)閉和使能中斷方法,只需要使用其中一個(gè)。多數(shù)情況下,推薦使用OS_CRITICAL_METHOD#3。
OS_CRITICAL_METHOD#3通過(guò)寫(xiě)一個(gè)保存CPU狀態(tài)寄存器在一個(gè)臨時(shí)變量里的函數(shù),實(shí)現(xiàn)OS_ENTER_CRITICAL()。OS_EXIT_CRITICAL()調(diào)用另一個(gè)函數(shù)從臨時(shí)變量恢復(fù)CPU狀態(tài)寄存器。
絕大多數(shù)微處理器和控制器的堆棧是從上往下遞減的,但是也有些處理器使用的是相反的方式。μC/OS-II對(duì)兩種都可以處理,只要配置常數(shù)OS_STK_GROWTH指定堆棧的方向就可以了。 Cortex-M3的堆棧增長(zhǎng)是從高內(nèi)存地址往低內(nèi)存地址,因此,OS_STK_GROWTH應(yīng)該設(shè)置為l。
2. 2 OS_CPU_C.C
移植μC/OS-Ⅱ要求編寫(xiě)10個(gè)簡(jiǎn)單的C語(yǔ)言函數(shù),但唯一必要的函數(shù)是OSTaskStkInit(),其他9個(gè)函數(shù)必須申明,但并不一定要包含任何代碼,允許用戶(hù)在必要時(shí)添加擴(kuò)展OS功能的代碼。
OSTaskCreate()和OSTaskCreateExt()通過(guò)調(diào)用OSTaskStklnit(),初始化任務(wù)堆棧。因此,堆棧看起來(lái)像中斷剛發(fā)生過(guò)一樣,所有寄存器都保存在堆棧中。多數(shù)CPU寄存器的初始值并不重要,但是為了方便調(diào)試和檢查堆棧,用寄存器序號(hào)去初始化它們。寄存器的順序是重要
的,應(yīng)該和 Cortex-M3在發(fā)生異常時(shí)的堆棧順序一樣。
2. 3 OS_CPU_A.ASM
移植μC/OS-II要求編寫(xiě)5個(gè)簡(jiǎn)單的匯編語(yǔ)言函數(shù)。
OS_CPU_SR_Save()
OS_CPU_SR_Restore()
OSStartHighRdy()
OSCtxSw()
OSIntCtxSw()
OS_CPU_SR_Save()按照OS_CRITICAL_METHOD#3的方式,首先保存中斷屏蔽寄存器,接著關(guān)閉中斷。這個(gè)函數(shù)被宏OS_ENTER_CRITICAL()調(diào)用。當(dāng)這個(gè)函數(shù)返回時(shí),RO包含關(guān)閉中斷前的中斷屏蔽寄存器的狀態(tài)。
OS_CPU_SR_Restore()恢復(fù)在調(diào)用OS_ENTER_CRITICAL()之前中斷屏蔽寄存器的原值。也就是說(shuō),若在調(diào)用OS_ENTER_CKJTICAL()之前中斷是關(guān)閉的,調(diào)用之后仍是關(guān)閉的。
OSStart()調(diào)用OSStartHighRdy()來(lái)運(yùn)行在調(diào)用OSStart()之前創(chuàng)建的最高優(yōu)先級(jí)任務(wù)。OSStart()設(shè)置OSTCBHighRdy指向最高優(yōu)先級(jí)任務(wù)的OS_TCB。
當(dāng)一個(gè)任務(wù)放棄對(duì)CPU的控制時(shí),OS_TASK_SW()宏被調(diào)用,實(shí)際最終調(diào)用的是OSCtxSw()函數(shù)。通常,OSCtxSw()應(yīng)該實(shí)現(xiàn)任務(wù)上下文切換,但是在 Cortex-M3中,所有的上下文切換由pendSV句柄來(lái)完成。OSCtxSw()僅僅觸發(fā)PendSV句柄,再返回到調(diào)用處。
ISR完成后,調(diào)用OSIntExit()查看是否有比中斷任務(wù)更重要的任務(wù)需要去執(zhí)行。若確實(shí)如此,OSIntExit()調(diào)用OSIntCtxSw()決定下一步將要運(yùn)行哪一個(gè)任務(wù)。然而,和OSCtxSw()一樣,僅僅觸發(fā)PendSV句柄,再返回到調(diào)用處。
限于篇幅,不詳細(xì)列出5個(gè)函數(shù)的源代碼。
2.4 PendSV句柄及系統(tǒng)滴答
PendSV句柄函數(shù)為μC/OS-Ⅱ?qū)崿F(xiàn)所有的上下文切換。這是ARM Cortex-M3推薦的上下文切換方法。這是因?yàn)锳RM Cortex-M3發(fā)生任何異常時(shí),自動(dòng)保存多個(gè)寄存器,異常返回時(shí)自動(dòng)恢復(fù)這些寄存器。PendSV僅僅需要保存R4-Rll和調(diào)整堆棧指針。不管是任務(wù)的初始化還是中斷或
異常引發(fā)的PendSV異常都是采用同樣的方法實(shí)現(xiàn)保存和恢復(fù)上下文。
μC/OS-Ⅱ要求用戶(hù)提供一個(gè)周期性的時(shí)鐘源來(lái)實(shí)現(xiàn)時(shí)間的延時(shí)和超時(shí)功能。Cortex-M3的系統(tǒng)滴答定時(shí)器是專(zhuān)門(mén)為RTOS設(shè)計(jì)的??梢栽贠SStart()運(yùn)行后,μC/OS-II啟動(dòng)運(yùn)行的第一個(gè)任務(wù)中調(diào)用OS_CPU_SysTickInit()初始化系統(tǒng)滴答定時(shí)器并使能中斷。
需要注意的是:在系統(tǒng)啟動(dòng)代碼中,初始化中斷向量時(shí),向量14和15應(yīng)放置PendSV和SysTick對(duì)應(yīng)的句柄。


關(guān)鍵詞: ARM

評(píng)論


相關(guān)推薦

技術(shù)專(zhuān)區(qū)

關(guān)閉