新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 實(shí)時操作系統(tǒng)mC/OS-II在AT91上的移植

實(shí)時操作系統(tǒng)mC/OS-II在AT91上的移植

作者:■ 長沙湖南大學(xué)電氣與信息工程學(xué)院 陰光磊 彭楚武 梁昂 時間:2005-03-04 來源:電子設(shè)計應(yīng)用2005年第1期 收藏

摘    要:本文介紹了的工作原理,并以為例,重點(diǎn)討論了在基于ARM架構(gòu)的AT91系列中的。最后給出了結(jié)果。
關(guān)鍵詞:;

本文引用地址:http://butianyuan.cn/article/4557.htm

mC/OS-II內(nèi)核工作原理
實(shí)時嵌入式操作系統(tǒng)mC/OS-II內(nèi)核的工作原理如圖1所示。首先,在主程序中對操作系統(tǒng)進(jìn)行初始化,完成mC/OS-II所有變量和數(shù)據(jù)結(jié)構(gòu)的初始化,包括任務(wù)控制塊(TCB)初始化,TCB優(yōu)先級表初始化,TCB鏈表初始化,事件控制塊(ECB)鏈表初始化以及空閑任務(wù)的創(chuàng)建等。
然后,根據(jù)應(yīng)用程序的需要,用戶可以調(diào)用OSTaskCreate()函數(shù)創(chuàng)建多個任務(wù)(至少1個)。該函數(shù)為新任務(wù)建立任務(wù)堆棧(OSTaskStkInit())以及初始化任務(wù)控制塊TCB(OS_ TCBInit())。
最后,通過調(diào)用OSStart()啟動多任務(wù)調(diào)度。程序?qū)⑻骄途w表中優(yōu)先級最高的任務(wù)開始執(zhí)行。這里假設(shè)啟動多任務(wù)調(diào)度前創(chuàng)建了一個任務(wù)Task1()。
程序進(jìn)入Task1()后,首先初始化時鐘和啟動時鐘節(jié)拍源開始計時。此節(jié)拍源給系統(tǒng)提供周期性的時鐘中斷信號,實(shí)現(xiàn)延時和超時確認(rèn)。然后根據(jù)應(yīng)用程序要求,完成該任務(wù)的基本功能。最后,調(diào)用OSTimeDly(),將自己掛起,即從就緒表中刪除。直到等待延時時間到,才將該任務(wù)恢復(fù)到就緒表中,并等待調(diào)度器的調(diào)度。
OSTimeDly()將任務(wù)掛起的同時,為其做好延時記號,然后調(diào)用OS_Sched()進(jìn)行任務(wù)級的任務(wù)調(diào)度。若此時沒有任何任務(wù)進(jìn)入就緒態(tài),就切換到空閑任務(wù)。
當(dāng)時鐘中斷來臨時,系統(tǒng)進(jìn)入中斷服務(wù)程序OSTickISR()。系統(tǒng)把當(dāng)前正在執(zhí)行的任務(wù)掛起,保護(hù)現(xiàn)場,進(jìn)行中斷處理OSTimeTick(),判斷有無任務(wù)延時到期,若有,則使該任務(wù)進(jìn)入就緒態(tài)。最后調(diào)用OSIntExit()進(jìn)行中斷級的任務(wù)調(diào)度,從而切換到優(yōu)先級最高的任務(wù),若沒有別的任務(wù)進(jìn)入就緒態(tài),則恢復(fù)現(xiàn)場繼續(xù)執(zhí)行原任務(wù)。

簡介
AT91FR40162是ATMEL公司出品的一款基于ARM7TDMI內(nèi)核的AT91 16/32位微控制器,其核心為高性能的32位RISC體系結(jié)構(gòu),并具有高密度的16位指令集和極低的功耗。
ARM處理器共有7種運(yùn)行模式,處理器模式可以通過軟件控制進(jìn)行切換,也可以通過外部中斷或異常處理過程進(jìn)行切換。在每一種處理器模式中有一組相應(yīng)的寄存器組。任意時刻(也就是任意的處理器模式下),可見的寄存器包括15個通用寄存器(R0~R14)、一個或兩個狀態(tài)寄存器及程序計數(shù)器(PC)。
CPSR(當(dāng)前程序狀態(tài)寄存器)可以在任何處理器模式下被訪問。它包含了條件標(biāo)志位、中斷禁止位、當(dāng)前處理器模式標(biāo)志以及其他的一些控制和狀態(tài)位。每一種處理器模式下都有一個專用的物理狀態(tài)寄存器,稱為SPSR(備份程序狀態(tài)寄存器)。當(dāng)特定的異常中斷發(fā)生時,這個寄存器用于存放CPSR的內(nèi)容。在異常中斷程序退出時,可以用SPSR中保存的值來恢復(fù)CPSR。

