新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 在MOTOROLA A68K系列MCU上移植μC/OS-II

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

作者: 時(shí)間:2012-03-07 來源:網(wǎng)絡(luò) 收藏

三、中的幾點(diǎn)注意事項(xiàng)

由于μ運(yùn)行的實(shí)時(shí)性,調(diào)試內(nèi)核幾乎不可能。一旦過程中內(nèi)核運(yùn)行不穩(wěn)定,很難確定是什么地方的問題,更困難的是有些現(xiàn)象幾乎是不可重復(fù)的。這就需要詳細(xì)了解內(nèi)核運(yùn)行機(jī)理,認(rèn)真分析,找出可能存在的問題。下面就來分析這些過程中的問題。

1.編譯器的優(yōu)化選項(xiàng)

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

通常在調(diào)用子程序或進(jìn)入中斷時(shí),C編譯器會自動保存CPU內(nèi)部寄存器到堆棧中。例如,在進(jìn)入中斷時(shí)編譯器會加入下面2條指令:

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

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

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

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

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

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

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

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

問題在于初始化任務(wù)的時(shí)候,每個(gè)任務(wù)實(shí)際上是按照圖1所示的堆棧結(jié)構(gòu)被初始化的,那么,按照圖2的堆棧結(jié)構(gòu)來恢復(fù)自然會導(dǎo)致堆棧崩潰。

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

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

較好的方法當(dāng)然是調(diào)整編譯器,取消這個(gè)優(yōu)化選項(xiàng)。如果無法調(diào)整編譯器,就只有用以上辦法來適應(yīng)編譯器了。

2.開關(guān)中斷的方法

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



關(guān)鍵詞: 移植 C/OS-II MCU 系列 A68K MOTOROLA

評論


相關(guān)推薦

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

關(guān)閉