《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 其他 > 業(yè)界動態(tài) > GCC編譯器在DCS組態(tài)軟件中的應(yīng)用

GCC編譯器在DCS組態(tài)軟件中的應(yīng)用

2008-03-26
作者:劉金龍

摘? 要:本文介紹了ConMaker編譯功能的設(shè)計與實現(xiàn),對ConMaker編譯器的各個子模塊的實現(xiàn)分別進行了說明,闡述了如何應(yīng)用GCC實現(xiàn)ConMaker的編譯功能。

關(guān)鍵詞:DCSGCC,編譯,編譯器

?

??? 北京和利時系統(tǒng)工程股份有限公司是以工業(yè)過程控制為基礎(chǔ)的企業(yè),公司2001年從德國3S公司引進了控制編程軟件CoDeSys。實踐證明,CoDeSys是一款符合IEC61131-3標(biāo)準(zhǔn)的、功能強大、運行效率較高的算法組態(tài)軟件" title="組態(tài)軟件">組態(tài)軟件。但是CoDeSys也存在著不足之處,如對組態(tài)人員計算機素質(zhì)要求較高,缺少參數(shù)回讀等DCS系統(tǒng)必備的功能。另外,由于知識產(chǎn)權(quán)保護等各方面原因,包括CoDeSys在內(nèi)幾乎所有商業(yè)化工業(yè)組態(tài)軟件的源碼都不公開,這在很大程度上制約了和利時公司在CoDeSys基礎(chǔ)上進一步改進和完善的空間,從而限制了公司產(chǎn)品發(fā)展的可持續(xù)性。

為了提高組態(tài)軟件的持續(xù)改進能力,實現(xiàn)控制組態(tài)軟件的完全自主化,增強企業(yè)的核心競爭力,和利時公司自主研發(fā)了適合DCS工程需求的自主化組態(tài)軟件ConMaker。

1? ConMaker系統(tǒng)介紹

ConMaker從可用性與易用性兩方面考慮,在結(jié)合和利時公司以往使用與開發(fā)DCS系統(tǒng)的經(jīng)驗,借鑒國外先進工控軟件優(yōu)點的基礎(chǔ)上開發(fā)的新一代組態(tài)工具。ConMaker系統(tǒng)分為4個主要部分:

(1)???? 算法編輯界面

??? 算法編譯界面包括圖3-2-1中的算法編輯(ST, CFC, LD)、變量定義、硬件配置和庫管理器。用戶可以通過ConMaker友好的編輯界面,使用IEC61131-3標(biāo)準(zhǔn)中定義的語言進行工藝算法邏輯的編寫、工程任務(wù)的配置、DP等硬件的配置及工程輔助信息的填寫。

(2)???? 編譯與執(zhí)行

??? 編譯與執(zhí)行部分包括預(yù)編譯和編譯。編輯好的組態(tài)算法通過ConMaker編譯模塊進行編譯。編譯過程先檢查組態(tài)算法的邏輯錯誤,在進行組態(tài)的預(yù)編譯和編譯、鏈接、裝載和代碼整理,最后根據(jù)配置文件生成特定格式的二進制代碼。編譯模塊配合通訊模塊可實現(xiàn)組態(tài)工程的全下裝、增量下裝、強制、參數(shù)回讀等功能。

(3)???? 通訊與在線監(jiān)視

??? 通訊與在線監(jiān)視部分包括參數(shù)回讀、下裝、在線、網(wǎng)絡(luò)變量和通訊。ConMaker的通訊模塊可將編譯好的二進制代碼下裝到控制器上,并可周期讀取監(jiān)控點的實時值。ConMaker通訊模塊還可以對監(jiān)控的組態(tài)工程進行在線操作,如寫變量、強制、任務(wù)啟停等。

(4)???? 系統(tǒng)框架程序

ConMaker通過系統(tǒng)框架程序?qū)Ω?/SPAN>ConMaker模塊進行統(tǒng)籌管理,處理模塊間的消息傳遞。此外,ConMaker系統(tǒng)還提供了日志記錄、用戶管理、權(quán)限控制和支持主要功能點的快捷鍵操作等輔助功能,方便用戶對組態(tài)工程進行操控和管理。

2? ConMaker編譯功能的需求與分析

2.1? 編譯模塊功能需求

ConMaker的編譯功能需要實現(xiàn),對預(yù)編譯模塊從用戶組態(tài)的IEC算法轉(zhuǎn)換得到的邏輯等價的C語言描述文件進行編譯,生成二進制文件。具體實現(xiàn)的主要功能點有:

