修改 MCU=8535
AAVRMCU=1
GCCMCU=at90s$(MICU)
AVRXMCU=_AT90S$(MCU)_為 ICCMCU=m16
AAVRMCU=3
GCCMCU=atmega16
AVRXMCU=_AT90Megal6_
②重新修改AVRX源碼的serialio.S文件,即根據不同的單片機修改串口部分的寄存器定義。需要增添如下代碼:
#if defined(UBRRL)
#define UBRR UBRRL
#endif
#if defined(UBRRH)
sts UBRRH, plh
#endif
③重新編譯內核。具體做法是復制一個“命令提示符”到AVRX目錄下,運行“命令提示符”,鍵入“makegcc”命令后運行就完成了AVRX內核的重新編譯,會生成很多的.o文件和avrx.a文件。這些文件在以后的應用程序中會使用。
至此就完成了AVRX在ATmegal6單片機上的內核移植,接著就可以編寫應用程序了。
2.2在AVRX上編寫應用程序
這時候要用一個新的makefile文件,同時自己的程序可以不和AVRX的內核在一個目錄,但是要指出依賴文件的明確路徑。makefile的框架可以采用Winavr的sam-ple文件夾下的makefile文件框架。這里的難點其實還是makefile文件的語法問題。下面介紹應用程序的makefile文件在實例中需要修改或增加的代碼:
MCU=atmegal6 /*微處理器的名字*/
TARGET=test /*應用程序文件名*/
GCCLIB=$(AVRX)/avrx/avrx.a
GCCINC=-I.-I$(AVRX)/avrx-I$(AVR)/avr/inc /*加上相關的庫*/
SCANF_LIB_MIN=-Wl,-u,vfscanf-lscanf_min
SCANF_LlB_FLOAT= -Wl,一u,vfscannf-lscanl_flt
SCANF_LIB= /*設置sacnf函數庫的類型,在不使用時可以
注釋掉,這樣可以減小編譯后的文件太小*/
LDFLAGS+=$(PRIBITF_LlB)$(SCANF_LIB)
$(MATH_LIB) /*新增的連接器參數設定*/
3 系統測試
3.1 系統實時性測試
在實時系統中,實時系統的實時性表現在系統對外部事件的響應能力上。系統通過中斷來響應外部事件的發生,并且在用戶中斷程序中做的事要盡量少,把大部分工作留給任務去做,只是通過信號量或者消息機制來通知任務運行。Mega16的定時器2設為比較匹配輸出模式,在匹配時間到了之后產生一定周期脈沖輸出,并產生中斷。設置定時器1為計數模式來計數產生的脈沖輸出。通過定時器2的比較匹配中斷服務子程序來發信號量通知任務運行,并在中斷子程序中不開中斷,而在任務得到信號后開中斷,以實現中斷處理與任務運行的同步。任務中對一個全局變量計數,以記錄任務執行的次數。運行一段時間后,在設置的匹配時間里,任務的運行次數和定時器1的計數一樣,則系統在這段時間里是能完全響應外部事件的。當定時器2的比較匹配時間設為大于23 μs時,2個計數是相等的;當小于23 μs時,定時器1計數值大于任務計數值,說明任務沒有完全得到響應。這說明中斷的進入和返回即系統對外部時間的響應和處理時間為23 μs,遠遠大于其他操作系統在AVR單片機上移植后的響應時間。
3.2應用例程測試
這里只對源文件中的幾個例程先進行簡單的編譯,然后去掉不必要的代碼,加入自己想測試的一些代碼,進行了定時器控制模塊、信號量和消息隊列以其簡單組合的測試,均在ATmega16上達到了預期的效果。
4 心得體會
①AVRX的源碼都是用匯編語言編寫的,相對來講代碼效率很高,但是由于沒有詳細的API介紹文檔,所以最好的入門方法就是先讀懂RTOS的源碼和例程,然后進行修改,再加上自己的代碼逐漸熟練應用。
②AVRX需要分配的堆棧為35個字節加上任務代碼需要的額外堆棧,具體的大小取決于每個進程用的本地變量個數。比較好的確定分配給任務堆棧大小的方法是:分配很大的堆棧(如70字節),運行一段應用程序后看堆棧到多深(因為GCC啟動時把所有內存都清0了,這樣很容易看到)。不過,為了安全起見,用編譯器或仿真器在估計堆棧的頂端寫入幾個字節的0xFFFFF去驗證到底達到了多少字節,然后分配給比測試結果多兩個以上的字節給這個任務。
③啟動的最后一個指令必須跳轉到Epilog()。
5 結論
AVRX是一個不錯的RTOS,最顯著的特點就是內核小,速度快,編譯后大概只需500~700字節,且基本的調度功能一個也不少。由于其代碼公開,結合不同型號AVR單片機的特性,可以在此基礎上進行系統的裁減和擴展,使之能達到更好的效果。本文為AVR嵌入式系統的應用提供了借鑒。