新聞中心

μC/OS-II在80x86上的移植

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

#defineUBYTEINT8U/*在uC/OS-II中并沒(méi)有實(shí)際的用處 */

#defineWORDINT16S

#defineUWORDINT16U

#defineLONGINT32S

#defineULONGINT32U

/*

*************************************************************************

******

*INTEL80x86(實(shí)模式, 大模式編譯)

*

*方法 #1: 用簡(jiǎn)單指令開(kāi)關(guān)中斷。

* 注意,用方法1關(guān)閉中斷,從調(diào)用函數(shù)返回后中斷會(huì)重新打開(kāi)!

* 注意將文件OS_CPU_A.ASM中與OSIntCtxSw()相關(guān)的常量從10改到8。

*

* 方法 #2: 關(guān)中斷前保存中斷被關(guān)閉的狀態(tài).

* 注意將文件OS_CPU_A.ASM中與OSIntCtxSw()相關(guān)的常量從8改到10。

*

*

*

*************************************************************************

******

*/

#defineOS_CRITICAL_METHOD2

#ifOS_CRITICAL_METHOD==1

#defineOS_ENTER_CRITICAL()asmCLI/* 關(guān)閉中斷*/

#defineOS_EXIT_CRITICAL()asmSTI/* 打開(kāi)中斷*/

#endif

#ifOS_CRITICAL_METHOD==2

#defineOS_ENTER_CRITICAL()asm{PUSHF;CLI}/* 關(guān)閉中斷 */

#defineOS_EXIT_CRITICAL()asmPOPF/* 打開(kāi)中斷 */

#endif

/*

*************************************************************************

******

*INTEL80x86(實(shí)模式, 大模式編譯)

*************************************************************************

******

*/

#defineOS_STK_GROWTH1/* 堆棧由高地址向低地址增長(zhǎng) (3)*/

#defineuCOS0x80/* 中斷向量0x80用于任務(wù)切換 (4)*/

#defineOS_TASK_SW()asmINTuCOS(5)

/*

*************************************************************************

******

* 全局變量

*************************************************************************

******

*/

OS_CPU_EXTINT8UOSTickDOSCtr;/* 為調(diào)用DOS時(shí)鐘中斷而定義的計(jì)數(shù)器*/

(6)*/

9.03.01 數(shù)據(jù)類型

由于不同的處理器有不同的字長(zhǎng),μC/OS-II的移植需要重新定義一系列的數(shù)據(jù)結(jié)構(gòu)。使用

BorlandC/C++編譯器,整數(shù)(int)類型數(shù)據(jù)為16位,長(zhǎng)整形(long)為32位。為了讀者方便起見(jiàn),盡管μC/OS-II中沒(méi)有用到浮點(diǎn)類型的數(shù),在源代碼中筆者還是提供了浮點(diǎn)類型的定義。

由于在80x86實(shí)模式中堆棧都是按字進(jìn)行操作的,沒(méi)有字節(jié)操作,所以BorlandC/C++編譯器中堆棧數(shù)據(jù)類型OS_STK聲明為16位。所有的堆棧都必須用OS_STK聲明。

9.03.02 代碼臨界區(qū)

與其他實(shí)時(shí)系統(tǒng)一樣,μC/OS-II在進(jìn)入系統(tǒng)臨界代碼區(qū)之前要關(guān)閉中斷,等到退出臨界區(qū)后再打開(kāi)。從而保護(hù)核心數(shù)據(jù)不被多任務(wù)環(huán)境下的其他任務(wù)或中斷破壞。BorlandC/C++支持嵌入?yún)R編語(yǔ)句,所以加入關(guān)閉/打開(kāi)中斷的語(yǔ)句是很方便的。μC/OS-II定義了兩個(gè)宏用來(lái)關(guān)閉/打開(kāi)中斷:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。此處,筆者為用戶提供兩種開(kāi)關(guān)中斷的方法,如下所述的方法1和方法2。作為一種測(cè)試,本書(shū)采用了方法1。當(dāng)然,您可以自由決定采用那種方法。

方法1

第一種方法,也是最簡(jiǎn)單的方法,是直接將OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()定義為處理器的關(guān)閉(CLI)和打開(kāi)(STI)中斷指令。但這種方法有一個(gè)隱患,如果在關(guān)閉中斷后調(diào)用μC/OS-II函數(shù),當(dāng)函數(shù)返回后,中斷將被打開(kāi)!嚴(yán)格意義上的關(guān)閉中斷應(yīng)該是執(zhí)行OS_ENTER_CRITICAL()后中斷始終是關(guān)閉的, 方法1顯然不滿足要求。 但方法1的最大優(yōu)點(diǎn)是簡(jiǎn)單,執(zhí)行速度快(只有一條指令),在此類操作頻繁的時(shí)候更為突出。如果在任務(wù)中并不在意調(diào)用函數(shù)返回后是否被中斷,推薦用戶采用方法1。此時(shí)需要將OSIntCtxSw()中的常量由10改到8(見(jiàn)文件OS_CPU_A.ASM)。