(1)????? ConMaker編輯界面定義的變量要分配在特定的內(nèi)存相對地址上。

(2)????? ConMaker支持任務(wù)調(diào)用、過程調(diào)用、函數(shù)調(diào)用和功能塊調(diào)用。

(3)????? 某站編譯成功后ConMaker會輸出該站的本次編譯相關(guān)信息。編譯相關(guān)信息包括:工程大?。?/SPAN>PRG文件大?。⒐灿卸嗌賯€POU參與編譯、分配在各內(nèi)存區(qū)域的變量所占空間、網(wǎng)絡(luò)變量數(shù)目、有參數(shù)回讀屬性變量所占空間等。

(4)????? 編譯并下裝后的進行在線監(jiān)視時可以進行讀寫變量、強制和強制釋放等操作。

(5)????? 編譯、下裝、強制、寫入等操作要記錄日志。

2.2? 編譯模塊需求分析

下面對ConMaker編譯功能的需求逐條分析,達到對ConMaker編譯模塊的詳細(xì)理解和剖析。

(1)???????? 由于ConMaker需要和RTS搭配使用,RTS中對下裝工程的變量所在的內(nèi)存區(qū)域進行了限制,在RTS中變量分為MemoryInput、Output、Retain、Global五類,各類所屬內(nèi)存彼此獨立,互相不重疊。在編譯過程中需要按照預(yù)編譯階段已經(jīng)指定好的各個變量的相對偏移,將各變量分配到指定的相對地址上。

(2)???????? 由于RTS采用函數(shù)指針列表的方式來實現(xiàn)函數(shù)的調(diào)用和訪問,所以在控制器上最終運行的機器碼只能只用函數(shù)相對地址調(diào)用的方式來實現(xiàn)。這就要求對C文件初步編譯生成匯編語言描述的.s文件進行二次處理,提取出其中函數(shù)訪問的部分,然后按照函數(shù)指針列表中的相對地址更新.s文件中函數(shù)調(diào)用部分(x86call***語句),并對函數(shù)返回值部分的指令做相應(yīng)處理。

(3)???????? 為實現(xiàn)ConMaker的強制功能,需要借助強制信息文件來記錄ConMaker中變量強制相關(guān)的信息。強制信息文件中包含PRG文件中可能會被真正強制的每一個變量的賦值語句的機器碼信息。

2.3? 選擇開源" title="開源">開源編譯器

ConMaker開發(fā)的關(guān)鍵技術(shù)之一就是編譯功能的實現(xiàn)。由于編譯器開發(fā)的代價太高,出于成本和風(fēng)險控制的考慮,在現(xiàn)有情況下可以利用開源的編譯器來實現(xiàn)ConMaker編譯功能,借助于開源編譯器實現(xiàn)ConMaker編譯功能積累的經(jīng)驗,對以后自主開發(fā)安全級編譯器也可起到很好的借鑒和幫助作用。

在選擇開源編譯器時ConMaker重點考慮編譯器生成目標(biāo)代碼的正確性、目標(biāo)代碼的高效性和編譯過程所用的時間?,F(xiàn)在較常用的開源編譯器有20多種,大多是由國外的高校和開源組織開發(fā)的。其中GCC是目前公認(rèn)的最穩(wěn)定、高效的開源編譯器,運行速度快,可實現(xiàn)多種高級語言、多種目標(biāo)代碼的交叉編譯,最重要的一點是使用GCC的項目和程序員非常多,經(jīng)過反復(fù)的測試、應(yīng)用和維護,GCC的正確性有了很好的保證。鑒于以上的情況,ConMaker選用開源編譯器GCC來實現(xiàn)其編譯功能。

3? ConMaker編譯功能的設(shè)計與實現(xiàn)

3.1? 編譯模塊體系結(jié)構(gòu)設(shè)計與子模塊劃分

ConMaker的系統(tǒng)結(jié)構(gòu)圖(圖4-1)中可看到,編譯模塊位于ConMaker的底層,主要與預(yù)編譯模塊和通訊模塊交互。編譯模塊中編譯預(yù)處理相關(guān)的操作與預(yù)編譯有緊密聯(lián)系,編譯后生成的PRG文件通過通訊模塊實現(xiàn)控制器下裝。

ConMaker編譯模塊的內(nèi)部,大體上可劃分為5個子模塊:

[1]????? 初始化處理模塊;

[2]????? 編譯預(yù)處理模塊;

[3]????? 編譯處理模塊;

[4]????? 相關(guān)配置數(shù)據(jù)生成模塊;

[5]????? 相關(guān)文件生成模塊。

