新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 在MOTOROLA A68K系列MCU上移植μC/OS-II

        在MOTOROLA A68K系列MCU上移植μC/OS-II

        作者: 時間:2012-03-07 來源:網絡 收藏

        三、中的幾點注意事項

        由于μ運行的實時性,調試內核幾乎不可能。一旦過程中內核運行不穩定,很難確定是什么地方的問題,更困難的是有些現象幾乎是不可重復的。這就需要詳細了解內核運行機理,認真分析,找出可能存在的問題。下面就來分析這些過程中的問題。

        1.編譯器的優化選項

        在移植過程中,除了要熟悉μ和目標芯片之外,熟悉使用的C編碼器也非常重要。通常C編譯器都會提供一些優化代碼的選項,在移植μc/OS-II的過程中,這些選項往往會帶來麻煩。下面是移植中與HIWARE的C編譯器有關的例子。

        通常在調用子程序或進入中斷時,C編譯器會自動保存CPU內部寄存器到堆棧中。例如,在進入中斷時編譯器會加入下面2條指令:

        LINK #$0000,A6;
        MOVEM.L D0/D1/D3/D4/D5/D6/D7/A0/A1/A2/A3/A4/A5,-(A7);

        這2 條匯編指令的作用是將CPU的數據寄存器D0~D7、地址寄存器A0~A5保存到堆棧中,再將此時的堆棧指針A7也保存到堆棧中,并使用A6作為臨時的堆棧指針。這本是一個非常好的優化選項,可以防止在中斷中偶然地更改了數據寄存器或地址寄存器;但在μ中,這個機制將對OS_CPU_C.C 和OS_CPU_ASM.ASM中的幾個子程序和中斷服務例程產生致命的影響。

        OS_CPU_C.C和OS_CPU_ASM.ASM中的子程序中斷引發任務調度,當前的任務被掛起。掛起任務是通過下面的語句來完成的:
        MOVEM.L A0-A6/D0-D7,-(A7);
        MOVE.L @OSTCBCur,A2;
        MOVE.L (A2),A1;
        MOVE.L A7,(A1);

        保存任務的指針和所有數據地址寄存器的值,那么理想情況下,此時的任務堆棧應該是如圖1所示的情況(以OSCtxSw()函數為例,可以對應到OS_CPU_C.C和OS_CPU_ASM.ASM中的其他函數和中斷處理例程)。

        那么恢復掛起的任務時,只要通過如下語句:
        MOVE.L OSTCBHighRdy,A1;
        MOVE.L @OSTCBCur,A2;
        MOVE.L A1,(A2);
        MOVE.L (A1),A7;
        MOVEM.L (A7)+,A0-A6/D0-D7;

        將保存在任務TCB中的任務堆棧指針恢復,再恢復數據地址寄存器,最后執行OSCtxSw()的中斷返回,就可以順利地恢復被掛起的任務。

        如果C編譯器在OSCtxSw()函數入口處插入了2條保存數據地址寄存器和堆棧指針的語句后,再執行掛起任務的語句,任務的堆棧會變成圖2所示的情況。編譯器引起了堆棧的變化,如果所有的任務都是用這種方式掛起和恢復的,并不會產生致命的問題,因為編碼器退出OSCtxSw()函數時會插入如下語句恢復堆棧:

        MOVEM.L (A7)+,D0-D7/A0-A5;
        UNLK A6;

        問題在于初始化任務的時候,每個任務實際上是按照圖1所示的堆棧結構被初始化的,那么,按照圖2的堆棧結構來恢復自然會導致堆棧崩潰。

        解決這個問題的方法很多,可以改定任務初始化的代碼以適應C編譯器的這個“優化”,也可以在進入OSCtxSw()函數時首先調用如下語句恢復堆棧,抵消C編碼器的影響:
        MOVEM.L (A7)+,D0-D7/A0-A5;
        UNLK A6;

        而在退出OSCtxSw()函數前再調用如下語句模擬出更動的堆棧:
        LINK #$0000,A6
        MOVEM.L D0-D7/A0-A5,-(A7);

        較好的方法當然是調整編譯器,取消這個優化選項。如果無法調整編譯器,就只有用以上辦法來適應編譯器了。

        2.開關中斷的方法

        在μC/OS -II中,開關中斷是非常重要的,它可以保證關鍵代碼或訪問全局變量時不受中斷的意外影響。CPU32的中斷控制比較復雜,提供了7級具有不同級別的中斷;可以選擇關閉或打開某幾級中斷。但多級中斷會使得μC/OS-II的中斷處理變得復雜。在簡單的應用或初次嘗試移植μC/OS-II時,可以使用全開全關的方法。



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 怀仁县| 普兰县| 辽中县| 临安市| 阿拉善右旗| 泰州市| 临潭县| 汝州市| 正镶白旗| 潞西市| 瑞安市| 象山县| 金乡县| 阳东县| 达日县| 新乐市| 迭部县| 宁强县| 云龙县| 叙永县| 灵川县| 缙云县| 闸北区| 岢岚县| 馆陶县| 弥渡县| 盐亭县| 芜湖县| 海晏县| 东安县| 沁源县| 台江县| 东港市| 临桂县| 晋州市| 南通市| 喀什市| 桦川县| 阳东县| 都江堰市| 新竹市|