• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      μC/OS-II的應(yīng)用設(shè)計(jì)

      2014-07-19 12:50:08
      科技視界 2014年14期
      關(guān)鍵詞:編譯器堆棧內(nèi)核

      凌 云

      (建東職業(yè)技術(shù)學(xué)院,江蘇 常州213022)

      0 引言

      在嵌入式系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)中,嵌入式實(shí)時(shí)操作系統(tǒng)得到了廣泛應(yīng)用,嵌入式實(shí)時(shí)操作系統(tǒng)為用戶提供了一個(gè)開(kāi)發(fā)環(huán)境,使用戶可以集中精力于特殊應(yīng)用的嵌入式軟件的設(shè)計(jì),簡(jiǎn)化了系統(tǒng)設(shè)計(jì),提高了開(kāi)發(fā)效率。

      μC/OS-II 是一個(gè)開(kāi)放源代碼的,精簡(jiǎn)的實(shí)時(shí)內(nèi)核。 它功能強(qiáng)大,提供了任務(wù)管理、進(jìn)程調(diào)度、任務(wù)間通信、內(nèi)存管理等功能。 更重要的是,μC/OS-II 自1992 年的第一版(μC/OS)以來(lái)已經(jīng)有好幾百個(gè)應(yīng)用,是一個(gè)經(jīng)實(shí)踐證明好用且穩(wěn)定可靠的內(nèi)核。 下面將介紹的是如何將μC/OS-II 移植到TI 公司高性能定點(diǎn)DSP TMS320LF2407 上。

      1 μC/OS-II 在TMS320LF2407 上的移植

      μC/OS-II 的移植條件是:只要該處理器有堆棧,有CPU 內(nèi)部寄存器入棧、出棧指令;使用的C 編譯器支持內(nèi)嵌匯編(inline assembly)或者該C 語(yǔ)言可擴(kuò)展,可連接匯編模塊,使得關(guān)中斷、開(kāi)中斷能在C 語(yǔ)言程序中實(shí)現(xiàn)。

      TMS320LF2407 是由美國(guó)德州儀器(TI)公司生成的高性能定點(diǎn)DSP[1]。 T1 公司提供的編譯器CodeComposer V4.10. 36 支 持C 語(yǔ) 言 和匯編語(yǔ)言開(kāi)發(fā),本文在此編譯器的基礎(chǔ)上進(jìn)行了μC/OS-II 的移植。CodeComposer V4.10. 36 內(nèi)置編譯器維持一個(gè)C 運(yùn)行環(huán)境, 為了確保C 語(yǔ)言的成功執(zhí)行,所有運(yùn)行時(shí)代碼都必須保持這個(gè)環(huán)境。 在編寫(xiě)匯編和C 代碼的接口函數(shù)時(shí)也必須遵循一些規(guī)則,μC/OS-II 才可以完全移植到TMS320LF2407 上。

      μC/OS-II 核心代碼很小,程序開(kāi)發(fā)人員要把它移植到自己的目標(biāo)板中只需做少量的工作。 μC/OS-II 大部分源代碼是用C 語(yǔ)言寫(xiě)的,但是完成和處理器一些相關(guān)的代碼時(shí), 還是必須要用匯編語(yǔ)言來(lái)實(shí)現(xiàn)的。寄存器的讀、寫(xiě)只能通過(guò)匯編語(yǔ)言的存儲(chǔ)和加載指令來(lái)實(shí)現(xiàn)。要使μC/OS-II 能夠正常工作,處理器必須滿足以下要求:①處理器的C 編譯器能產(chǎn)生可重入代碼;②用C 語(yǔ)言可以打開(kāi)和關(guān)閉中斷;③處理器支持中斷,并且能夠產(chǎn)生定時(shí)中斷(通常在10~100Hz 之間);④處理器能夠支持容納一定量數(shù)據(jù)的硬件堆棧;⑤處理器有將堆棧指針和其它寄存器讀出和存儲(chǔ)到堆?;騼?nèi)存中的指令。

      2 移植過(guò)程

      在移植之前,首先我們需要對(duì)μC/OS-II 的內(nèi)核,特別是任務(wù)切換機(jī)制要有一個(gè)比較深刻的理解, 而具體的移植工作主要是修改μC/OS-II 中與處理器相關(guān)的三個(gè)文件:OS_CPU_A.ASM、OS_CPU_C.C 以及OS_CPU.H, 此 外 還 需 要 修 改INCLUDES.H 文 件, 以 及 針 對(duì)TMS320LF2407 最多擴(kuò)展64K 程序存儲(chǔ)器的限制修改CFG.H 文件,裁減μC/OS-II,但后兩個(gè)文件改寫(xiě)較簡(jiǎn)單,這里不再贅說(shuō)。

      2.1 修改OS_CPU.H

      此文件的內(nèi)容可根據(jù)μC/OS-II 的內(nèi)容進(jìn)行修改, 這里僅給出關(guān)鍵內(nèi)容:

      unsigned int INT16U; /* 定義堆棧單位長(zhǎng)度*/

      unsigned int OS_STK;

      #define OS STK_GROWTH 0 /* 定義堆棧由低地址向高地址遞減*/

      #define OS_ENTER_CRITICAL() asm(” SECT INTM”); /* 開(kāi)關(guān)中斷宏定義*/

      #define 0S_EXTI_CRITICAL() asm(” CLRC INTM”);

      #define OS_TASI_SW() asm(” INTR 8”); /* 任務(wù)切換宏定義*/

      2.2 修改OS_CPU_C.C

      在這個(gè)文件中需要用戶定義6 個(gè)C 語(yǔ)言函數(shù):OSTaskStkInit(),OSTaskCreateHook(),OSTaskDelHook(),OSTaskSwHook(),OSTaskStatHook(),OSTimeTickHook(),實(shí)際必須修改的只有OSTaskStkInit()。

      OSTaskStkInit () 函數(shù)是由任務(wù)創(chuàng)建函數(shù)OSTaskCreate ()或OSTaskCreateExt()調(diào)用,功能是初始化任務(wù)堆棧。任務(wù)堆棧用于任務(wù)切換或中斷發(fā)生時(shí)保護(hù)當(dāng)前任務(wù)的上下文狀態(tài),以便中斷返回或者任務(wù)下次被調(diào)度運(yùn)行時(shí)能夠接著運(yùn)行。堆棧的結(jié)構(gòu)可以按照自己的需要而定制,考慮到CC2000 的C 語(yǔ)言運(yùn)行時(shí)支持庫(kù)rts2xx.lib 中已經(jīng)有用于保存中斷上下文的庫(kù)函數(shù)I$$SAVE 和I$$REST(可用Dspar 工具查看這一函數(shù)),為了重用這一庫(kù)函數(shù),這里按照這一庫(kù)函數(shù)堆棧結(jié)構(gòu)來(lái)設(shè)計(jì)堆棧,其結(jié)構(gòu)如下圖1 所示:

      一些說(shuō)明如下:

      (1)第一級(jí)硬件堆棧(HW STACK LEVEL 1)不需要保存,原因是I$$SAVE 是通過(guò)CALL 指令來(lái)調(diào)用,CALL 指令會(huì)使用一個(gè)硬件堆棧用于保存返回地址。所以在保存另外七個(gè)硬件堆棧前會(huì)將第一級(jí)硬件堆棧彈出。

      (2)當(dāng)調(diào)度再次發(fā)生時(shí),通過(guò)調(diào)用與I$$SAVE 對(duì)應(yīng)的I$$REST 來(lái)恢復(fù)被中斷的上下文。

      2.3 修改OS_CPU_ASM.ASM

      此文件包括的四個(gè)函數(shù)都跟處理器有關(guān),由于不同的處理器有不同的寄存器, 所以操作系統(tǒng)在這個(gè)文件里給用戶留下四個(gè)函數(shù)接口,以便用戶根據(jù)所選處理器編寫(xiě)相應(yīng)的匯編程序以完成固定的功能。四個(gè)函數(shù)分別是OSStartHighRdy(),OSCtxSw(),OSIntCtxSw(),OSTickISR()。

      2.3.1 OSStartHighRdy()

      該函數(shù)是由啟動(dòng)函數(shù)OSStart()調(diào)用的,功能是使系統(tǒng)能及時(shí)地運(yùn)行優(yōu)先級(jí)最高的就緒任務(wù),由于系統(tǒng)中數(shù)據(jù)指針OSTCBHighRdy 一直指向就緒任務(wù)中優(yōu)先級(jí)最高的任務(wù)控制塊OSTCB,使得OSStartHighRdy()輕易就可獲取最高優(yōu)先級(jí)任務(wù)的棧頂指針,再將保存在此任務(wù)堆棧的寄存器值恢復(fù)到CPU 寄存器中,使該任務(wù)得以運(yùn)行,實(shí)現(xiàn)多任務(wù)的啟動(dòng)。 對(duì)下TMS320LF2407 而言,OSStartHighRdy()代碼編寫(xiě)如下:

      _OSStartHighRdy:

      CALL _OSTaskSwHook;調(diào)用鉤子函數(shù),實(shí)現(xiàn)用戶自定義功能

      LACK 1; OSRunning = TRUE;

      LDPK _OSRunning

      SACL _OSRunning

      LDPK _OSTCBHighRdy; SP=OSTCBHighRdy->OSTCBStkPtr;

      LAR AR3, _OSTCBHighRdy

      MAR *, AR3

      LAR AR1, *

      B I$$REST, AR1; 上下文恢復(fù),任務(wù)返回在調(diào)用函數(shù)OSTaskSwHook()時(shí),由于當(dāng)前任務(wù)控制塊OSTCBCur仍然指向?qū)⒁磺袚Q出去的任務(wù),而OSTCBHighRdy 則指向即將被運(yùn)行的任務(wù),因此用戶可在OSTaskSwHook()中對(duì)它們操作,以實(shí)現(xiàn)特殊的功能,當(dāng)然該函數(shù)也可定義為不做任何事的空函數(shù)。 從程序我們可以看出,要運(yùn)行最高優(yōu)先級(jí)的任務(wù),首先得找到該任務(wù)堆棧指針,然后將寄存器內(nèi)容及參數(shù)從堆棧中恢復(fù)到CPU 的寄存器中。

      2.3.2 任務(wù)級(jí)上下文切換的實(shí)現(xiàn)函數(shù)OSCtxSw()

      前面曾提過(guò), 任務(wù)切換時(shí)使用了軟中斷, 并將中斷向量指向OSCtxSw(),因此該函數(shù)所要做的就是執(zhí)行任務(wù)級(jí)的任務(wù)切換。 其目的是為了保證CPU 永遠(yuǎn)運(yùn)行就緒表中優(yōu)先級(jí)最高的任務(wù)。 OSCtxSw()是任務(wù)調(diào)度函數(shù)OSSched()通過(guò)宏OS_TASK_SW()調(diào)用的,執(zhí)行的是多任務(wù)的調(diào)度功能:不僅要使高優(yōu)先級(jí)任務(wù)得以恢復(fù)運(yùn)行,還得將待切換出去的任務(wù)保存起來(lái),兩者的差別也可以從程序代碼中比較出來(lái):

      _OSCtxSw:

      CALL I$$SAVE

      LDPK _OSTCBCur; OSTCBCur->OSTCBStkPtr = SP;

      LAR AR3, _OSTCBCur

      MAR *, AR3

      SAR AR1, * , AR1_

      OSIntCtxSw:

      CALL _OSTaskSwHook;OSTaskSwHook();

      LDPK _OSTCBHighRdy;OSTCBCur = OSTCBHighRdy;

      BLDD _OSTCBHighRdy,#_OSTCBCur

      LDPK _OSPrioHighRdy;OSPrioCur = OSPrioHighRdy;

      BLDD _OSPrioHighRdy,#_OSPrioCur

      LDPK _OSTCBHighRdy;SP=OSTCBHighRdy->OSTCBStkPtr;

      LAR AR3, _OSTCBHighRdy

      MAR *, AR3

      LAR AR1, *

      B I$$REST, AR1

      顯然,對(duì)當(dāng)前任務(wù)相關(guān)內(nèi)容的保存、給當(dāng)前優(yōu)先級(jí)數(shù)據(jù)結(jié)構(gòu)賦值以及給當(dāng)前任務(wù)控制塊賦值都是OSStartHighRdy()所不具有的。

      2.3.3 時(shí)鐘中斷服務(wù)程序的實(shí)現(xiàn)

      OSTickISR()也是μC/OS -II 操作系統(tǒng)中要求用戶提供的匯編程序,其具體實(shí)現(xiàn)與中斷級(jí)上下文切換的實(shí)現(xiàn)有很大的關(guān)系, 它是時(shí)鐘中斷服務(wù)程序,主要調(diào)用函數(shù)OSTimeTick(),處理與系統(tǒng)時(shí)鐘相關(guān)的工作, 如將每個(gè)任務(wù)的等待時(shí)間減1、更新系統(tǒng)時(shí)間。 OSTickISR()具體代碼如下所示:

      _OSTickISR:

      CALL I$$SAVE

      CALL _OSIntEnter

      LAC _OSIntNesting; 保 存 堆 棧 指 針AR1 到 當(dāng) 前OSTCB 的

      OSTCBStkPtr;

      SUBK 1 BNZ L1

      LDPK _OSTCBCur

      LAR AR3, _OSTCBCur

      MAR *, AR3

      SAR AR1, * , AR1

      L1: CALL _OSTimeTick

      CALL _OSIntExit

      BI$$REST,AR1

      其中OSTimeTick()函數(shù)定時(shí)對(duì)所有的任務(wù)控制塊中的OSTCBDly減一,當(dāng)某任務(wù)的OSTCBDly 減為零時(shí),就將其轉(zhuǎn)到就緒態(tài),以備運(yùn)行。 而OSIntExit()主要用于判別中斷的執(zhí)行是否使得更高優(yōu)先級(jí)的任務(wù)進(jìn)人就緒態(tài),如有,則進(jìn)行任務(wù)切換,否則返回。 至于時(shí)鐘中斷可由DSP 的定時(shí)器1 的周期計(jì)數(shù)器PRT 產(chǎn)生。

      2.3.4 中斷級(jí)上下文切換的實(shí)現(xiàn)函數(shù)OSIntCtxSw()

      與OSCtxSw()相比較,OSIntCtxSw()也是執(zhí)行任務(wù)切換的,但它執(zhí)行中斷級(jí)的任務(wù)切換。 不使用現(xiàn)成的OSCtxSw()進(jìn)行切換主要基于這樣的考慮:它是在中斷處理程序中調(diào)用的,類似于OSCtxSw()中保存寄存器的工作在進(jìn)人中斷時(shí)就做過(guò)了。 具體實(shí)現(xiàn)代碼參考函數(shù)OSCtxSw()代碼。

      2.4 內(nèi)核的測(cè)試

      內(nèi)核移植選用三知公司的SZ-2407IV 作為測(cè)試平臺(tái), 測(cè)試使用LED 顯示模塊和數(shù)字信號(hào)處理模塊。 本文設(shè)計(jì)了Task0(),Task1()兩個(gè)任務(wù),Task0()為L(zhǎng)ED 顯示任務(wù),Task1()為數(shù)字信號(hào)處理模塊,執(zhí)行一次DFT 算法,計(jì)算一個(gè)采樣點(diǎn)的DFT 值。

      μC/OS-II 的Tick 時(shí)鐘是周期性中斷, 每1.66ms 觸發(fā)一次,Task0和Task1 在延時(shí)32 個(gè)Ticks 的情況下即20ms 切換一次LED 閃爍顯示一位。 最后觀測(cè)結(jié)果,得到了預(yù)期效果。

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

      為了保證移植的成功并使系統(tǒng)可靠運(yùn)行, 除了要熟悉μC/OS-II和所用的處理器外,熟悉CC 編譯器C 開(kāi)發(fā)環(huán)境也是移植能否成功的一個(gè)關(guān)鍵。 而且,μC/OS-II 在TMS320LF2407 上的移植成功只是第一步,今后還需要對(duì)μC/OS-II 的內(nèi)核進(jìn)行擴(kuò)展,例如添加TCP/IP 軟件包,以適應(yīng)網(wǎng)絡(luò)化的需求,使之真正成為一個(gè)可重用的開(kāi)發(fā)平臺(tái)。

      [1]Jean Labrosse.μC/OS-II, 源碼公開(kāi)的實(shí)時(shí)嵌入式操作系統(tǒng)[M].邵貝貝,譯.北京:中國(guó)電力出版社,2001.

      [2]TMS320C2x/C2xx/C5xx Optimizing C Compilaer User’s Guide[Z].Texas Instruments,1999.

      猜你喜歡
      編譯器堆棧內(nèi)核
      萬(wàn)物皆可IP的時(shí)代,我們當(dāng)夯實(shí)的IP內(nèi)核是什么?
      強(qiáng)化『高新』內(nèi)核 打造農(nóng)業(yè)『硅谷』
      基于相異編譯器的安全計(jì)算機(jī)平臺(tái)交叉編譯環(huán)境設(shè)計(jì)
      基于嵌入式Linux內(nèi)核的自恢復(fù)設(shè)計(jì)
      Linux內(nèi)核mmap保護(hù)機(jī)制研究
      嵌入式軟件堆棧溢出的動(dòng)態(tài)檢測(cè)方案設(shè)計(jì)*
      基于堆棧自編碼降維的武器裝備體系效能預(yù)測(cè)
      通用NC代碼編譯器的設(shè)計(jì)與實(shí)現(xiàn)
      一種用于分析MCS-51目標(biāo)碼堆棧深度的方法
      編譯器無(wú)關(guān)性編碼在微控制器中的優(yōu)勢(shì)
      务川| 清苑县| 嵊泗县| 天台县| 建水县| 罗甸县| 漠河县| 长白| 宁南县| 漳州市| 师宗县| 绥德县| 安丘市| 博乐市| 河东区| 黄龙县| 三都| 长子县| 大冶市| 泸水县| 剑川县| 崇阳县| 高台县| 景泰县| 盐边县| 中方县| 祁阳县| 长泰县| 南阳市| 富阳市| 陆川县| 宜春市| 社旗县| 吉林省| 左云县| 秦皇岛市| 衡水市| 景洪市| 金塔县| 通化市| 蓬溪县|