胡 昊,蔣志翔,張 楊
(中國航天科工集團第二研究院706所,北京100854)
一個良好的集成開發(fā)環(huán)境能夠簡化開發(fā)過程,減輕開發(fā)人員用于工具上的精力,提高開發(fā)效率。當前比較流行的開發(fā)環(huán)境平臺軟件有Microsoft Visual Studio、Eclipse、Code Blocks等,這些開發(fā)環(huán)境提供了一般軟件開發(fā)所需的一系列功能,然而對于嵌入式開發(fā)的支持卻相對薄弱,或缺乏跨平臺的支持,或缺乏一些開發(fā)功能;而對嵌入式開發(fā)支持較好的一些開發(fā)環(huán)境如Tornado又不提供源碼,不能根據需求更改功能[1,2]。嵌入式系統的交叉開發(fā)環(huán)境一般包括交叉編譯器、交叉調試器和系統仿真器等,并采用宿主機/目標機模式開發(fā)嵌入式應用軟件。國內外雖然對于嵌入式方向的研究和工程較多,但真正掌握核心開發(fā)技術、尤其是完全掌握交叉開發(fā)流程的公司和個人卻是少數。
在對通用的開發(fā)環(huán)境進行研究后,本文針對上述缺陷,提出對當前嵌入式集成開發(fā)環(huán)境的改進方案,并且在Eclipse框架的基礎上進行了實現。本文旨在研究并實現能夠在x86宿主機上交叉開發(fā)MIPS架構、龍芯3A 處理器的目標機上應用程序的集成開發(fā)環(huán)境。在開發(fā)環(huán)境中,不僅實現了基本的程序構建功能,為嵌入式工具鏈提供了健全的支持,同時還設計了一系列開發(fā)和測試工具,改進了編譯方式,提高了開發(fā)效率,能夠在一定程度上縮短開發(fā)周期、降低成本。
本文基于項目是面向MIPS架構的龍芯3A 硬件平臺的嵌入式操作系統及集成開發(fā)環(huán)境的研發(fā)。進行交叉開發(fā),必須在開發(fā)環(huán)境中集成目標機操作系統的一系列和編譯鏈接相關的文件。本項目中目標機上運行的特定嵌入式實時操作系統,也是由項目組開發(fā),如圖1 所示為基于Rtems內核的嵌入式實時操作系統的架構圖,分為4層結構:硬件抽象層、核心層、系統服務層和應用服務層[3]。硬件抽象層主要是和體系架構相關的驅動支持軟件;核心層由一系列核心組件組成,包括實時任務調度、內存管理系統、IO 系統等模塊組成;系統服務層主要完成給各種應用提供操作系統級的服務支持,包括VxWorks、Posix、Classic 3種API(application programming interface)的支持;應用服務層主要提供TCP/IP協議棧、GUI系統、文件系統等組件[4,5]。Rtems內核具有支持多任務,支持事件驅動、基于優(yōu)先級搶占的調度算法和具有快速響應的中斷管理等優(yōu)勢。
操作系統為上層應用程序的編寫提供了一套API,但由于不是在目標機上直接開發(fā)應用程序,在宿主機上就需要提供目標機操作系統的各類鏈接庫文件和頭文件等[6]。將這些系統文件集成于開發(fā)環(huán)境目錄之下,根據目錄組織結構,設計開發(fā)環(huán)境的路徑解析和文件查找功能,在構建程序時自動或手動去查找所需要的文件。
圖1 嵌入式實時操作系統基本架構
根據各層的實現原理及關系,將操作系統源文件在Cygwin下編譯成一系列的庫文件和可執(zhí)行文件,供開發(fā)環(huán)境在程序構建過程中調用。如圖2所示即為開發(fā)環(huán)境中操作系統相關的主要文件目錄樹,其中Tyche目錄下為程序構建過程中所需要的文件總目錄,三級子目錄tyche中是操作系統核心文件,里面主要包含了工具鏈的二進制文件(bin)、系統頭文件 (include)、C/C++庫、系統庫文件(lib)、makefile模板文件 (make)、說明手冊 (man)等。
圖2 開發(fā)環(huán)境中操作系統相關文件目錄
CDT (C/C ++development tool)是一套開源的Eclipse的插件,用于對C/C++程序開發(fā)的支持。由于Eclipse平臺強大的功能及友好的界面和特性,Java開發(fā)人員也想將這些優(yōu)秀的性能提供給C/C++開發(fā)人員。CDT對Windows平臺和Linux 平臺均提供了支持,并且由于Eclipse的插件結構形式,使得外部插件能夠無縫連接到Eclipse內核中。本項目以最新的版本CDT8.2為基礎進行研究,開發(fā)特定目標機平臺的集成開發(fā)環(huán)境,相比較其他平臺的集成開發(fā)環(huán)境,不僅擁有其已有的功能,同時還設計實現了一些新的功能,豐富了開發(fā)環(huán)境的輔助功能。
由于其復雜性,CDT 被分成了許多組件,他們都采用獨立插件的形式開發(fā),高度包含了面向對象的設計思想,從底層到高層的實現都秉承了高內聚、低耦合的設計原則,使得組件功能的擴展和刪除都相當清晰。CDT8.2 包含了幾十個獨立插件,然而核心插件及功能描述見表1。
表1 CDT 的核心插件與功能描述
CDT8.2 提供了對GNU、Cygwin、MinGW、Visual Studio等一系列工具鏈的支持,并且集成了工程創(chuàng)建管理、工程構建、調試和目標機狀態(tài)查看等C/C++程序開發(fā)的配套功能。然而由于本項目中目標機平臺的特殊性,CDT本身沒有提供對MIPS架構目標機的支持,所以不能夠直接使用CDT,需要進行2次開發(fā)以實現開發(fā)環(huán)境對C/C++的支持。
開發(fā)環(huán)境的核心功能之一就是工程管理,而其中的難點就在于實現在開發(fā)環(huán)境中指定程序的構建方式。因為在編寫大型應用程序的時候,往往需要面對復雜的編譯過程和大量的源代碼文件,該過程中需要處理配置選項、多種格式的輸入輸出文件、確定文件間復雜的依賴關系,同時還需要應對工程的反復修改編譯[7]。工程上常用Makefile和make工具來實現程序自動構建的過程,但在開發(fā)大型程序時,如果程序員手動去編寫所有的Makefile文件及組織相應的目錄,人工地分析上述的輸入輸出文件及依賴關系將會使開發(fā)過程變得更為繁瑣、開發(fā)效率極為低下,而且在后續(xù)的開發(fā)過程中工程文件將難以維護。特別是在嵌入式系統中,由于環(huán)境變量配置復雜,所需的庫文件沒有良好支持,極易導致編譯或鏈接錯誤,因此在集成開發(fā)環(huán)境中提供工程的自動管理和構建功能,即自動生成Makefile,就顯得十分必要[8]。
所需自動生成的Makefile共有4種:SubDir.mk、Objects.mk、Sources.mk 和 Makefile[9]。其中前3 種為子Makefile文件,最后一個為主Makefile,主Makefile中用include語句包含了前3種子Makefile。CDT8.2中各Makefile文件對應的功能和實現函數如下:SubDir.mk用于聲明各級子目錄模塊的源文件和依賴關系,生成SubDir.mk的函數名為populateFragmentMakefile;Objects.mk用于聲明生成的所有目標文件名和庫文件名,生成函數名為populateObjectsMakefile;Sources.mk用于聲明依賴的源文件及子目錄名稱,生成Sources.mk 的函數為populateSources-Makefile;生成主 Makefile 的函數為populateTopMakefile[10]。
開發(fā)環(huán)境中Makefile的生成流程,如圖3所示。
圖3 開發(fā)環(huán)境中Makefile的生成流程
項目中為了不破壞源代碼的封裝性和擴展性,保留了CDT 中這些接口函數的名稱,而重構了其實現方式,以生成Rtems操作系統下的Makefile文件。第1步,首先開發(fā)環(huán)境能夠自動為用戶工程配置大部分環(huán)境變量和編譯鏈接選項,圖形化的配置界面也能讓用戶自行配置一些其他選項,在Makefile的生成過程中,會先獲取這些配置信息并保存在相應的數據結構中,通過解析這些配置信息并根據模板編譯規(guī)則生成一條條的編譯命令,在后續(xù)過程中寫入Makefile。第2步,遍歷工程目錄下的所有文件,獲得工程文件的目錄樹,再根據文件后綴名判定是否為可編譯的源文件,若為可編譯的源文件則寫入Makefile中的對應位置,生成依賴關系。最后將第1步中自動生成的編譯命令寫入Makefile,完成所有Makefile,隨后調用make 工具,將Makefile中的命令傳遞給編譯器和鏈接器執(zhí)行,生成目標文件,完成工程的整個構建過程。
開發(fā)環(huán)境以良好的面向對象編程方式封裝數據和接口,既繼承了Eclipse和CDT 已有的優(yōu)良特性,又包含了新增的功能,從而實現了開發(fā)環(huán)境中的工程管理功能,無需開發(fā)者自行去分析工程目錄、工程配置信息和文件修改記錄,能夠自動編寫Makefile文件并生成相應的編譯命令,使得工程管理的難度明顯下降,從開發(fā)方式來說也符合軟件工程的規(guī)范。
3.2.1 編譯鏈接
如圖4所示,為項目中實現的應用程序構建流程。程序的構建過程從新建模板工程向導開始,在編輯器中編輯好源代碼后,開發(fā)環(huán)境會自行調用C/C++Parser和Codan工具檢查代碼語法和格式,之后根據用戶操作執(zhí)行工程的構建過程。
圖4 開發(fā)環(huán)境中程序構建流程
開始執(zhí)行工程構建時,首先根據用戶設置自動構建工程的Makefile 文件,其實現方法上一部分已有介紹。Makefile文件只是寫入文件間依賴關系及編譯鏈接規(guī)則,真正完成程序構建的是匯編器、編譯器、鏈接器等一系列工具鏈。開發(fā)環(huán)境中提供了對2種工具鏈的支持,即Cygwin工具鏈和MinGW 工具鏈,絕大多數情況下使用的是在Cygwin環(huán)境下重新編譯的 MIPS 工具鏈。包括mipstyche3.6-as (匯編器)、mips-tyche3.6-gcc (編譯器)、mips-tyche3.6-g++ (編譯器)、mips-tyche3.6-ld (鏈接器)等,這些工具及相關文件都被放置到本文第1部分所提到的tyche/bin/目錄下,開發(fā)環(huán)境根據系統環(huán)境變量進行查詢和調用。對Makefile中的編譯規(guī)則和文件依賴關系進行解析后,開發(fā)環(huán)境將調用make工具將對應的命令傳遞給上述編譯工具,編譯工具根據需要的文件查找Tyche目錄下所需要的相關操作系統頭文件、庫文件以及工程目錄下的源代碼文件,最終生成目標機上可執(zhí)行程序。
3.2.2 增量編譯
在實現上,為提高工程的編譯效率,研究并在開發(fā)環(huán)境中實現了增量編譯功能。遍歷工程目錄下的所有文件,以接口類IResourceDelta保存工程文件目錄樹和配置信息的修改內容,再次構建工程時,獲取記錄的上一次編譯時的工程信息,與當前工程信息對比,從而確立了工程的修改內容,即增量,根據增量信息,重新生成Makefile。
程序構建時,先判定編譯方式是增量編譯還是完全編譯,如果是完全編譯 (通常為第1次編譯工程或者是用戶選擇完全編譯選項),則會先執(zhí)行工程清理過程,刪除當前工程目錄下所有Makefile和目標文件,再重新編譯所有的源文件。如果是增量編譯,就調用genrerateMakefiles 函數,其中用ResourceDeltaVisitor類的visit函數得到當前工程的IResourceDelta,即得到了工程內源文件和配置信息的修改記錄;第2步,判定修改方式是增加、刪除還是其他,并將這些信息告知Makefile的生成器,生成器遍歷已修改的文件,根據修改過的文件名稱和編譯依賴規(guī)則重寫Makefile,這樣在后續(xù)真正的編譯過程中就只會重新編譯修改過的源文件及其依賴的文件,而不會重新編譯未修改過的源文件。這樣就實現了增量編譯功能,避免了因為少量的源代碼修改而需要重新編譯整個工程的復雜過程,提高了編譯效率。
增量編譯過程及增量Delta的存儲結構,如圖5所示。
圖5 增量編譯過程及增量Delta的存儲結構
3.2.3 代碼檢查
程序開發(fā)過程中,源代碼自動檢查也是集成開發(fā)環(huán)境設計中一個重要的問題,一個用戶友好的開發(fā)環(huán)境必須提供較為完備的代碼檢查功能。Codan是一個非常優(yōu)秀的C/C++靜態(tài)代碼審查工具,將其與CDT 集成后,在編寫程序源代碼和工程編譯過程中,開發(fā)環(huán)境會自行調用Codan工具檢查代碼語法格式和進行邏輯分析,例如緩沖區(qū)溢出問題,就能夠被自動檢查出來,并在出錯位置以編輯器標記的形式輸出,建立控制臺輸出信息與源代碼位置的映射,實現錯誤代碼定位功能,以便于開發(fā)人員修改程序代碼。
Codan在實現上使用的是java的非確定型有窮自動機(nondeterministic finite automaton,NFA)引擎,這種正則引擎的特點是以表達式為主導,模式正則表達式在編譯時效率較高,需要內存小,盡管在匹配過程中使用回溯匹配的算法,但使用者可以直接操控匹配的過程。如圖6所示為NFA 引擎的一個匹配示例。
圖6 NFA 引擎狀態(tài)圖示例
在程序的編譯期,開發(fā)環(huán)境還需要獲取編譯器的所有輸出信息并以流的方式重定向到控制臺,對這些輸出的字符串信息進行處理,以特定的方式顯示出來。在字符串信息的處理上就采用了Codan的字符串處理函數,以java的NFA 正則表達式引擎基礎,根據模式正則表達式匹配編譯器輸出信息,從而準確高效地分辨出正常輸出、警告信息,錯誤信息,并以顏色標記的方式在控制臺輸出,為開發(fā)環(huán)境提供了完善的代碼查錯功能。
調試方式也是嵌入式開發(fā)不同于一般應用開發(fā)的一項。本項目在開發(fā)環(huán)境實現了3種程序調試下載方式,即ejtag調試方式、串口調試、網絡調試,為上層開發(fā)者提供了多種調試方式,可根據硬件條件的不同使用不同的調試下載方式。ejtag調試方式采用的是龍芯公司的ejtag仿真器鏈接目標機和宿主機,經開發(fā)環(huán)境下載調試目標機程序;網絡調試實現經網線連接的下載調試方式,為追求下載速度和實現的簡易,采用基于UDP 協議的TFTP 協議進行通信;串口調試方式則是使用串口線連接目標機與宿主機,采用RPC協議進行通信。
雖然調試方式有多種,但原理上大同小異。執(zhí)行調試指令的過程是,先將GDB debugger的命令轉化為機器更易處理的MI接口命令,MI是開發(fā)環(huán)境和調試接口交互的接口。之后發(fā)送給通信代理模塊,發(fā)送給目標機,經解析后傳遞給GDB server執(zhí)行,執(zhí)行的結果又以特定的通信協議返回給宿主機開發(fā)環(huán)境進行解析,最后在用戶界面顯示,從而實現程序的調試執(zhí)行[2]。
項目中使用的Debugger是在Cygwin環(huán)境下重新編譯生成的mips-tyche3.6-gdb,在編譯時給編譯器增加參數-g,就能夠在可執(zhí)行文件中加入調試信息,包括源代碼中變量描述定義信息,函數類型及參數信息等;在底層實現上實際上是調用ptrace系統調用獲取調試進程的運行狀態(tài),比如堆棧的使用情況、各種變量的值等;獲取的這些程序運行信息經過指定的通信協議封裝成數據包回傳給宿主機,并在開發(fā)環(huán)境中以MI接口解析數據,最終在開發(fā)環(huán)境的調試視圖中顯示變量的值、寄存器使用情況,實現了單步進入、單步跳過、單步回跳等功能。
調試代理原理如圖7所示。
圖7 調試代理原理
在調試功能的多次使用測試后,得到如表2 所示的3種調試下載方式特點的比較,3種調試下載方式各有優(yōu)劣。
表2 3種調試方式特點對比
測試環(huán)境由x86 宿主機、龍心3A 目標機及連接設備(包括網線、串口線、ejtag仿真器)組成。主要測試應用程序的開發(fā)流程相關功能。測試結果表明,開發(fā)環(huán)境能夠提供完整的工程創(chuàng)建、工程管理、編譯和調試等界面及功能,能夠根據工程修改信息進行增量編譯,節(jié)省編譯時間。應用程序可以多種方式下載到目標機上,因通信協議的不同下載速度有所差異,但均能夠保證程序正確運行,達到了豐富調試方式,改善既有功能的目的。
為適應高效高質量的嵌入式開發(fā)方式,本文對嵌入式開發(fā)流程進行了深入的研究,針對已有開發(fā)工具的不足,進行了2次開發(fā),設計并實現了特定MIPS架構目標機的交叉開發(fā)環(huán)境。開發(fā)環(huán)境目前已能夠滿足用戶開發(fā)及調試目標機上程序的需求,測試情況與設計相符,提供了友好的交互界面,在繼承Eclipse已有功能的基礎上,根據需求實現了針對MIPS平臺的工程管理、增量編譯及遠程調試功能,縮短了編譯時間,改善了工程管理方式,從而提高了上層開發(fā)人員的開發(fā)效率。下一步的工作中,將對開發(fā)環(huán)境進行完善,繼續(xù)擴展必要的輔助功能,包括多核支持,性能分析、目標機狀態(tài)監(jiān)測等。
[1]Kopetz H.Real-time systems:Design principles for distributed embedded applications[M].Germany:Springer,2011.
[2]Sriram S,Bhattacharyya SS.Embedded multiprocessors scheduling and synchronization [M].USA:CRC Press,2009.
[3]On-Line Applications Research Corporation.Getting started with RTEMS [S].2011.
[4]Andrew S Tanenbaum. Modern operating systems [M].USA:Prentice Hall,2009.
[5]Rafael V Aroca.A real time operating systems(RTOS)comparison [C]//Workshop de Sistemas Operacionais,2009:2441-2452.
[6]Tan S,Tran Nguyen B.Survey and performance evaluation of real-time operating systems(RTOS)for small microcontrollers[J].IEEE Micro,2009,99 (1):1-14.
[7]Randal E Bryant,David R O’Hallaron.Computer systems:A programmer’s perspective[M].USA:Prentice Hall,2010.
[8]Leupers R.Code optimization techniques for embedded processors:Methods,algorithms and tools [M].USA:Kluwer Academic Pubilshers,2010.
[9]NAN Fang.Embedded integration development environment analysis and design on Eclipse[D].Xi’an:Xidian University,2009 (in Chinese).[南方.基于Eclipse的嵌入式集成開發(fā)環(huán)境分析與設計 [D].西安:西安電子科技大學,2009.]
[10]WANG Yang.Embedded integrated development environment design and implementation on Eclipse [D].Chengdu:UESTC,2012 (in Chinese).[汪洋.基于Eclipse架構面向Linux的嵌入式軟件開發(fā)環(huán)境的設計與實現 [D].成都:電子科技大學,2012.]