国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于Cortex-M3處理器的uC/OS-II移植方法的研究

2012-08-15 05:53王宜結(jié)
淮南師范學(xué)院學(xué)報 2012年5期
關(guān)鍵詞:堆棧指針調(diào)用

王宜結(jié)

(淮南師范學(xué)院 電氣信息工程學(xué)院,安徽 淮南 232038)

1 引言

隨著應(yīng)用系統(tǒng)復(fù)雜程度的不斷提高,程序編制也變得越來越難控制。解決復(fù)雜問題的最好辦法就把它分解成一個個相對簡單的問題,即一個個單獨的任務(wù),分而治之。UC/OS-II是一個實時多任務(wù)操作系統(tǒng),因其短小精悍又源代碼開放,在一些小型系統(tǒng)中得到了較廣泛的應(yīng)用。在MCU上加載uC/OS-II操作系統(tǒng),再對每個問題編寫相應(yīng)的任務(wù)代碼,就可以實現(xiàn)復(fù)雜的控制和應(yīng)用。

2 UC/OS-II簡介

uC/OS-II是基于優(yōu)先級的搶占式實時多任務(wù)操作系統(tǒng),最多可管理64個任務(wù),可固化,可剪裁,具體高穩(wěn)定性和可靠性。它包含了實時內(nèi)核、任務(wù)管理 、時間管理、任務(wù)間通信同步(信號量 ,郵箱,消息隊列)和內(nèi)存管理等功能。絕大部分代碼用C語言寫成,與硬件相關(guān)部分用匯編語言編寫,最鮮明的特點是源代碼是公開免費的,便于移植和維護。uC/OS-II是面向中小型嵌入式系統(tǒng)的,包含全部功能模塊的內(nèi)核大約為10KB,如果經(jīng)過裁減只保留核心代碼,則可壓縮到3KB左右。RAM的占用量與系統(tǒng)中的任務(wù)數(shù)及堆棧空間大小有關(guān),堆棧的大小取決于任務(wù)的局部變量、緩沖區(qū)大小及可能的中斷嵌套層數(shù)。應(yīng)用程序的時間精度由系統(tǒng)時鐘節(jié)拍決定,uC/OS-II需要用戶提供周期性的時鐘信號源,用于實現(xiàn)時間延時和確認超時,一般時鐘節(jié)拍在10到100Hz之間,因為uC/OS-II在每一個節(jié)拍都要檢查有沒有更高優(yōu)先級的就緒任務(wù)在等待執(zhí)行 ,若有 ,就要進行任務(wù)切換。所以時鐘節(jié)拍率越高,系統(tǒng)的額外負荷就越重。

3 uC/OS-II移植到Cortex-M3處理器的詳細過程

移植就是要修改與處理器有關(guān)部分的代碼,也就是要修改以下三個文件:OS_CPU.H、OS_CPU.C及OS_CPU_A.ASM。其中OS_CPU.H文件包括了用#define語句定義的與處理器相關(guān)的常數(shù)、宏以及數(shù)據(jù)類型。對于Cortex-M3,用于開中斷和關(guān)中斷的兩個宏可定義如下:

#define OS_ENTER_CRITICAL() {cpu_sr=OS_CPU_SR_Save();}

#define OS_EXIT_CRITICAL()

{OS_CPU_SR_Restore(cpu_sr);}

這兩個宏用匯編代碼實現(xiàn)如下:

OS_CPU_SR_Save;這個函數(shù)用于關(guān)中斷

MRS R0,PRIMASK

CPSID I;關(guān)閉除硬fault以處的全部可屏蔽中斷

BX LR;函數(shù)返回

OS_CPU_SR_Restore;這個函數(shù)用于開中斷

MSR PRIMASK,R0;回到關(guān)中斷之前的狀態(tài)

BX LR;函數(shù)返回

uC/OS-II用宏“OS_STK_GROWTH”來設(shè)置堆棧的增長方向,值為0時表示堆棧從低地址向高地址增長,值為1則相反。由于Cortex-M3內(nèi)核的堆棧是向下生長的滿棧,故應(yīng)把宏定義成“#define OS_STK_GROWTH 1”。定義數(shù)據(jù)類型宏比較簡單,這里就不介紹了。

在OS_CPU.C文件中要求我們必須編寫10個簡單的C函數(shù),它們是:

