999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于X86 體系μCOS-II 在VC6.0 下的移植

2011-07-20 09:40:34段玉波吳光敏
微處理機(jī) 2011年5期

段玉波,吳光敏

(昆明理工大學(xué)理學(xué)院,昆明 650093)

1 移植需要解決的主要問(wèn)題

移植主要解決三個(gè)問(wèn)題,時(shí)鐘獲得、中斷處理和任務(wù)切換。這里僅分析這幾個(gè)問(wèn)題的解決思路,后面第三部分將詳細(xì)講述其實(shí)現(xiàn)過(guò)程。

在PC 中,時(shí)鐘節(jié)拍由硬件定時(shí)器產(chǎn)生,硬件定時(shí)器會(huì)周期性中斷CPU。PC 機(jī)時(shí)鐘節(jié)拍的中斷向量為0x08,μCOS- II 將此向量截取,使之指向μCOS-II的時(shí)鐘節(jié)拍中斷服務(wù)子程序OSTickISR(),而原先的中斷向量保存在中斷向量0x81 中。然而,在基于控制臺(tái)的windows 保護(hù)模式下不能像DOS 下面那么容易,直接通過(guò)一個(gè)函數(shù)調(diào)用就能夠修改中斷。windows 下要修改中斷涉及到驅(qū)動(dòng)程序,這樣就加大了移植的困難度與復(fù)雜度。因此,考慮到本移植只是為了教學(xué)和學(xué)習(xí),并沒(méi)有應(yīng)用到對(duì)實(shí)時(shí)性要求高的產(chǎn)品,所以最終決定采用windows下的軟件定時(shí)器來(lái)模擬時(shí)鐘中斷。

時(shí)鐘中斷處理子程序。通過(guò)軟件定時(shí)器來(lái)模擬產(chǎn)生μC/OS-II的時(shí)鐘中斷,但timeSetEvent()函數(shù)調(diào)用定時(shí)回調(diào)函數(shù)是和主線程同時(shí)被windows 操作系統(tǒng)調(diào)度的,并沒(méi)有起到中斷的作用。所以在調(diào)用定時(shí)回調(diào)函數(shù)的時(shí)候必須停止主線程的運(yùn)行,退出回調(diào)函數(shù)則恢復(fù)主線程的運(yùn)行。這些事情可以都放在定時(shí)回調(diào)函數(shù),也就是μC/OS-II的時(shí)鐘中斷處理函數(shù)中完成。Windows 下要掛起一個(gè)線程的運(yùn)行,首先要得到這個(gè)線程的句柄,然后調(diào)用Suspend-Thread(hangdler)和ResumeThread(handler)就可以掛起和繼續(xù)執(zhí)行線程。

任務(wù)的切換。任務(wù)切換就是進(jìn)行任務(wù)的上下文切換,研究選擇了不帶浮點(diǎn)運(yùn)算的上下文切換進(jìn)行分析,任務(wù)的上下文和μCOS-II 在80x86 上移植的上下文很相近,不同點(diǎn)是段寄存器不用保存,因?yàn)閂C 下任務(wù)的切換是在同一個(gè)線程完成的,而保護(hù)模式下段寄存器的值在同一個(gè)線程下是不改變的。

2 Borland C/C++與VC++6.0 下編譯的主要區(qū)別

μCOS-II的作者使用了Borland C/C++編譯器,如今為便于學(xué)習(xí)要將其移植到VC ++6.0 編譯環(huán)境下,首先要說(shuō)明二者的一些區(qū)別,因?yàn)檫@直接關(guān)系到與CPU相關(guān)的那部分代碼的編寫。

采用Borland C/C ++ 編譯器編譯連接源文件后,μCOS-II 作為DOS 程序運(yùn)行于大存儲(chǔ)模式實(shí)模式下,而VC ++6.0 建立win32 工程文件編譯連接后,μCOS-II是在Windows 系統(tǒng)平臺(tái)上作為控制臺(tái)應(yīng)用程序運(yùn)行于保護(hù)模式下,二者主要區(qū)別如表1 所示。

表1 DOS 程序與控制臺(tái)程序比較表

Borland C/C++的庫(kù)文件與VC 使用的庫(kù)文件有很大差異,Borland C/C ++的一些宏也是VC ++6.0 所不支持的,因此需要做相應(yīng)的替換或屏蔽部分未使用代碼。

Borland C/C++編譯器對(duì)c 文件不支持匯編語(yǔ)言嵌套,而VC ++6.0 支持在c 程序中嵌套匯編代碼。基于此,工程中沒(méi)有單獨(dú)的匯編文件,而是將相關(guān)代碼放到OS_CPU_C.C 中。

3 具體移植步驟

3.1 建立和配置工程

創(chuàng)建工程:建立一個(gè)空的win32 控制臺(tái)應(yīng)用程序,在此工程內(nèi)創(chuàng)建相關(guān)目錄并將μCOS-II 文件添加到其中。

