摘要:首先介紹如何構建嵌入式開發平臺,包括硬件平臺和軟件平臺,硬件平臺的目標機采用ARM芯片,軟件平臺的宿主機采用Linux操作系統,并采用GDB調試軟件;然后詳細闡述了嵌入式軟件的交叉開發的一般步驟。通過實踐充分證明交叉開發是嵌入式軟件開發行之有效的方法,可以大大提高嵌入式軟件的開發效率。
關鍵詞:嵌入式系統; Linux; 交叉開發
中圖分類號:TP311文獻標志碼:A
文章編號:1001-3695(2008)01-0206-03
隨著信息技術的發展,微型化和專業化成為信息產品發展的新趨勢,嵌入式產品成為信息產業的主流。市場上出現種類眾多的商業性嵌入式操作系統。其中Linux以其內核可裁減、效率高、穩定性好、移植性好、源代碼開放等優點受到越來越多的企業和研發機構的關注。本文的開發就是基于Linux系統的。
由于嵌入式系統資源有限,用戶一般不具備自主開發能力,產品發布后用戶通常也不能對其中的軟件進行修改,必須有一套專門的開發環境由開發人員對軟件進行修改升級。該開發環境提供專門的開發工具(包括設計、編譯、調試、測試等工具),一般采用交叉開發的方式進行。
嵌入式軟件的交叉開發通常需要兩臺計算機。一臺作為主機(host),另一臺作為目標開發板(target)。主機可以是一臺運行Linux的PC,使用gcc、binutils作為編譯、鏈接器;目標開發板為gcc支持的CPU內核的S3C2410芯片的主板作為目標開發板,并在其上運行GDB stub 的調試監控程序。在主機上編譯、鏈接,得到包含調試符號的可執行文件并轉換成可下載的二進制文件;然后在主機上運行gdb,使用串行方式與目標板通信,實現下載、執行、單步、斷點等調試功能。在系統開發的初期,也可以在主機上完成所有工作,使用x86模擬器來運行和調試系統。常見的x86模擬器有VMWare、Bochs等。本文選擇的是VMWare。
1構建交叉開發平臺
基于Linux的嵌入式開發平臺由硬件平臺和軟件平臺組成。硬件平臺主要是指嵌入式系統運行的目標機,用于運行操作系統和系統應用軟件;目標板所用到的操作系統的內核編譯、應用程序的開發和調試則需要通過宿主PC機來完成。軟件平臺主要是指運行在宿主機上的基于GNU的開發工具鏈和調試運行時運行在目標機上的調試服務器、監視器等。
1)系統硬件平臺
在構建硬件平臺時,微處理器的性價比是筆者最關心的。現在比較流行的硬件平臺有Intel公司的StrongARM 系列,Motorola公司的DragonBall系列,NEC公司的VR系列,Hitachi公司的SH3、SH4系列等。選定硬件平臺前,首先要確定系統的應用功能和所需要的速度,并制定好外接設備和接口標準。這樣才能準確地定位所需要的硬件方案,得到性價比最高的系統。本文的硬件平臺是基于三星公司ARM 9 內核的S3C2410 芯片開發完成的。如圖1 所示, 整個硬件平臺由下面幾個部分組成[1]:
S3C2410: ARM 920T 核;
SDRAM: 8 MB;
flash: 128 MB;
LCD: 160×24016級灰度+觸摸屏;
16鍵矩陣鍵盤;
兩路RS-232接口等
其中, S3C2410 和SDRAM、或非型flash、與非型flash組成的最小系統可以運行指令和代碼; 通過串口、USB, SPI同外部交換信息和數據; 通過LCD 進行顯示; 在交叉調試時,宿主機通過JTAG接口對目標機進行調試。
2)系統軟件平臺
嵌入式軟件開發的最大特點就是交叉開發,體現在交叉編譯、交叉鏈接和交叉調試等方面。因此開發工具一定要能支持事先選定的硬件平臺,能夠生成基于特定微處理器指令集的目標程序,并能對其進行調試。建立交叉開發環境,首先要安裝軟件開發包。軟件開發包由嵌入式Linux操作系統、設備驅動支持包、嵌入式圖形包、GNU交叉編譯調試器組成。嵌入式Linux軟件開發平臺的系統結構如圖2所示[2]。
交叉調試的原理是用戶通過串口利用GDB遠程調試功能對目標機的二進制程序進行遠程調試,調試服務程序(GDBserver)在目標機上接收GDB(宿主機)通過串口發送的控制命令,控制二進制程序的運行狀態,并通過串口將GDB所需的狀態信息發給GDB。
在構建好交叉開發平臺后就可以進行嵌入式軟件的開發了。在交叉開發時通常分成五部分:建立嵌入式Linux交叉開發環境、交叉編譯和鏈接、交叉調試、系統測試、固化運行。
2建立嵌入式交叉開發環境
交叉開發環境是指編譯、鏈接和調試嵌入式應用軟件的環境。一般包括文本編輯器、交叉編譯器、交叉調試器、仿真器、下載器等工具。它與運行嵌入式應用軟件的環境有所不同,通常采用宿主機/目標機模式[3]。宿主機與目標機之間在物理連接的基礎上建立起邏輯連接,如圖3所示。
1)宿主機
宿主機是用于開發嵌入式軟件的計算機。從硬件配置來講,它們一般為通用的PC機,其上的軟件配置很豐富。除了功能強大的桌面操作系統外,還具備各種開發工具,為編輯、編譯、鏈接、調試、測試及固化嵌入式應用軟件提供全程支持。
2)目標機
目標機即所開發的嵌入式系統,是嵌入式軟件的運行環境。目標機的嵌入式操作系統是用于支撐嵌入式應用的,不是用于開發的環境平臺。在開發過程中目標機端需接收和執行宿主機發出的各種命令,如設置斷點、讀內存和寫內存等,將結果返回給宿主機,配合宿主機各方面的工作。斷點主要功能是使程序在某個指定的地方停下來,以便觀察各種有用的信息,如寄存器的值、某個變量的值和某個內存單元的值等。斷點可以分為硬件斷點和軟件斷點兩種。
3)物理連接和邏輯連接
物理連接是指宿主機和目標機上的一定物理端口通過物理線路連接起來。它是邏輯連接的基礎。邏輯連接是指宿主機和目標機間按照某種通信協議建立起來的通信連接,目前逐步形成了一些通信協議的標準。要順利地建立交叉開發環境,需要正確設置這兩種連接,缺一不可。在物理連接上,要注意使硬件線路正確連接,且硬件設備完好、能正常工作、連接線路的質量要好;邏輯連接在于正確配置宿主機和目標機的物理端口的參數,并且與實際的物理連接在一起。
3交叉編譯和鏈接
嵌入式軟件的生成可分為三個階段[3]:源代碼的編寫;將源程序交叉編譯成各個目標模塊;將所有目標模塊及相關的庫文件一起鏈接成可供下載調試或固化的可執行代碼,如圖4所示。由于開發過程大多是在Intel公司x86系列CPU的通用計算
機上進行的,而目標環境的處理器芯片卻大多為ARM、MIPS、PowerPC、DragonBall等系列的微處理器。這就要求在建立好的交叉開發環境中進行交叉編譯和鏈接。
1)交叉編譯器
交叉編譯器的主要功能是把宿主機上編寫的高級語言程序編譯成可以運行在目標機上的代碼,即在宿主機上能夠編譯生成能在另一種CPU(嵌入式微處理器)上運行的二進制程序。在基于ARM體系結構的gcc交叉開發環境中,arm linux gcc是交叉編譯器。
2)交叉鏈接器
嵌入式軟件的運行方式主要有兩種:調試方式和固化方式。不同方式下程序代碼或數據在目標機內存中的定位有所不同。宿主機上提供一定的工具或手段對目標程序的運行方式和內存定位進行選擇和配置;鏈接器再根據這些配置信息將目標模塊和庫文件中的模塊鏈接成目標程序。因此稱這樣的鏈接器為交叉鏈接器。在基于ARM體系結構的gcc交叉開發環境中,arm linux ld是交叉鏈接器。
4交叉調試
在開發嵌入式軟件時,交叉調試是必不可少的一步。交叉調試是指調試程序和被調試程序運行在不同機器上的調試。調試器通過某種方式能控制目標機上被調試程序的運行方式,并且通過調試器查看和修改目標機上的內存、寄存器以及被調試程序中的變量。
交叉調試的方式即調試器控制被調試程序運行的方式有很多種。本文所用的調試方案為主機端環境是標準Linux系統,基于邊界掃描JTAG技術[4]。交叉調試系統由主機調試器、目標機上的調試代理、調試協議三部分組成。其體系結構如圖5所示[4]。主機調試器主要實現對源文件、目標文件和符號表的訪問處理,接收用戶輸入的調試命令,并根據調試協議封裝成調試命令請求包發送給調試代理,同時接收調試代理返回的調試信息,以獲取目標程序的當前運行狀態。目標機上的調試代理負責根據調試協議接收并解析調試命令,監控目標程序的運行狀態,將目標程序狀態信息返回主機端。調試協議則規定了調試命令和調試信息的數據格式及通信過程。
圖4嵌入式軟件的生成階段圖5交叉調試系統體系結構
此交叉調試的特點是主機端環境為Linux系統,主機調試器采用GDB + JTAGER 的方案,由GDB 完成對源文件、目標文件和符號表的訪問處理及與用戶的交互,由JTAGER 程序封裝對交叉調試的支持;調試協議是JTAGER 程序與調試代理程序之間的通信規范。調試代理程序handler 則通過特有的LDIC 指令載入目標芯片的微型指令緩存中。
4.1調試協議
調試協議是整個交叉調試系統的中心。它規定了主機和目標機之間的數據通信過程。主機和目標機采用盡量簡單的數據包交互,JTAGER需要發往handler的調試命令包括讀寫目標機內存(g 和p)、增加斷點(b)、繼續運行(c)。由于讀寫目標機寄存器會頻繁發生,采用輪詢方式定時完成。
在主機和目標機通信過程中用到的通信協議主要有普通RX 握手協議、快速數據下載握手協議、TX 握手協議。
4.2主機端調試器GDB+JTAGER
GDB是公開源碼的一種功能強大的通用調試器。它支持豐富的調試命令和多種編程語言,并支持遠程調試方式。運行GDB的平臺通過并行端口(或網口、串口等)連接到已建立運行環境的目標機時,GDB 可以按照遠程串行協議(RSP)與目標機上的插樁程序通信來調試目標系統。但當目標機為裸機時,GDB無法與之通信而不能調試,所以再增加一個中間軟件JTAGER。其功能是應用JTAG 技術實現對裸機的交叉調試。
1)GDB 交互數據包
交互過程必須遵守GDB RSP進行數據包處理[4]。數據包格式為$packet_data#checksum。其中:
$為數據包的頭標志;packet_data 為數據包內容;#是數據包結束標志;checksum表示整個數據包的檢驗碼,用來保證數據的正確傳送。
在JTAGER 運行過程中,其主控循環不斷地接收RSP 數據包、解析,并將處理結果封裝成應答RSP數據包,交給GDB。以讀內存為例,
GDB 發往JTAGER 的數據包:$mc0018004,4#8d
JTAGER 應答GDB 的數據包:$00d82de9#30
2)JTAGER主控流程
JTAGER在主機上與GDB 并行運行。它使用UNIX的I/O多路轉換機制監聽指定的tcp 調試端口與GDB 進行通信。JTAGER主體控制流程偽碼如下:
JTAGER主控程序(…)
{
初始化目標板的JTAG接口;
往目標板的MiniIC載入handler;
打開GDB遠程tcp端口,接收gdb遠程調試數據;
while(1)
{
監視tcp調試端口和用戶標準輸入;
if(有數據包)解析后進入相應調試命令處理函數;
else輪詢目標機的傳輸寄存器TX;
}
收到退出命令作結束程序的處理,進行tcp連接的中斷和內存的回收。
}
4.3目標機代理handler
目標機調試代理handler按照調試協議[4]和JTAGER 進行調試命令與調試信息的交互。當調試事件發生時作為一個事件處理器對目標芯片進行控制。需要注意的是,由于微型指令緩存大小的限制(2 KB),handler代碼量要盡量地精簡。使用ARM匯編編寫,其程序流程偽碼如下所示:
handler程序流程(…)
{
初始化handler,使目標機處于就緒狀態(halt mode);
向JTAGER發送目標機就緒的信號;
while(1)
{
等待JTAGER發送相應調試指令;
//通過mrc實現對RX的讀出
if(接收到調試指令)進入相應調試處理子程序;
else向JTAGER發送調試結果;
//通過mcr實現對TX的寫入
}
}
5系統測試
整個軟件系統編譯過程中,嵌入式系統的硬件一般采用專門的測試儀器進行測試[3]。軟件則需要有相關的測試技術和測試工具的支持,并要采用特定的測試策略。嵌入式軟件測試中經常用到的測試工具主要有內存分析工具、性能分析工具、覆蓋分析工具和缺陷跟蹤工具等。
在嵌入式軟件測試中,常常要在基于目標機的測試和基于宿主機的測試間作出折中。基于目標機的測試需要消耗較多的時間和經費;基于宿主機的測試雖然代價較小,但畢竟是在仿真環境中進行的,因此難以完全反映軟件運行時的實際情況。這兩種環境下的測試可以發現不同的軟件缺陷,關鍵是要對目標機環境和宿主機環境下的測試內容進行合理取舍。
6嵌入式軟件的固化運行
當調試和測試完成后,程序代碼需要被完全燒入到目標板的非易失性存儲器中,并且在真實的硬件環境上運行。這個過程叫做固化。分析調試環境與固化環境之間的區別是解決固化問題的關鍵所在。兩者的詳細區別如表1所示[3]。
a)代碼定位不同。
在嵌入式系統中,一般使用兩種存儲器:可讀/寫的RAM;非易失性存儲器,如ROM、flash memory等。在調試方式下,全部應用代碼和數據都定位在RAM中,代碼在RAM中運行;在固化方式下,代碼和數據是存儲在非易失性存儲器中的,系統啟動時要先將數據搬移到RAM中,而程序代碼可在ROM、flash memory中運行。
b)初始化部分不同。
固化程序要創建boot模塊,此模塊被連接作為整個應用系統代碼的入口模塊。當應用程序在真實環境下運行時將首先執行該程序,完成對CPU的初始化。在嵌入式環境中,boot模塊一般包含初始化芯片的引腳、初始化一些系統外部控制寄存器、初始化基本I/O設備等功能。
完成了上述準備工作,就可以利用編譯鏈接工具生成可固化的應用程序;再用固化工具將它固化到目標機的ROM、flash memory等非易失性存儲器上。當用戶啟動目標機時,該應用程序就會被自動裝入運行。
7結束語
基于Linux平臺可以方便地進行嵌入式開發。利用Linux 下免費的開發工具集大大縮短了開發周期、提高了開發效率。用戶還可以很方便地添加自己所要的功能,其結構具有良好的移植性。但是由于嵌入式系統應用越來越廣泛,對嵌入式產品的需求高速增長,其產品開發效率成為開發者首要考慮的問題,提供完整的集成開發環境是每個嵌入式系統開發人員所期待的。Linux在基于圖形界面的特定系統定制平臺的研究上,與Windows操作系統相比還存在差距。因此,要使嵌入式Linux在嵌入式操作系統領域中的優勢更加明顯,整體集成開發環境還有待提高和完善。
本文從應用的角度詳細闡述了當今嵌入式開發的具體步驟。這是嵌入式開發的一般步驟。實踐證明交叉開發是嵌入式軟件開發行之有效的方法,可以大大提高嵌入式軟件的開發效率。
參考文獻:
[1]安成錦,孫茂陽,李坡,等.基于嵌入式Linux系統的MiniGUI圖形界面開發[J].現代電子技術,2005,28(20):108 110.
[2]唐永波,喻建文,邱緒蓮,等.基于Linux嵌入式系統的研究[J].計算機與數字工程,2005,33(10):98 102.
[3]羅蕾.嵌入式實時操作系統及應用開發[M].北京:北京航空航天大學出版社,2005:72-88.
[4]陽富民,柯滔,涂剛,等.基于JTAG技術的嵌入式交叉調試軟件[J].計算機工程與設計,2005,26(10):2817-2819.
[5]李允,熊光澤,程紅蓉.普適計算終端設備的電源管理技術研究[J].電子科技大學學報,2001,30(5):497-502.
[6]毛德操,胡希明.Linux 內核源代碼情景分析[M].杭州:浙江大學出版社, 2001:663-671.
[7]李善平, 劉文峰, 王煥龍,等.Linux與嵌入式系統[M].2版.北京: 清華大學出版社, 2006:187 193.
“本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文”