OSTaskStkInit();OSInitHookBegin();OSInitHook-End();OSTaskCreateHook();OSTaskDelHook();OSTask-IdleHook();OSTaskStatHook();OSTaskSwHook();OSTCBInitHook();OSTimeTickHook()。在這10個函數(shù)中唯一必要的是OsTaskStklnt()函數(shù)。其他9個函數(shù)是為了擴展用戶功能而定義的鉤子函數(shù),這些鉤子函數(shù)必須聲明,但可以都為空函數(shù),也可以加上一些用戶需要的擴展功能。OsTaskStklnt()被任務(wù)創(chuàng)建函數(shù)OSTaskCreate()或OSTaskCreateEXT()調(diào)用,用來初始化任務(wù)的堆棧,任務(wù)堆棧通常用數(shù)組來定義。OsTaskStklnt()函數(shù)首先將用戶為任務(wù)分配的堆棧棧底地址賦值給一個堆棧型指針變量,然后再通過這個堆棧指針向任務(wù)的??臻g寫入初值。初始化后任務(wù)堆棧圖1所示(堆??臻g大小為SIZE),其中task為要創(chuàng)建的任務(wù)代碼首地址,其他15個寄存器的值可為任意值,通常初始化為0。OsTaskStklnt()返回任務(wù)堆棧指針,這個指針在任務(wù)創(chuàng)建函數(shù)調(diào)用任務(wù)控制塊初始化函數(shù)OS_TCBInit()后存入任務(wù)控制塊中。

圖1 初始化后的堆棧

OS_CPU_A.ASM文件:在此文件中需改寫 4個簡單匯編語言函數(shù):OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OSTickISR()。

下面詳細分析這幾個函數(shù)的實現(xiàn)過程:

OSStartHighRdy():這個函數(shù)被 OSStart()調(diào)用,并且只執(zhí)行一次,它的主要功能是觸發(fā)PendSV異常,PendSV異常的核心工作是任務(wù)的切換,對Cortex-M3內(nèi)核,其代碼可以寫成:

PendSV_Handler

CPSID I;關(guān)中斷

MRS R0,PSP;當(dāng)前堆棧指針送給R0,首次運行任務(wù)時,PSP此前被置為0了。

CBZ R0,OSPendSV_nosave;首次運行任務(wù)時,不保存運行環(huán)境

SUBS R0,R0,#0x20;保存R4-R11到當(dāng)前任務(wù)的堆棧

STM R0,{R4-R11};R0為當(dāng)前任務(wù)的堆棧指針,要把它存到當(dāng)前任務(wù)控制塊中去

LDR R1,=OS_TCBCur;OSTCBCur-〉OSTCBStkPtr〈=當(dāng)前任務(wù)SP;

LDR R1,[R1];任務(wù)控制塊的第一個單元存放的是堆棧指針

STR R0,[R1];R0 isSP ofprocessbeing switched out;

至此,當(dāng)前任務(wù)的上下文都保存起來了OSPendSV_nosave

PUSH {R14};需要保護 LR exc_return值

LDR R0,__OS_TaskSwHook;調(diào) 用 OSTaskSwHook();

BLX R0

POP {R14}

LDR R0,__OS_PrioCur;OSPrioCur=OSPrio-HighRdy;

LDR R1,__OS_PrioHighRdy

LDRB R2,[R1]

STRB R2,[R0]

LDR R0,__OS_TCBCur;OSTCBCur =OSTCBHighRdy;

LDR R1,__OS_TCBHighRdy

LDR R2,[R1]

STR R2,[R0]

LDR R0,[R2];R0是新的進程堆棧指針SP:SP 〈=OSTCBHighRdy-〉OSTCBStkPtr;

LDM R0,{R4-R11};從待運行任務(wù)的堆棧中恢復(fù)R4-R11

ADDS R0,R0,#0x20

MSR PSP,R0;PSP〈=新的進程堆棧指針SP

ORR LR,LR,#0x04;確保異常返回后使用進程堆棧

CPSIE I;開中斷

BX LR;異常返回后將恢復(fù)待運行任務(wù)的上下文

當(dāng)主函數(shù)調(diào)用OS_START()首次運行多任務(wù)時,先查找優(yōu)先級最高的就緒任務(wù),然后調(diào)用OS-StartRdy()觸發(fā)PendSV異常(剛進入異常時,硬件自動保存8個寄存器,使用的是原來的堆棧指針),然后取中斷向量進入中斷服務(wù),再將堆棧指針切換為主堆棧指針MSP。PendSV異常服務(wù)程序中,首先判斷是不是第一次運行任務(wù),如果是,則不需要保存任務(wù)的運行環(huán)境(因為尚無任務(wù)在運行),而只要恢復(fù)待運行任務(wù)的運行環(huán)境,即把任務(wù)堆棧中的16個寄存器(如圖1)的值恢復(fù)到相應(yīng)的寄存器中(這時這個待運行任務(wù)的堆棧指針又指向棧底),這其中包含了待運行任務(wù)代碼的入口地址,它會被恢復(fù)到程序計數(shù)器PC中,PC得到待運行任務(wù)入口地址后就開始運行該任務(wù)。