配置工程:將μCOS-II相關(guān)路徑添加到工程配置選項(xiàng)中;添加與軟件定時(shí)器有關(guān)的庫(kù)winmm.lib。

3.2 Includes.h

在原有基礎(chǔ)上增加兩個(gè)頭文件:

#include <windows.h >

#include <mmsystem.h >//包含時(shí)鐘函數(shù)的頭文件,需要windows.h的支持。

3.3 OS_CPU_C.C 文件的修改

3.3.1 OSTaskStkInit()

初始化任務(wù)堆棧。保護(hù)模式下程序是在同一個(gè)段址內(nèi)處理的,因此段址不用壓棧,為研究方便,也沒(méi)有把浮點(diǎn)寄存器壓棧。Windows 保護(hù)模式下堆棧以32 位字為單位進(jìn)行處理,因此數(shù)據(jù)類型由INT16U 改為INT32U,代碼如下:

程序清單L1 初始化任務(wù)堆棧

3.3.2 OSStartHighRdy()

從處于就緒態(tài)優(yōu)先級(jí)最高的任務(wù)的TCB 中取得堆棧地址并恢復(fù)到SP,恢復(fù)所有寄存器使優(yōu)先級(jí)最高的任務(wù)開(kāi)始運(yùn)行,該函數(shù)由OSStart()函數(shù)調(diào)用。代碼如下:

程序清單L2 啟動(dòng)最高優(yōu)先級(jí)任務(wù)

3.3.3 OSCtxSw()

任務(wù)級(jí)的任務(wù)切換函數(shù),其實(shí)是完成任務(wù)的上下文切換。由于VC++6.0 下任務(wù)是在一個(gè)線程中切換的,而且保護(hù)模式下段址寄存器在同一個(gè)線程下的值不變,因此不用保存段寄存器。任務(wù)切換時(shí)的壓棧情況如圖1 所示。

圖1 任務(wù)切換壓棧后狀態(tài)

程序清單L3 手動(dòng)任務(wù)切換

3.3.4 OSIntCtxSw()

中斷級(jí)任務(wù)切換函數(shù),由于控制臺(tái)程序不能處理中斷,所以此處用庫(kù)函數(shù)模擬中斷來(lái)實(shí)現(xiàn)時(shí)鐘節(jié)拍終端服務(wù)子程序,但其中并沒(méi)有保存相應(yīng)寄存器,因此需要在這里保存CPU 寄存器,這與μCOS-II原來(lái)的程序是不同的。在Test.c 中定義了一個(gè)主線程句柄HANDLE 和一個(gè)CONTEXT 保存主線程上下文。在進(jìn)行任務(wù)切換時(shí),首先保存相應(yīng)寄存器,然后把要運(yùn)行的的任務(wù)的上下文填入CONTEXT 結(jié)構(gòu)并保存,完成切換。代碼如下:

程序清單L4 中斷級(jí)任務(wù)切換函數(shù)

3.3.5 OSTickISR()

在調(diào)用timeSetEvent 后,被定時(shí)器線程被周期調(diào)用,其代碼如程序清單L5 所示。

3.4 OS_CPU_C.H 文件的修改

開(kāi)關(guān)中斷通過(guò)設(shè)置一個(gè)全局變量來(lái)解決,代碼如下:

3.5 Test.c 文件的修改

在main 函數(shù)的OSInit()前,加入了一個(gè)VCInit()函數(shù),主要初始化VC 環(huán)境,包括獲得主線程的句柄,設(shè)置上下文環(huán)境標(biāo)志位,特別要注意的是,句柄的獲得是要通過(guò)偽句柄轉(zhuǎn)換的,代碼如下所示:

3.6 隨機(jī)數(shù)的產(chǎn)生

random 函數(shù)不是ANSI C 標(biāo)準(zhǔn),不能在gcc,vc等編譯器下編譯通過(guò),可改用C ++下的rand 函數(shù)來(lái)實(shí)現(xiàn),它由C+ +標(biāo)準(zhǔn)函數(shù)庫(kù)提供。

具體實(shí)現(xiàn)方法是:首先用srand()來(lái)初始化隨機(jī)種子數(shù),rand 產(chǎn)生的隨機(jī)數(shù)是從0 到rand_max的,而rand_max是一個(gè)很大的數(shù),因此產(chǎn)生從X 到Y(jié)的數(shù):從X 到Y(jié) 有Y-X +1個(gè)數(shù),所以要產(chǎn)生從X 到Y(jié)的數(shù),只需要這樣寫:k=rand()%(Y-X +1)+X。

3.7 啟動(dòng)時(shí)鐘線程