mC/OS-II在
AT91FR40162上的移植
本文使用的內(nèi)核是mC/OS-II v2.76,選用ADS1.2中的C編譯器。
整個移植過程主要分為兩個方面:與應(yīng)用相關(guān)的mC/OS-II配置(OS_CFG.H,INCLUDES.H);與處理器相關(guān)的mC/OS-II移植(OS_CPU.H,OS_CPU_A.ASM,OS_CPU_C.C)。
OS_CPU.H
此文件中主要是定義了一些與處理器相關(guān)的常數(shù)、宏以及類型。根據(jù)ADS1.2的編譯手冊,char型變量為8位,short型為16位,int型為32位,堆棧為32位寬。另外,v2.76版本中新增加了一個全局變量OSIntCtxSwFlag,如果需要中斷級的任務(wù)切換時,就令OSIntCtxSwFlag=TRUE。
OS_CPU_C.C
在這里需要編寫兩個函數(shù):OSInitHookBegin()和OSTaskStkInit()。
OSInitHookBegin()在OSInit()中調(diào)用,用來初始化移植中出現(xiàn)的特殊變量。這里將OSIntCtxSwFlag初始化為0。
OSTaskStkInit()在OSTaskCreate()和OSTaskCreateExt()中調(diào)用,用來初始化任務(wù)的棧結(jié)構(gòu)。圖2顯示了初始化后任務(wù)棧的結(jié)構(gòu)。堆棧從上往下遞減。mC/OS-II規(guī)定任務(wù)工作在SVC模式下。另外,根據(jù)ATPCS規(guī)定,子程序間通過R0~R3傳遞參數(shù),所以參數(shù)p_arg放在R0里。
與以往的版本不同,這里OSIntCtxSw()(由OSIntExit()調(diào)用)并不完成任務(wù)的切換工作,僅將OSIntCtxSwFlag變量置1,標(biāo)志需要進(jìn)行任務(wù)切換。當(dāng)OSIntExit()調(diào)用返回到ISR時,檢查OSIntCtxSwFlag變量,如果為1,則跳到OS_IntCtxSw()函數(shù)執(zhí)行任務(wù)切換。
OS_CPU_A.S
由于C語言不能對寄存器進(jìn)行直接操作,所以必須用匯編語言編寫以下函數(shù)。
OSStartHighRdy()由OSStart()調(diào)用。該函數(shù)使就緒態(tài)任務(wù)中優(yōu)先級最高的任務(wù)開始運(yùn)行。注意開始要將IRQ和FIQ中斷禁止,最后從堆棧彈出所有寄存器時,必須按照OSTaskStkInit()中相反的順序彈出。
OSCtxSw()由OSSched()調(diào)用,完成任務(wù)級的任務(wù)切換。任務(wù)級的任務(wù)切換包括將當(dāng)前任務(wù)在SVC模式下的寄存器壓入任務(wù)棧中,并且將新任務(wù)的堆棧彈出到SVC模式下的寄存器中。注意必須按照OSTaskStkInit()中任務(wù)棧的結(jié)構(gòu)對任務(wù)棧進(jìn)行操作。
OS_CPU_SR_Save()用于關(guān)中斷,OS_CPU_SR_Restore()用于開中斷。OS_CPU_SR_Save()將CPSR保存到R0中,通過將CPSR中I位和F位置1來禁止IRQ和FIQ中斷。OS_CPU_SR_Restore()只需將R0中保存的CPSR恢復(fù)即可。
OS_IntCtxSw()完成中斷級的任務(wù)切換。當(dāng)檢查OSIntCtxSwFlag變量為1時,就調(diào)用該函數(shù)。因為OS_IntCtxSw()是在ISR中被調(diào)用的,所以所有的處理器寄存器都已經(jīng)被正確地保存到了被中斷任務(wù)的堆棧中。
mC/OS-II 要求用戶提供一個周期性的時鐘源,來實(shí)現(xiàn)時間的延遲和超時功能。這里時鐘節(jié)拍設(shè)為100次每秒,使用定時器0來完成該任務(wù)。時鐘節(jié)拍中斷OSTickISR()代碼如下,此時系統(tǒng)進(jìn)入IRQ模式。
STMFD  SP!, {R0-R3, R12, LR}
BL      OSIntEnter       
BL      Tmr_TickISR_Handler
BL      OSIntExit       
LDR     R0,addr_OSIntCtxSwFlag
LDR     R1, [R0]
CMP     R1, #1
BEQ     OS_IntCtxSw    
LDMFD SP!, {R0-R3,R12,LR} 
SUBS    PC, LR, #4    
Tmr_TickISR_Handler是中斷處理程序,用C語言編寫。如果是其他類型的中斷,可以替換為相應(yīng)的中斷處理程序。這里定時器0中斷處理程序要做的工作是首先清中斷源,即讀取TC_SR寄存器值,AIC_ICCR=0x00000010,然后告訴處理器中斷結(jié)束(向AIC_EOICR寫數(shù)據(jù)),最后調(diào)用OSTimeTick()函數(shù),對延時記號進(jìn)行處理。
定時器0的設(shè)置為:WAVE模式;TC_CMR中CPCTRG=1,表示RC比較將復(fù)位計數(shù)器并開啟時鐘;TC_RC=計時時間;TC_IER=AT91C_TC_CPCS,允許RC比較中斷。

