陳 攀,張承瑞,羅 映
1(山東大學 機械工程國家級實驗教學示范中心,濟南 250061) 2(山東建筑大學 機電工程學院,濟南 250101) E-mail:sduchenpan@163.com
隨著軟件工具的發展,自動代碼生成技術在工業控制[1]、汽車電子[2]、航天和導彈制導[3]等領域得到廣泛的應用.自動代碼生成相比于手工編程,能夠減少偶然的bug,減少重復勞動的時間,提高嵌入式系統的可靠性[4].在MATLAB/Simulink下,8051、飛思卡爾DSP563XX、英飛凌C166和ARM系列等芯片都有對應的toolbox支持,在創建MATLAB/Simulink模型后,通過RTW工具,可直接生成控制代碼.而外圍器件選型或布置等設計變化可能導致用戶不能直接通過工具生成代碼.為了滿足不同項目的嵌入式控制器的設計需求,需要根據MATLAB/Simulink和RTW的工作原理,結合實際需求設計代碼生成工具,進而使代碼的生成符合預期,同時提高代碼質量.本文從RTW的工作原理出發,以飛思卡爾S12X系列單片機為例,利用COM技術連接MATLAB/Simulink與CodeWarrior IDE,整合驅動層與應用層,最后實現自動代碼生成,并且代碼無需手動修改,能夠直接下載到目標板上.
RTW(Real-Time Workshop)是基于Simulink的代碼自動生成環境.Simulink軟件生成一個包含框圖執行語義的高級表示文件——model.rtw文件.model.rtw文件是一個ASCII格式數據庫,其中的內容描述了Simulink模型中的各個塊的包括屬性名稱和屬性值等.目標語言編譯器(TLC)讀取model.rtw文件并將其轉換為內部表示,并根據其他模塊TLC文件等修改最初的model.rtw文件.在RTW下能直接從Simulink的模型中產生優化的、可移植的和個性的代碼,并根據目標配置自動生成多種環境下的程序[5].RTW環境下的代碼生成過程有如下四個部分:
1)RTW讀取模型文件model.mdl,生成模型的描述文件model.rtw,該文件以ASCII碼存儲;
2)TLC讀取model.rtw,并根據的系統TLC與模塊TLC文件,生成指定目標的代碼,如ANSI C/C++代碼;
3) RTW代碼生成器根據給定的模型,將makefile模板生成具體的makefile文件(model.mk),該文件可修改用于生成可執行文件的C/C++編譯器及編譯選項;
4)連接model.mk與運行時的接口支持文件,將代碼編譯成可執行的文件[6].

圖1 RTW工作過程Fig.1 RTW working process
MATLAB通過ActiveX自動化管理其他ActiveX組件或者被其他ActiveX組件所控制.ActiveX是Microsoft公司推出的基于組件對象模型(Component Object Model,COM)的一種技術,他使各種軟件組件可以在網絡環境中相互作用,而不管這種組件是使用什么語言編寫的.當MATLAB受到其他ActiveX組件控制時,充當了自動化服務器,ActiveX組件則是自動化客戶機[7].而實際上ActiveX是商標名稱,COM才是技術名稱.
COM是微軟公司提出的以組件為發布對象的軟件開發技術.組件對象模型(COM)是Windows對象的二進制標準.為Windows提供了統一地、面向對象的、可擴充的通訊協議.這意味著描述一個對象的可執行代碼(.dll或.exe文件的代碼)可以被其他對象執行[7].得益于COM具有與語言、平臺無關的特征,MATLAB的m函數可以基于COM標準與CodeWarrior IDE通訊,然后控制程序生成的過程.
在MATLAB下編寫m函數使用COM技術,可通過MATLAB的ActiveX支持調用必要的方法來調用CodeWarrior IDE.通過COM技術,可以實現調用CodeWarrior(例如,啟動一個新的CodeWarrior會話);打開CodeWarrior MCP項目文件;刪除舊的目標文件;構建項目以創建二進制文件;下載并執行目標板上的二進制文件.
嵌入式軟件架構的設計,可以按如圖2分為三層:微控制器層、設備接口層、邏輯應用層.微控制器層負責硬件的初始化和頭文件定義等內容;設備接口層,封裝驅動接口,供邏輯應用層調用.這兩層都在CodeWarrior IDE編寫,根據需要用C語言編寫IO驅動和通信驅動,封裝接口并測試,作為工程模板;最后的邏輯應用層在MATLAB/Simulink下編寫.邏輯應用層通過相關的UI模塊處理設備驅動層的接口,同時負責邏輯與應用的搭建.

