劉國(guó)偉,陳宏君,劉克金
(南京南瑞繼保電氣有限公司,南京 211102)
嵌入式裝置可視化頁面程序代碼處理架構(gòu)設(shè)計(jì)
劉國(guó)偉,陳宏君,劉克金
(南京南瑞繼保電氣有限公司,南京 211102)
提出一種靈活的嵌入式裝置可視化頁面程序的代碼處理架構(gòu)。基于元件的層次模型,形成相關(guān)數(shù)據(jù)結(jié)構(gòu)和功能調(diào)用函數(shù)。通過在腳本中調(diào)用代碼生成器開放的接口,可定制形成不同運(yùn)行場(chǎng)景的代碼。通過擴(kuò)充解析預(yù)處理函數(shù),支持形成高效緊湊的代碼。采用通用模板替換的方法,可自動(dòng)形成多種處理器的編譯文件。本文提出的技術(shù)已經(jīng)在電力系統(tǒng)保護(hù)控制裝置開發(fā)中進(jìn)行了批量應(yīng)用,顯著提升了開發(fā)效率和質(zhì)量。
嵌入式裝置;可視化編程;代碼生成;編譯
引 言
嵌入式裝置是嵌入對(duì)象系統(tǒng)中用于執(zhí)行獨(dú)立功能的專用計(jì)算機(jī)[1], 早期由于硬件資源和性能約束,一般用匯編語言或語言開發(fā)應(yīng)用程序。隨著硬件性能的提升, 圖形化編程、可視化調(diào)試成為一種可行趨勢(shì)[2-6]。面向?qū)ο蟮膱D形化軟件開發(fā)方法,用圖形化功能塊搭建程序,以直觀方便、易于理解的方式構(gòu)建應(yīng)用程序功能,在電力系統(tǒng)保護(hù)測(cè)控中得到了應(yīng)用[7-9]。在可視化編程使用過程中,面臨硬件平臺(tái)更新?lián)Q代周期加快、系統(tǒng)軟件的接口可能發(fā)生變化、支持嵌入式裝置運(yùn)行和PC機(jī)虛擬仿真等環(huán)境切換、提升代碼運(yùn)行效率等挑戰(zhàn),需要設(shè)計(jì)靈活高效的代碼生成和處理架構(gòu),提升可視化編程的靈活性、可靠性。
圖1 嵌入式平臺(tái)分層架構(gòu)
如圖1所示,嵌入式控制保護(hù)平臺(tái)由三大部分組成:硬件平臺(tái)、系統(tǒng)軟件、可視化編程軟件[2]。在平臺(tái)的最上層,就是基于平臺(tái)開發(fā)的各種裝置應(yīng)用程序,UAPC(統(tǒng)一的控制保護(hù))平臺(tái)+應(yīng)用功能就構(gòu)成一個(gè)完整的控制保護(hù)系統(tǒng)。本文的可視化編程軟件作為UAPC控制保護(hù)平臺(tái)的一部分,是銜接應(yīng)用和底層軟件的橋梁,對(duì)下屏蔽了不同版本硬件和系統(tǒng)軟件的接口差異,對(duì)上則需適配不同應(yīng)用場(chǎng)景的開發(fā)需求。各個(gè)方向的應(yīng)用基于通用符號(hào)庫和應(yīng)用符號(hào)庫來開發(fā)圖形化程序。編程軟件分析圖形化頁面,形成嵌入式裝置代碼和配置文件,并調(diào)用編譯器編譯形成目標(biāo)文件。
參考IEC61131-3的概念定義[10],采用層次數(shù)據(jù)模型組織整個(gè)裝置的程序結(jié)構(gòu)。
如圖2所示,可視化層次數(shù)據(jù)模型設(shè)計(jì)如下:
① 裝置:相當(dāng)于IEC61131-3標(biāo)準(zhǔn)定義的可編程控制系統(tǒng),位于軟件模型最上層,裝置是1個(gè)特定類型的控制系統(tǒng),包括硬件、處理資源、I/O通道、運(yùn)行的程序,反映了可編程控制器的物理結(jié)構(gòu),裝置包括若干插件。
② 插件:位于軟件模型的第2層,為運(yùn)行程序提供支持系統(tǒng),為程序和I/O通道提供界面和接口,提供一個(gè)支持系統(tǒng)運(yùn)行的程序,其中具有多核處理器的插件可加裝、啟動(dòng)、運(yùn)行多個(gè)獨(dú)立的程序,插件包括若干元件。
③ 元件:完成特定應(yīng)用功能的面向?qū)ο蟮囊唤M數(shù)據(jù)和對(duì)數(shù)據(jù)進(jìn)行處理的過程,處理后輸出的數(shù)據(jù)供其他元件進(jìn)一步使用[9]。元件包含輸入、輸出和參數(shù)等外部接口,由若干等級(jí)任務(wù)組成,可把插件的程序拆分為粒度適中的若干元件。
④ 任務(wù):用于規(guī)定程序組織單元在運(yùn)行期的特性,是一個(gè)執(zhí)行控制元素,具有調(diào)用能力,可周期或事件觸發(fā)執(zhí)行,包括若干程序頁面。在可視化工程中,采用圖形化任務(wù)鏈來設(shè)置頁面等級(jí)和執(zhí)行順序,通過元件執(zhí)行鏈來設(shè)置元件實(shí)例的執(zhí)行順序。
⑤ 頁面:由庫元件、符號(hào)和符號(hào)之間輸入-輸出數(shù)據(jù)連線組成,頁面功能形成1個(gè)函數(shù),可添加到任務(wù)隊(duì)列,通過繪制圖形化符號(hào)和數(shù)據(jù)連線搭建應(yīng)用邏輯。
圖2 可視化層次數(shù)據(jù)模型
支持以元件、插件、裝置為單位形成代碼??梢暬a生成主要步驟為:前端模塊讀取可視化工程和符號(hào)庫,形成可視化頁面內(nèi)存數(shù)據(jù)模型;對(duì)頁面符號(hào)進(jìn)行拓?fù)渑判颍纬煞?hào)調(diào)用執(zhí)行順序;啟動(dòng)腳本執(zhí)行引擎,在腳本中可獲取符號(hào)的屬性,腳本執(zhí)行后將數(shù)據(jù)存儲(chǔ)到中間件;后端模塊組織文本段落,輸出代碼文本;最后形成Makefile,并調(diào)用不同CPU/DSP的編譯器,形成目標(biāo)文件。
在設(shè)計(jì)時(shí),代碼生成工具面臨兩個(gè)挑戰(zhàn):一是相同的可視化程序會(huì)在不同的環(huán)境下運(yùn)行,例如嵌入式裝置、Windows的PSCAD仿真軟件、Linux的Hypersim仿真軟件,這些場(chǎng)景下的數(shù)據(jù)對(duì)象、代碼文件組織方式有差異(嵌入式裝置以插件為單位編譯,PC機(jī)仿真以裝置為單位編譯,需增加前綴處理重名、增加插件間連線代碼等),支持一種新的應(yīng)用場(chǎng)景時(shí),不能影響已經(jīng)穩(wěn)定的模塊。二是形成的代碼文本中有系統(tǒng)軟件的接口函數(shù),當(dāng)系統(tǒng)軟件升級(jí)時(shí),盡量不修改組件源代碼,需提高靈活性。通過采用加載不同后端產(chǎn)物生成組件方式實(shí)現(xiàn)平滑切換,采用腳本定義符號(hào)行為的方式來實(shí)現(xiàn)和底層軟件的解耦。代碼生成整體處理架構(gòu)如圖3所示。
圖3 代碼生成處理架構(gòu)
3.1 元件代碼模型
圖4 元件代碼文件結(jié)構(gòu)
可視化元件對(duì)應(yīng)一個(gè)h、c文件。如圖4所示,在h文件中定義元件數(shù)據(jù)結(jié)構(gòu)體(包括輸入變量、輸出變量、參數(shù)、內(nèi)部變量)和聲明接口函數(shù),在c文件形成庫函數(shù)、頁面函數(shù)、任務(wù)調(diào)用函數(shù)、元件構(gòu)造、元件初始化函數(shù)。在元件構(gòu)造函數(shù)中分配數(shù)據(jù)結(jié)構(gòu)體,并調(diào)用系統(tǒng)接口注冊(cè)接口變量信息;在初始化函數(shù)中完成變量初始化,并將任務(wù)函數(shù)添加到任務(wù)隊(duì)列中。
以一個(gè)過壓元件為例, 其形成的數(shù)據(jù)結(jié)構(gòu)體示例如下:
struct OverVoltage {
#include"basecomp.h"
unsigned short* UA; //A相電壓
unsignedshort* UB; //B相電壓
unsignedshort* UC; //C相電壓
unsigned char FD; //啟動(dòng)
unsigned char Op; //動(dòng)作
unsigned int U_Set; //電壓定值
intOpt_Curve; //延時(shí)特性
… };
在c文件中,依次形成newOverVoltage、initOverVoltage等函數(shù),例如在元件構(gòu)造函數(shù)代碼示例如下:
Component* newOverVoltage(void* parent, char* name){
OverVoltage* dp = calloc(1, sizeof(OverVoltage));
if(!dp)return NULL;
//調(diào)用系統(tǒng)平臺(tái)的注冊(cè)接口
defineComp(dp, parent, name);
defineIn(dp, &&dp->UA,"UA tp=us");
defineOut(dp, &dp->Op,"Op tp=uc");
definePara(dp, &dp->U_Set,"U_Set tp=ui");
……
return (Compoent*)dp;
}
代碼生成工具分析頁面中的輸入-輸出符號(hào),形成對(duì)應(yīng)變量定義、變量注冊(cè)代碼,分析庫元件、功能塊函數(shù)符號(hào)和連線,形成對(duì)應(yīng)的函數(shù)調(diào)用代碼。
3.2 數(shù)據(jù)中間件設(shè)計(jì)
為了能夠形成圖4模型的元件代碼,設(shè)計(jì)了代碼文本處理數(shù)據(jù)中間件,對(duì)h/c文件進(jìn)行了抽象建模,將文本的結(jié)構(gòu)分為如下幾類:
enum SemanticType{
SBASE_TYPE=0,
SINCLUDE_TYPE, //include
SCOND_COMPILE_TYPE, //條件編譯
SVAR_TYPE, //變量聲明
SMACRO_TYPE, //宏定義
SENUM_TYPE, //枚舉定義
SFUNC_TYPE, //函數(shù)聲明和定義
SSTRUCT_TYPE, //結(jié)構(gòu)體定義
SFILE_TYPE, //源文件定義
STEXT_TYPE, //各種代碼段
SOTHER_TYPE
};
其中STEXT_TYPE是代碼片段,又細(xì)分為頭文件定義段、變量定義段、本地函數(shù)段、頁面new函數(shù)段、頁面init函數(shù)段、頁面運(yùn)行函數(shù)段、元件new函數(shù)段、元件init函數(shù)段等。其UML結(jié)構(gòu)如圖5所示。
圖5 數(shù)據(jù)中間件模型
將這些段落順次拼接匯總,形成元件的h/c代碼文本。代碼段定義為CSection類,包括若干前置代碼、函數(shù)代碼、后置代碼等,在文件實(shí)例中創(chuàng)建若干代碼片段,調(diào)用接口向相關(guān)段落中添加變量、函數(shù)等內(nèi)容。
3.3 腳本調(diào)用技術(shù)
基于跨平臺(tái)C++/QT開發(fā)的代碼工具,從QObject基類繼承的相關(guān)類可定義若干SLOT函數(shù),并向腳本引擎中注冊(cè)指針對(duì)象,從而腳本中可調(diào)用對(duì)象實(shí)例的SLOT函數(shù)(定義為API接口)。API接口提供可視化編程軟件的開放服務(wù)功能,在腳本中調(diào)用API來定義編程符號(hào)的代碼輸出內(nèi)容,通過這種解耦方式,應(yīng)用開發(fā)人員在不需要掌握平臺(tái)內(nèi)部工作細(xì)節(jié)的前提下,即可使用相關(guān)軟件或硬件接口,并且平臺(tái)升級(jí)時(shí),只需刷新符號(hào)塊,應(yīng)用程序頁面不需要修改。向腳本引擎注冊(cè)的對(duì)象有代碼生成器coder、裝置實(shí)例app、當(dāng)前處理的插件board、當(dāng)前處理的元件comp、當(dāng)前處理的頁面page、當(dāng)前處理的符號(hào)symb等。以1個(gè)PAM跳閘矩陣符號(hào)為例,腳本調(diào)用示例如下:
#set func code
pamna='PAM_'+pamid;
s=' '
s+='static void'+pamna+'()'
for i in range(num):
sidx=('%d'%(i+1))
if i<(num-1):
s+='Uint8 a'+sidx+','
if ((i+1)%5)==0:
s+=' '
else:
s+='Uint8 a'+sidx+') '
…
s+='} '
coder.cout(s,'LOCAL_FUNC')
3.4 提高運(yùn)行效率設(shè)計(jì)
嵌入式裝置由于實(shí)時(shí)性的要求,對(duì)程序運(yùn)行效率要求極高,可視化程序設(shè)計(jì)和處理中,可通過如下措施,盡可能地提高程序運(yùn)行效率:
① 高質(zhì)量的模塊化符號(hào)庫設(shè)計(jì)?;谒神詈?、高內(nèi)聚的原則,對(duì)各種保護(hù)測(cè)控功能進(jìn)行合理粒度的劃分,形成模塊名和功能定義。統(tǒng)一的標(biāo)準(zhǔn)子程序庫對(duì)常用的小模塊(如付氏濾波算法,延時(shí)算法等)進(jìn)行標(biāo)準(zhǔn)化函數(shù)庫設(shè)計(jì)和嚴(yán)格的性能、功能測(cè)試,通過集體評(píng)審和優(yōu)化,形成高質(zhì)量、高可靠、可重用的符號(hào)庫,則可視化頁面是高質(zhì)量的子程序的組合關(guān)系。
② 為了節(jié)省代碼空間,盡量將運(yùn)行代碼放入到片內(nèi)。通過合理設(shè)置ldf文件,并在元件頁面的任務(wù)函數(shù)前面指定section存放標(biāo)記,編譯鏈接時(shí)可最大程度地將運(yùn)行函數(shù)放入到片內(nèi)執(zhí)行。在節(jié)省代碼空間方面,支持將部分可視化頁面進(jìn)行組合封裝,形成復(fù)用庫,一處功能多處實(shí)例,調(diào)用相同的代碼,從而減少冗余代碼。
③ 在功能塊函數(shù)建模階段,定義函數(shù)原型代碼時(shí),擴(kuò)充條件預(yù)處理語句,在代碼生成階段處理相關(guān)語句,輸出條件對(duì)應(yīng)的分支代碼。引入并擴(kuò)充條件預(yù)編譯語句,定義#if、#elif、#else、#endif關(guān)鍵字,條件語句包含參數(shù)設(shè)置值的加減乘除四則運(yùn)算,并擴(kuò)充支持C庫函數(shù),開發(fā)了C預(yù)處理解析器,能計(jì)算含C庫函數(shù)的表達(dá)式。例如某個(gè)功能塊在初始化階段運(yùn)行的代碼是根據(jù)時(shí)間單位的設(shè)置情況決定變量的初始值。其示例如下:
#if( strcmp(time_unit, "USEC") == 0 )
{ time_intel = (int)time_val / 10; }
#elif( strcmp(time_unit, "MSEC") == 0 )
{ time_intel = (int)time_val * 100;}
當(dāng)time_unit的設(shè)置值為USEC時(shí),只形成如下代碼:
time_intel = (Uint32)time_val / 10;
避免采用if-else語句在運(yùn)行過程中進(jìn)行條件判斷,有效地提高了自動(dòng)生成代碼的執(zhí)行效率,并節(jié)省了代碼空間。
由于不同的編譯器其Makefile文件格式不同,如果每新增一種處理器就修改處理程序,存在工具軟件和硬件平臺(tái)緊耦合的問題。故設(shè)計(jì)了一種可配置模板的Makefile通用形成技術(shù),將配置模板分為如下幾段:
① Tool:編譯前調(diào)用的文件操作、目錄操作命令格式模板;
② Lib:需鏈接的系統(tǒng)庫,支持通配符替換;
③ Inc:依賴的頭文件查找目錄列表,提供一些默認(rèn)的文件目錄,并可擴(kuò)充新的目錄;
④ Flag:編譯選項(xiàng)、鏈接選項(xiàng);
⑤ Obj:需鏈接的二進(jìn)制目標(biāo)文件,不同編譯器文件后綴可不同;
⑥ Compile:執(zhí)行編譯過程命令鏈,依次包括形成單個(gè)c文件的obj、將obj文件鏈接為目標(biāo)文件、將目標(biāo)文件轉(zhuǎn)換為Hex文件的命令序列。
整個(gè)編譯鏈接過程如圖6所示。
圖6 編譯鏈接過程
基于通用模板方法,當(dāng)新增一種新的處理器時(shí),只需在配置目錄增加一份新的編譯模板,并在配置文件設(shè)置插件的處理器型號(hào)和模板文件的關(guān)聯(lián)關(guān)系,按照預(yù)定的關(guān)鍵字和通配符,代碼生成工具可自動(dòng)形成對(duì)應(yīng)的Makefile文件,實(shí)現(xiàn)了可靈活增加新的處理器型號(hào)。
[1] Elecia White.嵌入式系統(tǒng)設(shè)計(jì)與實(shí)踐[M].北京:機(jī)械工業(yè)出版社,2013.
[2] 李響,劉國(guó)偉,馮亞東,等.新一代控制保護(hù)系統(tǒng)通用硬件平臺(tái)設(shè)計(jì)與應(yīng)用[J].電力系統(tǒng)自動(dòng)化,2012,36(14):52-55.
[3] 王培進(jìn),李曉路.嵌入式系統(tǒng)集成開發(fā)平臺(tái)的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用與軟件,2012,29(5):10-13.
[4] 陳宏君,劉克金,馮亞東,等.新一代保護(hù)測(cè)控裝置配套工具軟件設(shè)計(jì)與應(yīng)用[J].電力系統(tǒng)自動(dòng)化,2013,37(20):92-96.
[5] 劉克金,陳宏君,馮亞東,等.新一代控制保護(hù)系統(tǒng)可視化編程軟件設(shè)計(jì)與實(shí)現(xiàn)[J].工業(yè)控制計(jì)算機(jī),2014,27(10):82-87.
[6] 陳宏君,馮亞東,文繼鋒,等.嵌入式程序動(dòng)態(tài)分配內(nèi)存的調(diào)試方案設(shè)計(jì)[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2015(9):18-21.
[7] 姚成,黃國(guó)方,周邵亮,等.軟PLC技術(shù)應(yīng)用于智能保護(hù)測(cè)控裝置的實(shí)現(xiàn)方案[J].電力系統(tǒng)自動(dòng)化,2010,34(43):115-117.
[8] 仲偉,丁寧,吳參林,等.圖形化編程的繼電保護(hù)平臺(tái)軟件平臺(tái)設(shè)計(jì)[J].電力系統(tǒng)保護(hù)與控制,2011,39(3):100-147.
[9] 陳宏君,熊蕙,文繼鋒.嵌入式系統(tǒng)面向?qū)?yīng)的多層次復(fù)用架構(gòu)[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2016(9):8-11.
[10] 彭瑜,何衍慶.IEC61131-3編程語言及應(yīng)用基礎(chǔ)[M].北京:機(jī)械工業(yè)出版社,2012.
[11] 馮亞東,劉克金,陳宏君,等.一種用于可視化編程的功能塊函數(shù)建模方法:中國(guó), 201210036681.8[P],2012-08-01.
劉國(guó)偉(高級(jí)工程師),主要研究方向?yàn)榍度胧狡脚_(tái)軟硬件開發(fā)和管理;陳宏君、劉克金(高級(jí)工程師),主要研究方向?yàn)榭梢暬幊誊浖_發(fā)。
Visual Graph Code Processing Architecture for Embedded Device
Liu Guowei,Chen Hongjun,Liu Kejin
(NR Electric Co.,Ltd.,Nanjing 211102,China)
In the paper,a flexible visualization program processing architecture for embedded device is proposed.Based on the hierarchy component model,the data structure and function call function are formed.By calling the open API interface in the script,the tool can be used to generate code for different application scenarios.By executing the preprocessing function,the tool supports the formation of highly efficient and compact code.Using the common template replacement method,the tool can automatically form a variety of processors compiled files.The technology has been applied in the development of power system protection and control devices,which significantly improves the efficiency and quality of development.
embedded system;visual graph coding;code generation;compile
TP393
A
士然
2017-01-03)