ConMaker編譯器的子模塊劃分如圖4-1所示。

?

4-1ConMaker編譯器子模塊邏輯圖

3.1.1? 初始化子模塊

初始化子模塊主要完成兩個功能,一是用來實現(xiàn)通過ConMaker的配置文件(Target文件)對編譯模塊進行相關(guān)數(shù)據(jù)和編譯選項的設(shè)置;二是生成根據(jù)編譯配置生成一些獲取工程標(biāo)識號等ConMaker中必須有且功能固定的函數(shù)的二進制機器碼。

3.1.2? 編譯預(yù)處理子模塊

編譯預(yù)處理主要設(shè)置函數(shù)表信息和生成工程變量賦初值的二進制機器碼。

函數(shù)表信息包括工程中涉及到的每一個可能被調(diào)用的函數(shù)名稱、函數(shù)索引值、函數(shù)類型、函數(shù)代碼長度等信息。

由于ConMaker預(yù)編譯模塊生成的C文件中不包括各變量的初始化部分代碼,因此要實現(xiàn)變量賦初值需要額外生成賦初值的機器碼和重定位" title="重定位">重定位數(shù)據(jù),這部分代碼是無法借助GCC實現(xiàn)的。編譯預(yù)處理子模塊根據(jù)ConMaker預(yù)編譯模塊提供的變量表結(jié)合CPU類型生成變量賦初值的機器碼。

3.1.3? 編譯處理子模塊

編譯處理子模塊是ConMaker編譯的核心。經(jīng)過前期的準(zhǔn)備和預(yù)處理,對ConMaker組態(tài)算法邏輯等價的C文件進行編譯,這里需要ConMaker預(yù)編譯模塊保證C語言描述文件的詞法、語法和語義的正確性。

由于在編譯的過程中,需要調(diào)用GCC進行編譯,當(dāng)GCC編譯結(jié)束后ConMaker才能進行后續(xù)處理,因此需單獨啟用一個進程完成GCC的調(diào)用,當(dāng)GCC執(zhí)行結(jié)束后ConMaker進行后續(xù)的處理,在GCC執(zhí)行過程中ConMaker其它進程都處于等待狀態(tài)。

整個編譯過程分多步進行,包括匯編-〉修改匯編代碼-〉編譯-〉鏈接等。具體的處理過程如下:

3.1.3.1? 生成匯編文件

調(diào)用GCC編譯C文件生成匯編文件。從C文件到匯編文件的生成對編譯器而言是非常重要的一步,GCC在編譯C文件到匯編文件的過程中進行了詞法檢查、語法檢查、語義分析檢查、中間代碼生成、中間代碼優(yōu)化和目標(biāo)代碼生成幾步關(guān)鍵處理,首先將C文件經(jīng)過前端處理生成抽象語法樹AST(Abstract Syntax Tree),然后轉(zhuǎn)換成中間代碼的表示形式RTS(Register Transfer Language),最后經(jīng)代碼生成器生成最終的匯編語言描述文件。

3.1.3.2? 修改匯編文件

修改匯編代碼。如前文系統(tǒng)分析中提到的,要使GCC編譯生成的匯編文件能符合ConMaker 的編譯要求,需要修改匯編文件中函數(shù)調(diào)用語句的匯編代碼。

由于C語言的編譯和鏈接乃至運行過程中發(fā)生的與編譯相關(guān)的錯誤大多與函數(shù)調(diào)用約定(Call Convertion)有關(guān),所以這里我們對使用GCC的編譯方式和C文件的語法的限定作相關(guān)說明,保證ConMaker編譯、鏈接生成的目標(biāo)代碼的正確性,因此ConMaker需要修改GCC編譯生成的匯編文件中所有“call _函數(shù)名”格式的指令。

3.1.3.3 ?生成未重定位目標(biāo)代碼

調(diào)用GCC編譯修改后的匯編文件生成未重定位的目標(biāo)代碼。從匯編語言到機器語言的轉(zhuǎn)換主要工作是由匯編器完成的。GCC后臺調(diào)用的匯編器是as,as可編譯GCC生成的AT&T格式匯編語言得到目標(biāo)代碼,另外as可在生成的目標(biāo)代碼中包含被編譯程序的符號表,這可是ConMaker編譯模塊以后實現(xiàn)組態(tài)工程的調(diào)試功能打下基礎(chǔ)。

3.1.3.4? 連接

連接是編譯過程中很重要的一個環(huán)節(jié),連接負(fù)責(zé)的工作是為程序分配相關(guān)的地址和完成重定位以使編譯的程序可以在目標(biāo)機器上運行。在連接的過程中涉及到一些與其相關(guān)的概念。

