董高云,周庭梁
(1.卡斯柯信號(hào)有限公司 研發(fā)中心, 上海 200071;2.同濟(jì)大學(xué) 道路與交通工程教育部重點(diǎn)實(shí)驗(yàn)室,上海 201804)
安全苛求系統(tǒng)下的嵌入式C語言程序調(diào)試技巧
董高云1,周庭梁2
(1.卡斯柯信號(hào)有限公司 研發(fā)中心, 上海 200071;2.同濟(jì)大學(xué) 道路與交通工程教育部重點(diǎn)實(shí)驗(yàn)室,上海 201804)
介紹安全苛求系統(tǒng)下的嵌入式C語言程序調(diào)試的技巧??偨Y(jié)安全苛求系統(tǒng)的編碼和程序調(diào)試工作中的嵌入式C語言調(diào)試經(jīng)驗(yàn),介紹正式代碼調(diào)試之前的3件準(zhǔn)備工作,代碼調(diào)試的“版本升級(jí)比較法”,打印添加技巧以及其它調(diào)試技巧和經(jīng)驗(yàn)。
安全苛求系統(tǒng);嵌入式系統(tǒng); C語言;調(diào)試技巧
安全苛求系統(tǒng)(Safety Critical System),通常是指一旦發(fā)生故障或出現(xiàn)差錯(cuò),會(huì)帶來人員傷亡、大宗財(cái)產(chǎn)損失、環(huán)境遭受嚴(yán)重破壞的系統(tǒng)[1]。安全苛求系統(tǒng)多以計(jì)算機(jī)為核心子系統(tǒng)構(gòu)成其監(jiān)控系統(tǒng),這類系統(tǒng)又被稱為安全苛求計(jì)算機(jī)系統(tǒng),國內(nèi)有的文獻(xiàn)也稱之為“安全關(guān)鍵計(jì)算機(jī)系統(tǒng)”。安全苛求計(jì)算機(jī)系統(tǒng)常用于軍事、航空航天、工業(yè)控制、銀行、醫(yī)療、通信等安全苛求領(lǐng)域,以避免由于計(jì)算機(jī)的失效造成重大事故。在鐵路信號(hào)領(lǐng)域的安全苛求系統(tǒng)包括車站聯(lián)鎖、區(qū)間閉塞,列車自動(dòng)駕駛,列車超速防護(hù)和道口防護(hù)等。
對(duì)于安全苛求系統(tǒng),需要從系統(tǒng)的規(guī)劃階段開始,在整個(gè)生命周期中給予特殊的關(guān)注。它的需求說明、設(shè)計(jì)、制作、驗(yàn)證、安裝、使用維護(hù)等都有特殊的要求。除了需要利用一系列的容錯(cuò)技術(shù)保證系統(tǒng)的可靠性以外,還需要采用故障–安全的技術(shù)來防護(hù)系統(tǒng)在故障或者軟件錯(cuò)誤的情況下產(chǎn)生災(zāi)難性的后果。例如在鐵路信號(hào)領(lǐng)域的聯(lián)鎖系統(tǒng)中經(jīng)常采用的二乘二取二結(jié)構(gòu)。
為了滿足安全苛求系統(tǒng)故障-安全的需要,高實(shí)時(shí)性、多任務(wù)的嵌入式操作成為首選。該系統(tǒng)廣泛應(yīng)用于鐵路信號(hào)領(lǐng)域的聯(lián)鎖、列車控制車、載控制器(CC)、軌旁區(qū)域控制器/線路控制器(ZC/LC)等多個(gè)安全產(chǎn)品中。因此,掌握在嵌入式操作系統(tǒng)環(huán)境下的程序開發(fā)調(diào)試技巧,是從事相關(guān)工作的技術(shù)人員的迫切需要。
安全苛求系統(tǒng)下的嵌入式程序故障表現(xiàn)為系統(tǒng)運(yùn)行不穩(wěn)定,或部分功能實(shí)現(xiàn)不正確,其原因大致可以分為以下幾類:硬件故障;驅(qū)動(dòng)板級(jí)支持包(BSP)和操作系統(tǒng)的故障;配置文件錯(cuò)誤;軟件本身的漏洞(BUG)。
正確的代碼調(diào)試步驟,應(yīng)該是在確認(rèn)和定位程序代碼的BUG之前,首先要排除前3類原因,然后再展開代碼本身的調(diào)試,也就是正式開始進(jìn)行嵌入式操作系統(tǒng)程序代碼BUG調(diào)試之前所必須要做的3件事情。
(1)先排除硬件故障的可能。嵌入式系統(tǒng)本身是一個(gè)軟硬件緊密結(jié)合的系統(tǒng),很多從表現(xiàn)上看是軟件的故障,實(shí)際查下來才發(fā)現(xiàn)是硬件所導(dǎo)致的。主要的硬件故障包括板卡本身的損壞和故障,板卡接觸不良,硬件插錯(cuò)等。此外,用于網(wǎng)絡(luò)通信的交換機(jī)和集線器本身的故障,也會(huì)造成網(wǎng)絡(luò)通信的不正常,或者進(jìn)行嵌入式程序調(diào)試時(shí)下載緩慢等。只有先排除了以上的各種硬件故障之后,再繼續(xù)下面的排查。
排除硬件的一個(gè)簡(jiǎn)單方法是:在備件充足的情況下,通過交換硬件來進(jìn)行硬件故障的確認(rèn)。例如互為主備的聯(lián)鎖A機(jī)機(jī)柜故障,聯(lián)鎖B機(jī)機(jī)柜運(yùn)行正常,若懷疑A機(jī)的某塊硬件板卡有問題,則與B機(jī)交換對(duì)等的硬件板卡,觀察故障是否跟著板卡走(即交換后,A機(jī)變?yōu)檎#珺機(jī)變成故障),如果是的話,應(yīng)該就是該塊硬件板卡的問題。
(2)確認(rèn)驅(qū)動(dòng)程序和BSP包是否正常。在代碼調(diào)試時(shí),除非進(jìn)行新產(chǎn)品開發(fā),相關(guān)驅(qū)動(dòng)尚未發(fā)布,否則必須選用已正式發(fā)布的驅(qū)動(dòng)。在嵌入式系統(tǒng)調(diào)試過程中,經(jīng)常會(huì)碰到由于硬件的驅(qū)動(dòng)本身有BUG,導(dǎo)致通信有故障或通信功能不穩(wěn)定的情況發(fā)生,此時(shí)如果貿(mào)然排查上層軟件的話,很可能走錯(cuò)了查找的方向。
此外,已發(fā)布的驅(qū)動(dòng)只是針對(duì)該驅(qū)動(dòng)發(fā)布時(shí)的硬件和BSP包環(huán)境所進(jìn)行的封版測(cè)試,并不一定能保證在所有的硬件和BSP包環(huán)境下的正常運(yùn)行。為了定位是否為驅(qū)動(dòng)本身的問題,在求助于驅(qū)動(dòng)開發(fā)人員之前,調(diào)試人員需要先準(zhǔn)備好一個(gè)驅(qū)動(dòng)測(cè)試程序,該測(cè)試程序只保留與驅(qū)動(dòng)相關(guān)的部分代碼,從而將問題定位至驅(qū)動(dòng)本身,證明問題來源于驅(qū)動(dòng),也方便驅(qū)動(dòng)開發(fā)人員進(jìn)行驅(qū)動(dòng)問題排查。
還有編譯環(huán)境的問題,調(diào)試某個(gè)版本的代碼時(shí)始終只有單網(wǎng)通信,無法實(shí)現(xiàn)雙網(wǎng)冗余,排查了所有原因,最終發(fā)現(xiàn)是進(jìn)行調(diào)試所用的筆記本電腦所裝載的Tornado開發(fā)環(huán)境軟件包本身有問題,導(dǎo)致編譯后的可執(zhí)行文件有缺陷。重裝Tornado后再進(jìn)行編譯,故障就沒有再出現(xiàn)了。
(3)確認(rèn)所調(diào)試程序的配置文件是正確無誤的,且各個(gè)配置文件都是基于同一版本發(fā)布基線的。在正式的程序調(diào)試之前,一定要確認(rèn)該代碼相關(guān)的所有配置文件版本無誤,且是相互匹配的,在一個(gè)錯(cuò)誤配置環(huán)境下的所有“故障”現(xiàn)象,由于其本身配置的不正常,都無法作為程序本身“故障”的參考。
版本升級(jí)對(duì)比法的具體操作為:在查找問題前,首先確保有一份舊版本且確認(rèn)無BUG的代碼,對(duì)新舊版本的代碼展開對(duì)比調(diào)試。即:采用代碼比較軟件(如Beyond Compare),逐行對(duì)比新舊版本代碼?;谝粋€(gè)基本的出發(fā)點(diǎn):新版本的代碼BUG是在舊版本的基礎(chǔ)上,進(jìn)行升級(jí)過程中所引入的。
對(duì)于引起B(yǎng)UG的故障語句的定位,可以有兩種思路:添加法,即在舊代碼的基礎(chǔ)上,逐步添加升級(jí)代碼,每次只添加一個(gè)或兩個(gè)功能點(diǎn)的升級(jí)代碼,每添加完后進(jìn)行編譯運(yùn)行,觀察是否異常,一般情況下,在添加至某個(gè)功能點(diǎn)時(shí),會(huì)出現(xiàn)“故障”現(xiàn)象,則可以定位為添加的功能點(diǎn)相關(guān)代碼是引起“故障”的源頭,從而實(shí)現(xiàn)“故障”代碼的定位。減少法,在新代碼的基礎(chǔ)上逐步刪減功能點(diǎn),退回至穩(wěn)定版本的舊代碼,在此過程中,會(huì)有某一功能點(diǎn)的減少,導(dǎo)致原來不穩(wěn)定的代碼重新趨于穩(wěn)定,這個(gè)功能點(diǎn)相關(guān)的代碼就是引起新代碼不穩(wěn)定的“故障”代碼源頭。
當(dāng)然,無論是添加法還是減少法,都需要提前規(guī)劃測(cè)試策略,注意做好測(cè)試版本的備份。在調(diào)試過程中,需要注意編譯環(huán)境的問題,注意全編譯和部分編譯的區(qū)別。每次“添加”或“刪減”一個(gè)功能點(diǎn)之后,進(jìn)行運(yùn)行拷機(jī)之前,最好要進(jìn)行全編譯,以確保完全整合了所有的修改,保證編譯代碼的完整性。
進(jìn)行嵌入式系統(tǒng)調(diào)試時(shí),需要注意使用打印語句進(jìn)行變量追蹤。由于嵌入式實(shí)時(shí)程序的特殊性,在非嵌入式(如Visual C++)程序調(diào)試時(shí)所使用的單步調(diào)試,加斷點(diǎn)、變量和語句的跟蹤等方法在大多數(shù)情況下無法使用。對(duì)于vxWorks這樣的操作系統(tǒng),只能通過添加打印語句來實(shí)現(xiàn)。打印語句的添加需要注意兩點(diǎn):(1)在中斷中,不能添加printf打印語句,只能添加logMsg()函數(shù)的打印語句。(2)無論是添加printf語句,還是添加logMsg(),都需要“慎用”,要考慮到這兩種打印語句對(duì)系統(tǒng)的穩(wěn)定性所帶來的負(fù)面影響。
通過添加臨時(shí)全局變量的方式,實(shí)際上是“面向接口的調(diào)試方法”的一種,即增加專用的調(diào)試接口,以方便故障定位和程序調(diào)試。除了增加臨時(shí)變量的方式,還可以采用直接增加網(wǎng)絡(luò)消息處理函數(shù),將相關(guān)的調(diào)試信息通過網(wǎng)絡(luò)接口直接發(fā)送到上位機(jī)的診斷維護(hù)支持系統(tǒng)中,從而使在線診斷和故障分析更加方便。與臨時(shí)添加打印變量相比,采用診斷維護(hù)支持系統(tǒng)來獲取調(diào)試信息的方式,能夠?qū)崿F(xiàn)調(diào)試信息的在線實(shí)時(shí)存儲(chǔ),有利于實(shí)現(xiàn)長(zhǎng)時(shí)間拷機(jī)時(shí)的故障記錄,對(duì)于出現(xiàn)頻率低的故障收集和排查具有良好的效果。
除了以上的調(diào)試技巧之外,還需要強(qiáng)調(diào)的是從事嵌入式系統(tǒng)調(diào)試的相關(guān)人員,需要有一個(gè)良好的心態(tài)。嵌入式系統(tǒng)運(yùn)行和啟動(dòng)比較耗時(shí),每次重啟之后,宿主機(jī)需要重新連接下位目標(biāo)機(jī)。從事安全系統(tǒng)和安全軟件開發(fā)的技術(shù)人員都有一個(gè)基本理念,就是計(jì)算機(jī)本身可能受到隨機(jī)干擾的影響會(huì)出錯(cuò),所以才會(huì)引出安全計(jì)算機(jī)的概念。但是需要指出,在嵌入式代碼調(diào)試時(shí),恰恰要反過來,不能夸大隨機(jī)干擾的影響。需要將系統(tǒng)性故障和隨機(jī)故障區(qū)分開,因?yàn)楸旧沓绦虻腂UG而引入的故障均為系統(tǒng)性故障,與CPU或RAM等隨機(jī)出錯(cuò)引起的隨機(jī)性故障無關(guān),相應(yīng)的出錯(cuò)概率也遠(yuǎn)高于隨機(jī)故障的出錯(cuò)概率。
在問題查找過程中,除了采用打印跟蹤之外,還可以考慮利用其它開發(fā)環(huán)境所提供的交互工具對(duì)嵌入式程序的運(yùn)行進(jìn)行監(jiān)控,對(duì)程序架構(gòu)和代碼中的關(guān)鍵變量,任務(wù)執(zhí)行等進(jìn)行分析。
對(duì)于短期內(nèi)難以解決的疑難問題,必須堅(jiān)持長(zhǎng)期拷機(jī),持續(xù)跟進(jìn)測(cè)試,并定期發(fā)布拷機(jī)匯報(bào),做好拷機(jī)記錄,不放過任何細(xì)節(jié),嵌入式系統(tǒng)的調(diào)試人員只有抱著持之以衡的心態(tài),采取正確的策略,理清相關(guān)的思路,才能攻堅(jiān)克難獲得最終勝利。
[1]酈 萌, 吳芳美. 鐵路信號(hào)可靠性安全性理論及證實(shí)[M].北京:中國鐵道出版社, 2008.
[2]員春欣, 江建慧. 安全關(guān)鍵計(jì)算機(jī)系統(tǒng)[M]. 北京:中國鐵道出版社, 2003.
[3]鄺 堅(jiān). Tornado/VxWorks 入門與提高[M]. 北京:科學(xué)出版社,2004.
[4]Wind River. VxWorks/BSP 開發(fā)人員指南[M]. 王金剛,蘇 琪,楊錫勱,譯.北京:清華大學(xué)出版社,2003.
責(zé)任編輯 陳 蓉
Program debug skill of C Language in Embedded Operation System running in Safety Critical System
DONG Gaoyun1, ZHOU Tingliang2
( 1. Research and Development Center, CASCO Signal Company, Shanghai 200071, China; 2. Key Laboratory of Road and Traff i c Engineering of the State Ministry of Education, Tongji University, Shanghai 201804, China )
This paper introduced the program debug skills of C Language in Embedded Operation System running in Safety Critical System, summarized serials of debug experiences of C Language. The three preparing work was pointed out before formal code debugging. The “version updating &comparing method”was introduced. The print adding skills during debug process and other debug skills as well as the experiences for Safety Critical System were also introduced.
Safety Critical System; Embedded Operation System; C Language; debug skills
U284∶TP39
:A
1005-8451(2014)06-0062-03
2014-01-28
董高云 ,高級(jí)工程師;周庭梁,在讀博士研究生。