圖2 軟件框架設計Fig.2 Design of software framework
在MATLAB/Simulink中,驅動UI模塊與設備驅動一一對應.驅動UI模塊的功能是在RTW程序創建過程中將驅動程序內嵌到模型源代碼中.驅動UI驅動的建立有兩種思路:一種是用TLC語言處理寄存器配置等底層硬件驅動,后生成C代碼;另一種是通過MATLAB配置相關的參數,后調用相關的驅動函數,生成階段只負責整合.采用第二種思路編寫驅動,可以在IDE編寫底層驅動庫[8],便于對已有的產品代碼進行重構,更能適應新的需求[9],而TLC文件處理相關的接口即可.對于TLC語言不熟悉的硬件工程師而言,采用第二種方式能減少編寫TLC文件的工作量,提高效率.
驅動模塊的建立需要先創建代表硬件的S函數,通過在與S函數對應的UI模塊上定義參數,例如外設寄存器地址、采樣時間等,將這些參數傳遞到RTW文件中去.實際的驅動接口相關的函數寫在S函數同名的TLC文件中.驅動模塊的建立可以分為兩個部分,第一步,模型階段,處理模型相關的模塊noninlined C MEX S-Function,此時創建的S函數模塊只能用于仿真而不能用于生成代碼;第二步,RTW階段,編寫TLC文件,用來定制RTW,為系統模型生成實時C代碼.最后通過MEX指令生成Inlined S-function(內聯S函數).
對于I/O驅動模塊的設計,具體的過程包含如下四個階段:
1.UI模塊界面設計,根據模塊參數及輸入輸出來設計模塊的配置參數,對于AI模塊可以設計電壓、電阻、電流模式參數,分辨率參數、通道參數等配置選項,UI界面的參數會傳遞到接下來編寫的S-Function中;
2.編寫模塊S-Function,通過修改Simulink Library提供的S-Fuction Example中提供的合適的S-Function模板,使得在RTW的程序創建過程中能將自定義的模塊程序嵌入到模型源代碼中,注意,此時創建的S函數模塊只能用于仿真而不能用于生成代碼;
3.編寫TLC文件,需設計模塊TLC文件用于定制模塊程序,TLC文件通過獲取模塊中的參數值來定制驅動程序并將其嵌入到自動生成的模型源代碼中,一般TLC文件負責制定的I/O宏定義、變量定義、code庫等內容和硬件初始化等,按照本文的軟件結構,TLC文件以接口處理為主.
4.模塊整合,調用命令mex生成內聯S函數,最后將目標硬件驅動程序封裝成靜態庫:調用sblock函數,封裝并加入Simulink庫,供系統邏輯應用調用.
系統設計不僅僅負責main主函數生成,還為COM技術的使用和整個自動代碼過程服務.目標系統通過系統文件(TLC)和hook文件把mdl轉換成c/h文件,而其余文件輔助這個過程.系統級設計包含系統目標文件、hook文件和腳本文件[10],過程如圖1所示.
1) 系統目標文件用于設置代碼生成的參數及目標硬件相關的專用數據.可以設置一些最基本的內容,配置代碼生成格式、類型、語言等內容,一般用于對目標系統的各種參數進行默認配置;
2) hook 文件用于對代碼生成的各個階段對自定義操作的處理.hook文件的設計用于在代碼生成過程中hook文件的執行分為表1六個階段,貫穿了整個RTW的程序創建過程.根據實際需要可設計與修改各階段的內容.
表1 RTW 創建過程
Table 1 RTW creation process