重定位:編譯器和匯編其一般在建立目標(biāo)代碼文件的時候都令程序的地址從零開始,但很少有計算機允許你將你的程序加載" title="加載">加載到零地址。如果一個程序由多個子程序組成,所有的子程序必須被加載到不交叉的地址中。重定位就是為程序的各個部分分配加載地址,并調(diào)整程序的代碼和數(shù)據(jù)以反映已分配的地址的過程。在很多系統(tǒng)中,重定位發(fā)生不止一次。一個連接器從多個子程序建立一個程序并且從零開始連接輸出程序非常常見,多個子程序會重定位到大程序中的指定位置。之后在程序加載時,系統(tǒng)會決定實際的地址,連接后的程序會作為一個整體重定位到加載地址。

符號確定:當(dāng)一個程序由多個子程序構(gòu)成時,一個子程序?qū)ζ渌映绦虻囊糜煞枺?/SPAN>symbol)完成;一個主程序可能要用到一個稱為sqrt的平方根例程,而數(shù)學(xué)庫中定義了sqrt。連接器通過計算sqrt在庫中分配的位置并根據(jù)調(diào)用者的目標(biāo)代碼來修正這個位置,最后給call指令提供正確的地址。

加載:指將程序從其它存儲器復(fù)制到內(nèi)存中,另外還進行系統(tǒng)保護設(shè)置和將虛擬內(nèi)存地址映射到磁盤頁上等工作。

可完成連接功能的軟件稱為連接器,GCC使用的連接器是ld。像通常的連接器一樣,ld通過兩遍連接來完成連接工作的,以未重定位的目標(biāo)文件和連接腳本、調(diào)用命名參數(shù)為輸入,生成最終的目標(biāo)文件和其它輔助信息。

ld的第一遍連接運行時,先掃描輸入文件,以確定輸出目標(biāo)代碼中各段(Segment)的大小,收集所有符號的定義和引用,之后,ld建立一個輸入文件的框架圖并記錄輸入文件中包含的所有段信息和輸入文件的符號表。經(jīng)過第一遍的連接,ld可根據(jù)連接腳本文件為符號表中的需要地址分配的變量分配數(shù)值地址,確定輸出文件中包含的段及各段的大小和位置,最后標(biāo)記出輸出文件所包含的內(nèi)容。

ld第二遍連接使用了第一遍所收集的信息,用以確定實際的連接過程。它讀取并重定位目標(biāo)代碼,用符號引用來替換數(shù)值地址,并調(diào)整代碼和數(shù)據(jù)中的內(nèi)存地址以反映重定位段地址,最后將從定位代碼寫入到輸出文件中。接下來它寫出這個輸出文件,通常還要加上頭信息、重定位段和符號表信息。如果程序使用了動態(tài)連接,符號表還要包含能夠提供信息以供運行時連接器確定動態(tài)符號所需。在很多情況下,ld本身會在輸出文件中產(chǎn)生少量的代碼或數(shù)據(jù),諸如用于在復(fù)用或動態(tài)連接庫中調(diào)用例程的“粘貼代碼(glue?code)”,或者指向用于在程序開始時執(zhí)行的初始化例程的指針數(shù)組。

不論程序是否使用動態(tài)連接,輸出文件中都會包含一個符號表用以重新連接或調(diào)試,這個符號表并不會有程序本身使用,但是其他處理輸出文件的程序可能會用到。

ld工作的核心是重定位和代碼修正。為重定位目標(biāo)代碼中的代碼所使用的數(shù)據(jù)和定義的代碼通常是從0開始的,要使這些代碼被目標(biāo)機器運行需要進行重定位和修正目標(biāo)代碼以反映實際情況的地址分配。在連接過程中,一些指針等數(shù)據(jù)和指令也可能會進行重定位,所以代碼修正不僅影響到具體的某些指令,目標(biāo)文件的數(shù)據(jù)部分中的所有指針可能都同時需要調(diào)整。

ConMaker編譯模塊中,變量分為多種類型,不同類型變量分配的地址空間也不一樣,可通過連接腳本來進行具體控制。

3.1.4? 配置數(shù)據(jù)生成子模塊

ConMaker編譯組態(tài)工程最后生成的二進制文件中包含了一些工程配置信息,如組態(tài)工程中的硬件配置信息和任務(wù)配置信息、I/O點信息的數(shù)據(jù)都由配置數(shù)據(jù)生成子模塊實現(xiàn)。這些數(shù)據(jù)主要以信息說明為主,不包含組態(tài)邏輯部分。