移植中要注意的問題
由于各方面的原因,移植中編寫的代碼不一定完全正確,需要進(jìn)行逐步調(diào)試。調(diào)試過程中,要善于根據(jù)具體現(xiàn)象來發(fā)現(xiàn)問題所在。根據(jù)筆者的調(diào)試經(jīng)歷,總結(jié)了一些移植調(diào)試過程中要注意的問題。
(1) 對mC/OS-II的內(nèi)核機(jī)理要有充分理解??梢試L試對其內(nèi)核進(jìn)行調(diào)試,這樣可以幫助自己從更深的層次來理解。只有對mC/OS-II的內(nèi)核有了清楚地認(rèn)識,才能在移植過程中發(fā)現(xiàn)問題的本質(zhì)。
(2) 對所使用的編譯器要有深刻細(xì)致的了解。由于ADS1.2的C 編譯器有很多優(yōu)化編譯選項和流水處理選項,在處理內(nèi)核編譯時很容易有沖突,所以,選擇優(yōu)化選項要慎重。加強(qiáng)對ADS1.2的C 編譯器的理解,可以節(jié)約代碼編寫時間。
(3) 在移植過程中,最容易出問題的就是堆棧處理。堆棧處理是操作系統(tǒng)移植的關(guān)鍵部分。先分析ARM系統(tǒng)自身在進(jìn)行現(xiàn)場保護(hù)時的堆棧處理的操作,然后模擬其過程。關(guān)鍵是要將需要的寄存器都保護(hù)到。由于我們在進(jìn)行任務(wù)切換的時候采用了系統(tǒng)函數(shù)來進(jìn)行現(xiàn)場保護(hù),因此在堆棧初始化的時候,就應(yīng)該按照這兩個函數(shù)的操作來對任務(wù)堆棧進(jìn)行初始化。
(4) 要詳細(xì)分析ARM系統(tǒng)自身處理中斷時的壓棧操作,必須將多余的信息從堆棧中清理干凈。如果對編譯器不熟悉,可以通過仔細(xì)調(diào)試中斷,來確定編譯器的具體操作。在對AT91FR40162的移植中,由于ARM處理器有7種運(yùn)行模式,每種運(yùn)行模式下都有自己獨(dú)立的寄存器,所以在處理中斷的過程中,要注意運(yùn)行模式的切換,避免寄存器的內(nèi)容無法正確保存和恢復(fù)。
(5) 注意程序的返回地址。異常中斷發(fā)生時,程序計數(shù)器PC所指的位置對各種不同的異常中斷是不同的,所以,返回地址也是不同的。需要根據(jù)不同的中斷類型,確定不同的中斷返回地址偏移量,否則程序?qū)⑴茱w。

結(jié)語
本方案經(jīng)過測試已證明移植成功。本文是以AT91FR40162為例,說明mC/OS-II的移植,對于ARM系列的處理器,只需稍加改動就可以實(shí)現(xiàn)?!?/p>

參考文獻(xiàn)
1 邵貝貝等譯. 嵌入式實(shí)時操作系統(tǒng)mC/OS-II(第2版). 北京:北京航空航天大學(xué)出版社,2003



評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