當(dāng)前運行的任務(wù)可能調(diào)用void OSTimeDly(INT16U ticks)函數(shù)來主動延時,這個函數(shù)會使任務(wù)延時ticks個時鐘節(jié)拍,并通過調(diào)用OS_Sched();函數(shù)引發(fā)一次任務(wù)調(diào)度。通常把這種情況下的調(diào)度稱作任務(wù)級調(diào)度,另一種調(diào)度是在中斷返回時進行的,叫做中斷級調(diào)度。OS_Sched()函數(shù)的功能是先查找任務(wù)就緒表中優(yōu)先級最高的就緒任務(wù),然后調(diào)用OS_TASK_SW()函數(shù)(這個函數(shù)在os_cpu.h中用宏定義成:“#define OS_TASK_SW()OSCtxSw()”)觸發(fā)PendSV異常完成一次任務(wù)切換。PendSV異常從第二次被調(diào)用開始,就要先保存當(dāng)前正在運行任務(wù)的運行環(huán)境 (即壓入R4-R11共8個寄存器,另外8個寄存器(PSR,PC,LR,R12,R3-R0)在進入PendSV異常時由硬件自動壓入待切換任務(wù)的堆棧保護)。PendSV異常最后4行的功能是:把待運行任務(wù)的堆棧指針賦給進程堆棧指針PSP,然后調(diào)整LR的值,確保返回后使用進程堆棧。由于LR在出入ISR的時候,其值得到了重新的詮釋,這種特殊的值稱為“EXC_RETURN”,EXC_RETURN 的D0位對于Cortex-M3核必須為1(D0=1表示返回Thumb狀態(tài)),D1位保留,D2位非常重要:當(dāng)D2=0時,從主堆棧中做出棧操作,返回后使用MSP;當(dāng)D2=1時,從進程堆棧中做出棧操作,返回后使用進程堆棧。所以指令 “ORR LR,LR,#0x04”的功能就是控制從PendSV異常返回時,待運行任務(wù)保存在堆棧中的“PSR,PC,LR,R3-R0”這 8 個寄存器能正確地彈出到對應(yīng)的寄存器中,從而實現(xiàn)恢復(fù)現(xiàn)場的目的。EXC_RETURN的D3位的功能是控制返回后進入Handler模式(=0時)還是進入線程模式(=1時)。這里不修改此值是為了返回時仍然進入原來的模式,31:4位必須全為1。

OSIntCtxSw()函數(shù)是中斷級任務(wù)切換函數(shù),即在中斷返回時通過調(diào)用該函數(shù)觸發(fā)PendSV異常實現(xiàn)任務(wù)切換,功能與OSCtxSw()幾乎一樣。

OSTickISR()函數(shù)即節(jié)拍中斷服務(wù),其代碼如下:

{OS_CPU_SR cpu_sr;

OS_ENTER_CRITICAL();//保存全局中斷標志,關(guān)總中斷,通知uC/OS-II正在開始進行ISR服務(wù)

OSIntNesting++;//統(tǒng)計中斷嵌套次數(shù)

OS_EXIT_CRITICAL();//恢復(fù)全局中斷標志

OSTimeTick();/*在os_core.c文件里定義,主要判斷延時的任務(wù)是否計時到,或正在等待事件的任務(wù)是否超時。將到時或超時的任務(wù)由原來的掛起狀態(tài)置為就緒狀態(tài)*/

OSIntExit();/*在os_core.c文件里定義,如果有更高優(yōu)先級的任務(wù)就緒了,則執(zhí)行一次任務(wù)切換。*/}

4 結(jié)束語

本文詳細分析了uC/OS的移植過程。因為不同處理器字長、使用的開關(guān)中斷指令、堆棧組織方式、寄存器的數(shù)量、進出中斷時的具體行為不同,所以要針對具體使用的處理器來寫這部分代碼,這就是移植的本質(zhì)。本文著重分析了任務(wù)切換的詳細過程以及與之關(guān)聯(lián)的部分,這也是移植過程的難點所在。實踐表明,上述方法移植后的操作系統(tǒng)工作正常,能長時間穩(wěn)定運行。

[1]陳啟軍.嵌入式系統(tǒng)及其應(yīng)用[M].上海:同濟大學(xué)出版社,2011

[2][美]Jean J.Labrosse.嵌入式實時操作系統(tǒng)UC/OS-II(第2版)[M].邵貝貝等譯.北京:北京航空航天大學(xué)出版社,2003

猜你喜歡
堆棧指針調(diào)用
基于行為監(jiān)測的嵌入式操作系統(tǒng)堆棧溢出測試*
核電項目物項調(diào)用管理的應(yīng)用研究
LabWindows/CVI下基于ActiveX技術(shù)的Excel調(diào)用
為什么表的指針都按照順時針方向轉(zhuǎn)動
基于堆棧自編碼降維的武器裝備體系效能預(yù)測
基于系統(tǒng)調(diào)用的惡意軟件檢測技術(shù)研究
基于改進Hough變換和BP網(wǎng)絡(luò)的指針儀表識別
ARM Cortex—MO/MO+單片機的指針變量替換方法
利用RFC技術(shù)實現(xiàn)SAP系統(tǒng)接口通信
一種用于分析MCS-51目標碼堆棧深度的方法