任務(wù)配置信息的數(shù)據(jù)按照組態(tài)工程中設(shè)置的任務(wù)信息填充,包括任務(wù)數(shù)、任務(wù)名、任務(wù)周期、調(diào)用方式、看門狗設(shè)置等按固定的格式組織,以二進制數(shù)據(jù)形式存放在CI文件中。

ConMaker的硬件配置在硬件配置模塊處理,生成二進制格式數(shù)據(jù),在編譯過程中被編譯模塊的配置數(shù)據(jù)生成子模塊獲取填入到CI文件中。

I/O點信息數(shù)據(jù)是組態(tài)中參與運算的I/O點的描述信息,只有添加描述信息的I/O點才可能在實際的數(shù)據(jù)采集和輸出中起作用。

3.1.5? 相關(guān)文件生成子模塊

在編譯的過程中需要生成一些相關(guān)文件,這些文件的生成過程貫穿整個編譯模塊,包括最終需要的PRG文件、FV文件等與通訊相關(guān)的磁盤文件和一些編譯過程中產(chǎn)生的臨時文件。下文中將重點介紹ConMaker生成的磁盤文件的過程及各文件的作用。

ConMaker在編輯和預(yù)編譯階段將組態(tài)工程的邏輯轉(zhuǎn)換成C語言的描述形式,將其保存在C文件中,文件的內(nèi)容大多采用ANSI C89語法規(guī)定的規(guī)則描述,唯一的區(qū)別是C文件中采用了GCCC語言擴充的_attribute_屬性,這使得ConMaker預(yù)編譯生成的C語言文件不能用其它編譯器編譯。

ConMaker在編譯階段以C文件為輸入通過調(diào)用GCC及整理數(shù)據(jù)得到編譯的臨時文件.asd,如果用戶此時選擇對ConMaker編譯結(jié)果進行保存則編譯模塊會將.asd文件轉(zhuǎn)換成編譯信息文件.ci,之后整理ci文件的內(nèi)容生成PRG文件。對于工程組態(tài)中定義的所有變量類型和每個變量的具體信息,編譯模塊將其統(tǒng)一記錄在符號表文件.SDB 中。

ConMaker編譯成功后,這時用戶可通過ConMaker的通訊模塊來操作PRG文件進行下裝和在線的操作,如果進行了組態(tài)工程的下裝,通訊模塊會根據(jù)本次下裝的PRG文件經(jīng)過處理后生成下裝信息文件.didi文件將記錄下本次下裝所有的信息,包括控制器的IP地址、下裝的工程標(biāo)識及工程的組態(tài)信息等。另外,通訊模塊在下裝后會將強制臨時文件轉(zhuǎn)換成強制信息文件.fv,在下裝后才進行強制信息文件的生成可以減少編譯執(zhí)行的時間。由于ConMaker支持增量下裝的功能,所以在每次編譯生成PRG文件后,編譯模塊會比較ci文件和di文件的數(shù)據(jù)并以此判斷在下次可能進行的增量下裝時需要傳遞的通訊內(nèi)容,將這些通訊內(nèi)容保存在.OL文件中。

4? 總結(jié)

本文介紹了和利時自主研發(fā)的組態(tài)軟件ConMaker,對其編譯功能的需求進行了說明和分析,并對如何借助GCC實現(xiàn)ConMaker的編譯功能做了詳細(xì)介紹。通過一年半時間的預(yù)研和開發(fā),經(jīng)過初步測試,ConMaker編譯的工程運行快速、穩(wěn)定,滿足實際應(yīng)用的需要。

?

參考文獻

[1]????? Alfred V.Aho Ravi Sethi,Jeffrey D.Ullman著:Compilers : Principles Techniques and Tools機械工業(yè)出版社,1987

[2]????? Andrew W.AppelMaia Ginsburg著:Modern Compiler Implementation in C,人民郵電出版社,2000

[3]????? Brian W.KernighanDennis M.Ritchi著:The C Programming Language? (2nd Edition),機械工業(yè)出版社,1991

[4]????? John E.Hopcroft,Rajeev Motwani,Jeffrey D.Ullman著:Introduction to Automata Theory Languages and Computation (2nd Edition)機械工業(yè)出版社,1990

[5]????? 沈美明,溫冬嬋著:80x86匯編語言程序設(shè)計,清華大學(xué)出版社,2001

[6]????? http://gcc.gnu.org/onlinedocs/gccint/

[7]?? GB/T 15969.3--2005/IEC 61131-3:2002
本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。