新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > UCOS移植心得

        UCOS移植心得

        作者: 時間:2016-11-27 來源:網絡 收藏
        移植UCOS之前,你首先應該做好三件事:


        1.弄懂UCOS,這是誰都知道的哦 ^_^

        2. 弄懂你想要移植到的硬件平臺

        3. 清楚你使用的編譯器是如何處理函數的局部變量和怎么樣處理函數間的參數傳遞

        這里多廢話幾句第三點:在UCOS里面,所有函數都要求具有重入性(除了OSSTAR()外,只有這個函數我覺得是不需要的,它僅僅使用了一次);重入性是多任務的基礎,而所謂重入性從函數而言就是它的變量的保存問題,在中斷這個函數的執行時它使用的變量需要得到保存,以便返回后的執行是正確的,就我使用的編譯器而言,它通過堆棧傳遞函數參數,

        重入性問題就很容易解決拉,在中斷任務時,它的參數已經在堆棧里面了,只要你保存好CPU寄存器和堆棧指針SP就好

        而如果你使用的是KEIL的話就比較復雜拉,首先KEIL是51單片機的東西,51只有很少的存儲空間,KEIL的重入性是通過設立模擬棧實現的,當任務中斷執行時,你不僅需要保存CPU寄存器,還要保存模擬棧的內容,特別是51的SP尋址能力不強,只有8位,不能在64K的空間自移動,而UCOS比較大,KEIL編譯時只能用大規模方式,這就意味著所有的全局變量都會保存在片外空間,而SP無法訪問到,你需要設立一個公共的系統棧,保存正在運行的任務的數據,在任務切換時把這個系統棧的內容拷貝到它的任務棧里,操作比較繁瑣

        注意系統的初始化問題,我在第一個任務里調用了系統初始化函數,在里面開中斷允許.

        任務可以是關中斷時被掛起,也可以是開中斷時被掛起,那么在任務切換回來后如何保證它的中斷狀況呢?問題可以通過給每個任務設置一個中斷計數器解決,并初始化為 0,記錄每個任務的開關中斷次數,關一次中斷加 1,開一次中斷減 1, 在任務調度的時候保存當前任務的中斷計數器,切換到新任務時查看新任務的中斷計數器,如果為 0就開中斷返回,不然就直接返回(任務級切換是在關中斷下進行的);而對于中斷級任務調度,肯定是發生在開中斷情況下的,就要查看是否需要關中斷處理

        現在開始說我的移植:我移植到的平臺是凌陽公司的SPCE061A 16位單片機,它有2K的RAM,32K的ROM空間,基本上夠用,但不能有太多功能,我在研究了這款片子的資料后,才開始自己的移植,主要是學了一下它的匯編語言和混合編程以及CPU得硬件方面;在堆棧的問題上我發現凌陽的SP是16位的,可以尋址64K的空間,不需要設立系統棧. 在OS_CPU_C.C中注意堆棧的初始化,一定要在任務切換時嚴格遵守你的初始化時假定的寄存器順序.

        下面開始移植最重要的三個文件:

        OS_CPU_C.C:

        OSTaskStkInit():

        stk=(OS_STK *)ptos;


        *stk--=*((INT16U*)task+1);/*任務首地址 (PC)*/

        *stk--=0x0000;/*SR(R6) */

        *stk--=0x0000;/*BP(R5) */

        *stk--=0x0000;/*R4*/

        *stk--=0x0000;/*R3*/

        *stk--=0x0000;/*R2*/

        *stk--=0x0000;/*R1*/

        *stk--=0x0000;/*該任務的中斷狀況計數器*/

        return((void *)stk);

        別的就是空函數,比較簡單,這里略去

        這個文件比較簡單,唯一要注意的是堆棧初始化函數,像剛剛說到的,你假定的堆棧內容必須在任務切換時嚴格遵守.還有就是定義幾個空函數

        OS_CPU_A.ASM:

        這個文件呢是移植的關鍵,需要用匯編語言編寫,(我有個同學很能噴,認為匯編語言純屬沒用,像這種話千萬不要相信!),在這個文件里,你需要完成UCOS的核心代碼!

        首先是OSStartHighRdy():

        該函數在系統開始時使最高優先級任務運行,代碼如下:

        _OSStartHighRdy:

        CALL_OSTaskSwHook



        R1=0x0001

        [_OSRunning]=R1



        R1=[_OSTCBCur]

        SP=[R1]

        POP R1 FROM [SP]

        [_InterruptC]=R1//彈出任務中斷狀況計數器

        POP R1,R5 FROM [SP]

        RETI

        接著是OSCtxSw():

        完成任務切換,代碼如下:

        _OSCtxSw:

        PUSH R1,R5 TO [SP]

        R1=[_InterruptC]

        PUSH R1 TO [SP]//保存任務中斷狀況



        R2=[_OSTCBCur]

        [R2]=SP

        CALL _OSTaskSwHook



        //OSUCBCur=OSTCBHighRdy

        R1=_OSTCBCur

        R2=[_OSTCBHighRdy]

        [R1]=R2



        //OSPrioCur=OSPrioHighRdy

        R1=[_OSPrioHighRdy]

        [_OSPrioCur]=R1



        R1=[_OSTCBHighRdy]

        SP=[R1]

        POP R1 FROM [SP]

        [_InterruptC]=R1//彈出任務中斷狀況

        CMP R1,0//查看是否需要開中斷

        JNE KAI

        INT IRQ

        KAI: POP R1,R5 FROM [SP]

        RETI

        上一頁 1 2 下一頁

        關鍵詞: UCOS移植心

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 西华县| 台江县| 太和县| 西青区| 舒兰市| 桃园县| 温泉县| 咸丰县| 苏尼特右旗| 枣庄市| 富蕴县| 新沂市| 兴城市| 绥滨县| 柘荣县| 龙南县| 通州市| 东辽县| 交城县| 和静县| 全州县| 巴东县| 阿鲁科尔沁旗| 封丘县| 牡丹江市| 鄂尔多斯市| 孙吴县| 紫阳县| 乐清市| 平罗县| 仙居县| 台江县| 丰镇市| 南充市| 涿鹿县| 登封市| 舟曲县| 新竹县| 玉龙| 宁波市| 峡江县|