多任務(wù)啟動(dòng)后,優(yōu)先級(jí)最高的任務(wù)TaskStart()首先運(yùn)行,該任務(wù)調(diào)用timeSetEvent()產(chǎn)生定時(shí)器線程,定時(shí)器線程就會(huì)按預(yù)定的時(shí)間周期調(diào)用μC/OS-II的時(shí)鐘節(jié)拍中斷服務(wù)子程序OSTickISR()。代碼如下:

3.8 任務(wù)堆棧分配

盡量為任務(wù)分配足夠大的堆棧空間,如果分配不夠,則可能導(dǎo)致調(diào)試或運(yùn)行時(shí)發(fā)生內(nèi)存溢出錯(cuò)誤。

4 結(jié)束語(yǔ)

通過(guò)以上分析進(jìn)行試驗(yàn),移植工作成功完成,運(yùn)行正常,且經(jīng)過(guò)單步跟蹤調(diào)試也沒(méi)有出現(xiàn)錯(cuò)誤。

雖然μCOS-II 在各種處理器上的移植項(xiàng)目不勝枚舉,但單純?cè)赩C ++6.0 下進(jìn)行該例程的移植還未見(jiàn)到。移植的過(guò)程可以使人進(jìn)一步了解與CPU相關(guān)部分程序的編寫以及弄懂μCOS-II時(shí)鐘調(diào)用的方法,為深入研究μCOS-II 及運(yùn)用到實(shí)際項(xiàng)目中打下基礎(chǔ)。

最后,希望移植后的例程能夠?yàn)棣藽OS- II 學(xué)習(xí)者提供一個(gè)新的學(xué)習(xí)環(huán)境,也為μCOS-II 課堂教學(xué)提供參考。

[1]Jean J Labrosse.嵌入式實(shí)時(shí)操作系統(tǒng)μC/OS-II[M].北京:北京航空航天大學(xué)出版社,2003.

[2]沈美明,溫東撣.IBM-PC 匯編語(yǔ)言程序設(shè)計(jì)[M].北京:清華大學(xué)出版社,1999.

[3]羅清平.基于X86 體系結(jié)構(gòu)的μCOSII 移植研究[D].成都:四川大學(xué),2008.

[4]Jean Louis Gareau.Porting μC/OS-II to the x86 Protected Mode[EB/OL].2001.http://theblog.tistory.com/71.

主站蜘蛛池模板: 国产一区亚洲一区| 呦女精品网站| 久久99精品久久久久久不卡| 一级毛片在线播放免费观看| 成年女人18毛片毛片免费| 蝴蝶伊人久久中文娱乐网| 国产精品香蕉| 免费看a级毛片| 精品国产免费人成在线观看| 青青热久麻豆精品视频在线观看| 美女啪啪无遮挡| 国产精品尤物铁牛tv| 91亚洲国产视频| 亚洲精品不卡午夜精品| 成人午夜福利视频| 中文字幕资源站| 久久人人妻人人爽人人卡片av| 老司机久久99久久精品播放| 五月丁香在线视频| 国产无遮挡猛进猛出免费软件| 人妻出轨无码中文一区二区| 日韩欧美高清视频| 国产成人艳妇AA视频在线| 亚洲精品va| 日本午夜在线视频| 日本三级黄在线观看| 欧美成人看片一区二区三区 | 麻豆精品在线| 亚洲欧美一区在线| 亚洲区欧美区| 911亚洲精品| 91区国产福利在线观看午夜| 亚洲天天更新| 久久精品嫩草研究院| 久久国产乱子| 久久黄色小视频| 天天综合亚洲| 欧美啪啪视频免码| 91青青在线视频| 狠狠色综合久久狠狠色综合| 国产精品无码影视久久久久久久| 久久成人18免费| 中日韩一区二区三区中文免费视频| 在线国产91| 国产三级a| 国产欧美另类| 亚洲午夜天堂| 国产黄在线观看| 亚洲女同欧美在线| 欧美狠狠干| 欧美午夜网| 91精品视频在线播放| 午夜视频免费一区二区在线看| 成人看片欧美一区二区| 亚洲av无码片一区二区三区| 国产精品99一区不卡| 丝袜亚洲综合| 国产素人在线| 亚洲免费福利视频| 欧美日韩第三页| 在线欧美日韩| 国产精品专区第一页在线观看| 伊人成人在线| 久久精品只有这里有| 欧美亚洲国产一区| 国模视频一区二区| 国产剧情国内精品原创| 国产一区成人| 波多野结衣亚洲一区| 99久久亚洲精品影院| 亚洲高清无码久久久| 日韩毛片在线播放| 亚洲高清无码久久久| 国产一区二区三区精品欧美日韩| a亚洲视频| 国产欧美视频在线观看| 亚洲成人精品久久| 亚洲欧洲免费视频| 国产成人亚洲精品蜜芽影院| 国产精品香蕉| 又黄又爽视频好爽视频| 国产制服丝袜91在线|