階段創建過程entry自定義目標進行預配置,參數配置檢驗before_tlc調用目標語言編譯器TLC自動生成模型源代碼after_tlc自動生成創建目錄的信息文件,并將其放在創建的文件夾中before_make生成程序創建過程必須的庫文件after_make更新創建信息對象exit調用COM組件來處理代碼整合
3)腳本文件用于創建訪問實例,通過COM組件在MATLAB中實現對編譯器的操作.首先用MATLAB注冊函數actxserver(′CodeWarrior.CodeWarriorApp′)創建CodeWarrior的COM對象,返回句柄,然后再通過COM接口來執行將基于模型的.c和.h文件添加到CodeWarrior的工程中,接著進行編譯,最后根據設置執行程序下載等命令.
項目開發一款飛思卡爾S12X系列MC9S12XEP100為主控芯片的控制器,具備AD采集、數字DA、電流測量、時間測量、PWM輸出、高低邊功率輸出、CAN、LIN、RS232和RS485,10種通用I/O功能.以AD采集模塊為例,說明硬件模塊在MATLAB/Simulink下程序整合的過程.對無操作系統的嵌入式系統主要有兩種實現方式:循環輪轉和前后臺系統,程序是基于時間的循環輪轉系統.AD5V代表最大量程5V.按照圖2的分層思路,AD5V在底層進行封裝,并留出初始化接口函數和獲取電壓接口函數:
ret_t ecmad5VddiInit (uint16_t Channel,int mode);
int32_t ecmAI5ddiGetVol(uint16_t Channel);
以初始化為例,在TLC文件中將如圖3的AD模塊中的配置參數(Supply項為標記不與形參對應)傳遞給接口函數
%assign Channel=CAST("Number",SFcnParamSettings.Channel)
%assign Mode=CAST("Number",SFcnParamSettings.Mode)
%assign Supply=CAST("Number",SFcnParamSettings.Supply)
/* S-Function "INIT_ad5V" initialization Block:%
ecmad5VddiInit(%

圖3 AD 模塊Fig.3 AD module
配置面板中選擇創建的系統TLC文件作為System target file,代碼生成的默認選項與系統TLC設置對應.通過系統TLC設置,可提供代碼生成后編譯、下載或無操作的選項.

圖4 MATLAB/Simulink測試模型Fig.4 Test model in MATLAB/Simulink
搭建如圖5所示MATLAB/Simulink測試模型,通過PIT定時模塊設置定時任務[11],I/O模塊采集信號并進行邏輯運算并輸出.硬件驅動模塊在底層IDE工具中完成,在MATLAB/Simulink模型初始化時,獲取工程模板文件路徑;系統編寫通過修改對應部分的系統TLC文件和M文件完成,利用COM技術,實現對CodeWarrior的生成控制.

圖5 自動代碼生成的工程文件Fig.5 Project of automatic code generation
運行“build model”,新生成的工程會新增如圖5“Sources”文件夾下的多個文件,其中s12x100_main,程序的main文件;model.h/c包含模型數據模型算法邏輯,是程序入口與核心,其他文件與宏定義結構體等有關.“model”代表模型的實際命名,工程目錄中為“Interrrupt_led”.另外,若需要進一步優化代碼,提高模塊重用性,提升代碼簡潔性等,需要在配置參數界面內設置.
MATLAB作為現在重要的工具軟件,深入探究其RTW工作的原理,結合COM技術,成功實現代碼的生成代碼與底層的整合.合適的軟件結構設計,合理的工作分工,能夠提升開發的效率,并減少了TLC代碼的工作量,更加符合一般硬件工程師開發習慣.對于自動代碼生成的研究,對于快速原型開發和V流程設計有較好的借鑒意義.
[1] Guo Xiao-qiang,Zhao Gang,Huang Kun.Auto-generation of TI C2000 DSP code on MATLAB/simulink bench[J].Science Technology & Engineering,2011,11(13):2941-2944.
[2] Hong Xiao-jun,Zhu Lei.Vehicle controller rapid prototype based on the automatic code generation technology on MATLAB/RTWEC [J].Mecha Tronics,2014,20(8):47-52.
[3] Yang Xiang,An Jin-wen,Cui Wen-ge.The research on application of embedded auto code generation[J].Journal of Projectiles Rockets Missiles & Guidance,2008,28(3):250-253.
[4] Guo Wen-sheng,Wang Yong,Yang Xia,et al.Codecomb:automated test case generation and defect detecting for embedded software based on symbolic execution[J].Journal of Chinese Computer Systems,2017,38(6):1250-1255.
[5] Yang Di.The environment and application of system real time simulation and development[M].Beijing:Tsinghua University Press,2002:32-37.
[6] Liu Jie,Weng Gong-yu,Zhou Yu-bo.The design of the model-MCU[M].Beijing:Beihang University Press Based on,2011:152-218.
[7] Zhang De-feng.MATLAB and external programming interface programming [M].Beijing:Machinery Industry Press,2009:192-209.
[8] Ren Jia-li,Cao Hai-yan.Research of code auto-generation and integration for the embedded software[J].Journal of Taiyuan University of Technology,2013,44(4):518-521.
[9] Zhang Wei,Wu Yi-jian,Shen Li-wei,et al.Software product line evolution driven by source code changes[J].Journal of Chinese Computer Systems,2017,38(5):919-924.
[10] Feng Hui-zong,Zhu Peng,Jiang Jian-chun,et al.Research on driver code quick generation technology based on real-time workshop[J].Computer Application and Software,2016,33(3):226-228.
[11] Gong Wei-wei,Wang Rui,Li Xiao-juan.Modeling and validation of cognitive robot control behavior using uppaal [J].Journal of Chinese Computer Systems,2016,37(6):1279-1283.
附中文參考文獻:
[1] 郭小強,趙 剛,黃 昆.基于MATLAB/Simulink平臺下TI C2000 DSP代碼的自動生成[J].科學技術與工程,2011,11(13):2941-2944.
[2] 洪曉君,朱 磊.基于MATLAB/RTWEC自動代碼生成技術整車控制器快速原型開發[J].機電一體化,2014,20(8):47-52.
[3] 楊向忠,安錦文,崔文革.嵌入式自動代碼生成技術應用研究[J].彈箭與制導學報,2008,28(3):250-253.
[4] 郭文生,汪 勇,楊 霞,等.Codecomb:基于符號執行的嵌入式軟件測試案例自動生成與缺陷檢測[J].小型微型計算機系統,2017,38(6):1250-1255.
[5] 楊 滌.系統實時仿真開發環境與應用[M].北京:清華大學出版社,2002:32-37.
[6] 劉 杰,翁公羽,周宇博.基于模型的設計—MCU篇[M].北京:北京航空航天大學出版社,2011:152-218.
[7] 張德豐.MATLAB與外部程序接口編程[M].北京:機械工業出版社,2009:192-209.
[8] 任佳麗,曹海燕.嵌入式軟件自動代碼生成和代碼整合方法研究[J].太原理工大學學報,2013,44(4):518-521.
[9] 張 薇,吳毅堅,沈立煒,等.代碼變更驅動的軟件產品線演化方法[J].小型微型計算機系統,2017,38(5):919-924.
[10] 馮輝宗,朱 澎,蔣建春,等.基于RTW的驅動代碼快速生成技術研究[J].計算機應用與軟件,2016,33(3):226-228.
[11] 鞏衛衛,王 瑞,李曉娟.基于UPPAAL的認知機器人控制行為建模與驗證[J].小型微型計算機系統,2016,37(6):1279-1283.