μC/OS-Ⅱ在ATmega128上的移植Step by Step
本文詳細介紹了把μC/OS-Ⅱ移植到ATMEL公司的8位微控制器ATmega128上的全過程。所謂移植,就是使一個實時內(nèi)核能在
本文引用地址:http://cafeforensic.com/article/201610/305777.htm某個微處理器或微控制器上運行。在移植之前,希望讀者能熟悉所用微處理器和C編譯器的特點。
1 ATmega128的內(nèi)核特點
之所以要先介紹ATmega128 MCU內(nèi)核特點,是因為在μC/OS-Ⅱ的移植過程中,仍需要用戶用C語言和匯編語言編寫一些與微
處理器相關(guān)的代碼。這里主要介紹ATmega128與μC/OS-Ⅱ移植相關(guān)的內(nèi)核特點。如果讀者已經(jīng)對ATmega128 比較了解了,
那就不必閱讀這一部分了。
1.1微控制器 (MCU)
ATmega128的MCU包括一個算術(shù)邏輯單元(ALU),一個狀態(tài)寄存器(SREG),一個通用工作寄存器組和一個堆棧指針。狀態(tài)
寄存器(SREG)的最高位I是全局中斷允許位。如果全局中斷允許位為零,則所有中斷都被禁止。當系統(tǒng)響應(yīng)一個中斷后,I位將由硬件自動清“0”;當執(zhí)行中斷返回(RETI)指令時,I位由硬件自動置“1” ,從而允許系統(tǒng)再次響應(yīng)下一個中斷請求。
通用工作寄存器組是由32個8位的通用工作寄存器組成。其中R26~R31這6個寄存器還可以兩兩合并為3個16位的間接地址寄存器。這些寄存器可以用來對數(shù)據(jù)存儲空間進行間接尋址。這3個間接地址寄存器的名稱為:X寄存器、Y寄存器、Z寄存器。其中Z寄存器還能用作對程序存儲空間進行間接尋址的寄存器。有些AVR C語言編譯器還把Y寄存器作為軟件堆棧的堆棧指針,比如ICC- AVR,CodevisionAVR。
堆棧指針(SP)是一個指示堆棧頂部地址的16位寄存器。在ICCAVR中,它被用作指向硬件堆棧的堆棧指針。AVR單片
機上電復(fù)位后,SP指針的初始值為0x0000,由于AVR單片機的堆棧是向下生長的(從高地址向低地址生長),所以系統(tǒng)程序
一開始必須對堆棧指針SP進行初始化,即將SP的值設(shè)為數(shù)據(jù)存儲空間的最高地址。ICCAVR編譯器在鏈接C程序文件的時 候,會自動在程序頭鏈入startup文件。startup文件里面的程序?qū)プ龀跏蓟疭P指針的工作。鏈入startup文件是ICCAVR 這個編譯器的特點,在用其它編譯器的時候,希望讀者確認所使用的編譯器是否帶有自動初始化SP的功能,若沒有,應(yīng)在 用戶程序中初始化SP。
1.2 數(shù)據(jù)存儲空間(僅內(nèi)部)
AVR單片機的數(shù)據(jù)存儲器是線形的,從低地址到高地址依次是CPU寄存器區(qū)(32個通用寄存器),I/O寄存器區(qū),數(shù)據(jù)存儲區(qū)ICCAVR編譯器又將數(shù)據(jù)存儲區(qū)劃分為全局變量和字符串區(qū),軟件堆棧區(qū)和硬件堆棧區(qū)三個空間。
高地址
硬件堆棧區(qū)
軟件堆棧區(qū)
全局變量和字符串區(qū)
I/O寄存器區(qū)
CPU寄存器區(qū)
低地址
ICCAVR編譯器將堆棧分成了兩個功能不同的堆棧來處理(這一點與8051系列的單片機編譯器處理方式不同)。硬件堆棧用于儲存子程序和中斷服務(wù)子程序調(diào)用時的函數(shù)返回地址。這塊數(shù)據(jù)區(qū)域由堆棧指針SP進行尋址,數(shù)據(jù)的進棧和出棧有專門的匯編指令(pop,push等)支持,所以叫做硬件堆棧區(qū)。軟件堆棧用于傳遞參數(shù),儲存臨時變量和局部變量。這塊數(shù)據(jù)區(qū)域是用軟件模擬堆棧儲存數(shù)據(jù)的方式進行數(shù)據(jù)存儲,對該區(qū)域?qū)ぶ返闹羔樣捎脩糇约憾x,所以叫做軟件堆棧區(qū)。AVR單片機的硬件堆棧的生長方向是向下的(從高地址向低地址生長),所以軟件堆棧在定義的時候,也采取相同的 生長方向。
這里沒有用ATmega128而采用AVR單片機的提法是因為ATmega128屬于AVR系列單片機中的一種,而所有的AVR單片機的數(shù)據(jù)存儲器組織方式都是一致的。在創(chuàng)建μC/OS-Ⅱ的任務(wù)棧時,需要了解所用微處理器數(shù)據(jù)存儲空間尤其是堆棧空間的組 形式及相關(guān)的操作。讀者應(yīng)參閱所用微處理器的資料和編譯器的幫助文檔,了解該部分知 識。
1.3 ATmega128的中斷響應(yīng)機制
ATmega128有34個不同的中斷源,每個中斷源和系統(tǒng)復(fù)位在程序存儲空間都有一個獨立的中斷向量(中斷入口地址)。每個中斷源都有各自獨立的中斷允許控制位,當某個中斷源的中斷允許控制位為“1”且全局中斷允許位I也為“1”時,系統(tǒng)才響應(yīng)該中斷。
當系統(tǒng)響應(yīng)一個中斷請求后,會自動將全局中斷允許位I清零,此時,后續(xù)中斷響應(yīng)被屏蔽。當系統(tǒng)執(zhí)行中斷返回指令RETI時,會將全局中斷允許位I置“1”,以允許響應(yīng)下一個中斷。若用戶想實現(xiàn)中斷嵌套,必須在中斷服務(wù)子程序中將全局中斷允許位I置“1”。(這一點與8051系列的單片機不同)中斷向量表中,處于低地址的中斷具有高的優(yōu)先級。優(yōu)先級高只是表明在多個中斷同時發(fā)生的時候,系統(tǒng)先響應(yīng)優(yōu) 先級高的中斷,并不含有高優(yōu)先級的中斷能打斷低優(yōu)先級的中斷處理工程的意思。這與8051系列單片機的中斷優(yōu)先級概念
不同。
由于μC/OS-Ⅱ的任務(wù)切換實際上是模擬一次中斷,因此需要知道CPU的中斷響應(yīng)機制。中斷發(fā)生時,ATmega128按以下
步驟順序執(zhí)行:
A. 全局中斷允許位I清零。
B. 將指向下一條指令的PC值壓入堆棧,同時堆棧指針SP減2。
C. 選擇最高優(yōu)先級的中斷向量裝入PC,程序從此地址繼續(xù)執(zhí)行中斷處理。
D. 當執(zhí)行中斷處理時,中斷源的中斷允許控制位清零。
中斷結(jié)束后,執(zhí)行RETI指令,此時
A. 全局中斷允許位I置“1”。
B. PC從堆棧推出,程序從被中斷的地方繼續(xù)執(zhí)行。
特別要注意的是:AVR單片機在響應(yīng)中斷及從中斷返回時,并不會對狀態(tài)寄存器SREG和通用寄存器自動進行保存和恢復(fù)操作,因此,對狀態(tài)寄存器SREG和通用寄存器的中斷保護工作必須由用戶來完成。
1.4 ATmega128的定時器中斷
ATmega128有三個定時器:T0,T1,T2;它們?nèi)叨加杏嫈?shù)溢出中斷功能,而且T1和T2還有匹配比較中斷,即定時器計數(shù)到設(shè)定的值時,產(chǎn)生中斷并自動清零。若系統(tǒng)采用這種中斷方式,其好處是在中斷服務(wù)程序ISR中不需要重新裝載定時器的值。但本文出于通用性的考慮,仍采用定時器計數(shù)溢出中斷方式
2 μC/OS-Ⅱ的移植
2.1移植條件
要實現(xiàn)μC/OS-Ⅱ的移植,所用的處理器和編譯器必須滿足一定的條件:
(1) 所用的C編譯器能產(chǎn)生可重入代碼。
可重入代碼是指可以被一個以上的任務(wù)調(diào)用,而不必擔心其數(shù)據(jù)會被破壞的代碼??芍厝氪a任何時候都可以被中斷,一段時間以后又可以重新運行,而相應(yīng)的數(shù)據(jù)不會丟失,不可重入代碼則不行。本文所使用ImageCraft公司的ICCAVR V6.29編譯器能產(chǎn)生可重入代碼。
評論