方法2

執(zhí)行OS_ENTER_CRITICAL()的第二種方法是先將中斷關(guān)閉的狀態(tài)保存到堆棧中,然后關(guān)閉中斷。與之對(duì)應(yīng)的OS_EXIT_CRITICAL()的操作是從堆棧中恢復(fù)中斷狀態(tài)。采用此方法,不管用戶是在中斷關(guān)閉還是允許的情況下調(diào)用μC/OS-Ⅱ中的函數(shù),在調(diào)用過(guò)程中都不會(huì)改變中斷狀態(tài)。

如果用戶在中斷關(guān)閉的情況下調(diào)用μC/OS-Ⅱ函數(shù),其實(shí)是延長(zhǎng)了中斷響應(yīng)時(shí)間。雖然OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()可以保護(hù)代碼的臨界段。但如此用法要小心,特別

是在調(diào)用OSTimeDly()一類函數(shù)之前關(guān)閉了中斷。 此時(shí)任務(wù)將處于延時(shí)掛起狀態(tài), 等待時(shí)鐘中斷,但此時(shí)時(shí)鐘中斷是禁止的!則系統(tǒng)可能會(huì)崩潰。很明顯,所有的PEND調(diào)用都會(huì)涉及到這個(gè)問(wèn)題,必須十分小心。所以建議用戶調(diào)用μC/OS-Ⅱ的系統(tǒng)函數(shù)之前打開(kāi)中斷。

9.03.03 堆棧增長(zhǎng)方向

80x86處理器的堆棧是由高地址向低地址方向增長(zhǎng)的, 所以常量OS_STK_GROWTH必須設(shè)置為1

[程序清單L9.2(3)]。

9.03.04 OS_TASK_SW()

在 μC/OS-II中,就緒任務(wù)的堆棧初始化應(yīng)該模擬一次中斷發(fā)生后的樣子,堆棧中應(yīng)該按進(jìn)

棧次序設(shè)置好各個(gè)寄存器的內(nèi)容。OS_TASK_SW()函數(shù)模擬一次中斷過(guò)程,在中斷返回的時(shí)候進(jìn)

行任務(wù)切換。80x86提供了256個(gè)軟中斷源可供選用,中斷服務(wù)程序(ISR)(也稱為例外處理過(guò)

程)的入口點(diǎn)必須指向匯編函數(shù)OSCtxSw()(請(qǐng)參看文件OS_CPU_A.ASM)。

由于筆者是在PC機(jī)上測(cè)試代碼的,本章的代碼用到了中斷號(hào)128(0x80),因?yàn)榇酥袛嗵?hào)是提供給用戶使用的[程序清單L9.2(4)](PC和操作系統(tǒng)會(huì)占用一部分中斷資源—譯者注),類似的用戶可用中斷號(hào)還有0x4B到0x5B,0x5D到0x66,或者0x68到0x6F。如果用戶用的不是PC,而是其他嵌入式系統(tǒng),如80186處理器,用戶可能有更多的中斷資源可供選用。

9.03.05 時(shí)鐘節(jié)拍的發(fā)生頻率

實(shí)時(shí)系統(tǒng)中時(shí)鐘節(jié)拍的發(fā)生頻率應(yīng)該設(shè)置為10到100Hz。通常(但不是必須的)為了方便計(jì)算設(shè)為整數(shù)。不幸的是,在PC中,系統(tǒng)缺省的時(shí)鐘節(jié)拍頻率是18.20648Hz,這對(duì)于我們的計(jì)算和設(shè)置都不方便。本章中,筆者將更改PC的時(shí)鐘節(jié)拍頻率到200Hz(間隔5ms)。一方面200Hz近似18.20648Hz的11倍,可以經(jīng)過(guò)11次延時(shí)再調(diào)用DOS中斷;另一方面,在DOS中,有些操作要求時(shí)鐘間隔為54.93ms,我們?cè)O(shè)定的間隔5ms也可以滿足要求。如果您的PC機(jī)處理器是80386,時(shí)鐘節(jié)拍最快也只能到200Hz,而如果是PentiumII處理器,則達(dá)到200Hz以上沒(méi)有問(wèn)題。



關(guān)鍵詞:

評(píng)論


相關(guān)推薦

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

關(guān)閉