吳曉葵
(西安航空技術(shù)高等??茖W(xué)校 現(xiàn)代教育技術(shù)中心,陜西 西安 710077)
嵌入式系統(tǒng)被廣泛應(yīng)用于工業(yè)控制、醫(yī)療儀器、通信設(shè)備、信息家電等領(lǐng)域,隨著應(yīng)用需求的復(fù)雜化,嵌入式軟件的規(guī)模和復(fù)雜性也日益增加,軟件質(zhì)量對整個系統(tǒng)質(zhì)量的影響也越來越大[1]。而嵌入式系統(tǒng)對可靠性的要求比較高,嵌入式系統(tǒng)安全性的失效可能會導(dǎo)致災(zāi)難性的后果,即使是非安全性系統(tǒng),也會導(dǎo)致嚴(yán)重的經(jīng)濟(jì)損失。這就要求對嵌入式系統(tǒng)及軟件必須進(jìn)行嚴(yán)格的測試、確認(rèn)和驗(yàn)證[2]。嵌入式系統(tǒng)具有實(shí)時性強(qiáng),存儲、計(jì)算等資源有限,與硬件緊密相關(guān)等特點(diǎn),這決定了傳統(tǒng)軟件測試?yán)碚摬荒苤苯佑糜谇度胧杰浖y試。因此需要研究更好的嵌入式軟件測試方法和策略。
嵌入式軟件與通用軟件相比具有專用性,只能在特定的硬件平臺上執(zhí)行,其開發(fā)環(huán)境和運(yùn)行環(huán)境不一致。嵌入式軟件的開發(fā)環(huán)境被認(rèn)為是主機(jī)平臺,運(yùn)行環(huán)境則為目標(biāo)平臺。嵌入式軟件測試即跨平臺交叉測試,一部分工作在主機(jī)上進(jìn)行,而其他工作在目標(biāo)平臺上進(jìn)行,這就帶來了嵌入式軟件的測試策略問題[3]。通常嵌入式軟件測試要經(jīng)歷單元測試、集成測試、系統(tǒng)測試等階段[1]。
多數(shù)單元級測試都在主機(jī)環(huán)境上進(jìn)行,因?yàn)橥ǔV鳈C(jī)平臺的測試速度比目標(biāo)平臺快得多,同時可提供更豐富的測試工具。在主機(jī)平臺完成測試后,可以在目標(biāo)平臺上重復(fù)簡單的確認(rèn)測試,確認(rèn)測試將確定一些未知的、難以預(yù)料的主機(jī)與目標(biāo)機(jī)之間的差異。通過在主機(jī)平臺上模擬目標(biāo)運(yùn)行環(huán)境,集成測試也可在主機(jī)環(huán)境上完成。但隨著計(jì)算機(jī)系統(tǒng)和物理系統(tǒng)的耦合越來越緊密[4],如何準(zhǔn)確模擬目標(biāo)平臺的軟硬件環(huán)境變得更為困難。因此集成測試的進(jìn)行將綜合軟件開發(fā)的條件和用戶對軟件質(zhì)量的期望水平等因素,此階段的確認(rèn)測試將確定一些環(huán)境上的問題,例如內(nèi)存定位和分配上的一些錯誤。系統(tǒng)測試,比如恢復(fù)測試、安全測試、強(qiáng)度測試、性能測試等均需在目標(biāo)環(huán)境下執(zhí)行。
總之,通常在主機(jī)環(huán)境執(zhí)行多數(shù)的測試,只是在最終確定測試結(jié)果和最后的系統(tǒng)測試才移植到目標(biāo)環(huán)境,這樣可避免對目標(biāo)系統(tǒng)的訪問競爭而造成資源瓶頸,也可減少昂貴資源(如在線仿真器)的使用費(fèi)用。軟件良好的可移植性將有助于交叉測試的進(jìn)行,可提高軟件測試的效率,提高軟件質(zhì)量。
目前的測試工具大致分為純軟件測試工具、純硬件測試工具和硬件輔助軟件的測試工具。
純軟件測試工具采用軟件打點(diǎn)技術(shù),即在被測代碼中加入一些插樁函數(shù),借以生成測試數(shù)據(jù)并存儲在目標(biāo)系統(tǒng)共享內(nèi)存中。目標(biāo)系統(tǒng)對這些數(shù)據(jù)進(jìn)行預(yù)處理,然后交給主機(jī)平臺進(jìn)行深入分析,獲取程序當(dāng)前的運(yùn)行狀態(tài)。由于插入插樁函數(shù)和預(yù)處理任務(wù)的存在,使系統(tǒng)的代碼增大,更嚴(yán)重的是這些代碼會對系統(tǒng)的運(yùn)行效率有很大的影響[5]。因此目標(biāo)系統(tǒng)是在一種不真實(shí)的環(huán)境下運(yùn)行的,所捕獲的數(shù)據(jù)也就不夠精確。純軟件測試工具在進(jìn)行嵌入式軟件測試時不能對目標(biāo)系統(tǒng)中的函數(shù)和任務(wù)運(yùn)行時間進(jìn)行精確的分析,難以對內(nèi)存的動態(tài)分配進(jìn)行有效的觀察,當(dāng)進(jìn)行覆蓋率分析時,只能做單元覆蓋率分析且單元的程序量不能太大。
而純硬件測試工具通常用于系統(tǒng)的硬件設(shè)計(jì)與測試,當(dāng)它用于軟件的分析測試時,很難滿足用戶的基本要求[5]。比如邏輯分析儀通過信號采樣分析判斷程序當(dāng)前的運(yùn)行狀態(tài),這可能會遺失重要的信號。仿真器無法在CACHE打開的方式下工作,不能對內(nèi)存分配進(jìn)行分析和檢查,由于做覆蓋率分析時硬件工具是從系統(tǒng)總線捕獲數(shù)據(jù),因此可能不是真實(shí)的系統(tǒng)環(huán)境。
圖1 CodeTEST測試原理圖Fig.1 Testing principle diagram of CodeTEST work
CodeTEST是硬件輔助軟件的測試工具。它采用并改進(jìn)了軟件打點(diǎn)技術(shù),純軟件工具插入的是一個函數(shù),而CodeTEST插入的是一條賦值語句,所以它執(zhí)行的時間很短,對目標(biāo)系統(tǒng)的影響非常小。另外,CodeTEST采用了純硬件工具中從總線捕獲數(shù)據(jù)的技術(shù)并且對其進(jìn)行完善。CodeTEST不再使用采樣方式,而是通過監(jiān)視系統(tǒng)總線,當(dāng)程序運(yùn)行到插入的特殊點(diǎn)的時候才會主動到數(shù)據(jù)總線上把數(shù)據(jù)捕獲回來。因此,在同樣的處理能力下,CodeTEST能同時對多個函數(shù)和任務(wù)進(jìn)行性能分析,精確得出其執(zhí)行的最大、最小和平均時間。能夠精確地顯示各函數(shù)或任務(wù)之間的調(diào)用情況,能夠動態(tài)跟蹤內(nèi)存分配情況,報告內(nèi)存出錯點(diǎn)和相應(yīng)的原始數(shù)據(jù),因此可以做到精確的數(shù)據(jù)觀察。另外,CodeTEST在做覆蓋率分析時,能夠在實(shí)時系統(tǒng)環(huán)境下測試SC、DC和MC/DC級別的代碼覆蓋率,掌握當(dāng)前的代碼測試覆蓋的真實(shí)情況。
CodeTEST是專為嵌入式系統(tǒng)軟件測試而設(shè)計(jì)的工具套件,它與開發(fā)環(huán)境無縫集成,能夠有效地進(jìn)行軟件性能分析、內(nèi)存分析、覆蓋率分析和代碼跟蹤等。根據(jù)嵌入式系統(tǒng)不同的開發(fā)階段和測試需求,CodeTEST分為3種測試模式:1)CodeTEST Native:主機(jī)測試;2)CodeTEST Software-In-Circuit:將軟件植入目標(biāo)系統(tǒng)通過以太網(wǎng)連接進(jìn)行軟件測試;3)CodeTEST Hardware-In-Circuit:系統(tǒng)測試。
CodeTEST由數(shù)據(jù)采集單元 (DCU)和數(shù)據(jù)處理單元(DPU)2大部分組成,其中數(shù)據(jù)采集單元用于采集目標(biāo)板上的數(shù)據(jù),數(shù)據(jù)處理單元用于處理數(shù)據(jù),并將結(jié)果發(fā)回到宿主機(jī),由宿主機(jī)進(jìn)行分析,得出測試結(jié)果。CodeTEST進(jìn)行軟件測試的過程大體上分為3個步驟,其具體過程如圖1所示。
1)CodeTEST編譯器調(diào)用原編譯器對源代碼進(jìn)行預(yù)編譯,插樁器對編譯后的源代碼進(jìn)行插樁,即在需要插樁的關(guān)鍵位置寫入一條賦值語句,并建立符號數(shù)據(jù)庫保存插入標(biāo)記以備后續(xù)使用。
2)CodeTEST編譯器調(diào)用原編譯器編譯插樁后的源代碼,生成可執(zhí)行目標(biāo)代碼,并下載到目標(biāo)板上運(yùn)行。
3)當(dāng)程序運(yùn)行到插樁點(diǎn)的位置時,目標(biāo)板控制總線和地址總線上會出現(xiàn)相應(yīng)的控制信號和地址信號。CodeTEST一旦監(jiān)測到這些信號,就會從數(shù)據(jù)線上捕獲插樁點(diǎn)處的信息,送入內(nèi)存進(jìn)行預(yù)處理,然后將處理后的數(shù)據(jù)回送,并和原符號數(shù)據(jù)庫中保存的數(shù)據(jù)相比較,由此得知程序的當(dāng)前運(yùn)行狀態(tài),進(jìn)而完成對嵌入式軟件的性能分析,覆蓋率分析等各類測試。由于CodeTEST采用硬件直接從目標(biāo)機(jī)的總線上跟蹤嵌入式代碼的實(shí)時運(yùn)行情況,可以實(shí)現(xiàn)邊測試邊觀察覆蓋率,這樣實(shí)現(xiàn)了對嵌入式實(shí)時軟件的測試。
CodeTEST-ACT (CodeTEST Advanced Coverage Tools)擴(kuò)展了CodeTEST的簡單語句覆蓋(SC)為決策覆蓋(DC)以及條件決策覆蓋(MC/DC),利用CodeTEST對嵌入式實(shí)時軟件的測試功能可以一邊測試,一邊觀察覆蓋率的情況。
由于不同環(huán)境下的測試流程各有差異,基于如下環(huán)境:宿主機(jī)操作系統(tǒng),Windows XP;目標(biāo)板處理器,PowerPC860;目標(biāo)板操作系統(tǒng),VxWorks;開發(fā)環(huán)境,Tornado2.0 for ppc。覆蓋測試開發(fā)的一組嵌入式程序(30個程序代碼)。其過程如下:
1)設(shè)置環(huán)境變量。設(shè)置環(huán)境變量AMC_HOME和AMC_TARGET。其中AMC_HOME為CodeTEST安裝目錄,AMC_TARGET為編譯項(xiàng)。本例中AMC_TARGET設(shè)為gnuppc-vxworks-hwic。這四項(xiàng)分別對應(yīng)編譯器,目標(biāo)板處理器,目標(biāo)板操作系統(tǒng)以及Hardware-In-Circuit測試類型。
2)修改Makefile文件,對源代碼進(jìn)行編譯。根據(jù)實(shí)際環(huán)境修改Makefile文件中相應(yīng)選項(xiàng),確保對源文件能夠進(jìn)行有效編譯。在本例中修改cpu=ppc860,tool=gnu,cc=ctcc-ctvctkeep-cttag-allocator。其中ctcc表示編譯驅(qū)動,整個打點(diǎn)過程由它控制,相當(dāng)于一個批處理文件。ctv顯示打點(diǎn)器的版本號。cttag-allocator表示內(nèi)存打點(diǎn)的選項(xiàng)。ctkeep表示源代碼打點(diǎn)生成的臨時文件保留。執(zhí)行make-f makefile all命令,生成.idb文件,即添加了插樁信息的符號數(shù)據(jù)庫文件。執(zhí)行make-f makefile命令,生成可在目標(biāo)板上執(zhí)行的.out文件。
3)下載可執(zhí)行文件到目標(biāo)板。啟動 Tornado,配置好VxWorks操作系統(tǒng)所在路徑以及目標(biāo)板的IP地址,將Vxworks操作系統(tǒng)、目標(biāo)板驅(qū)動、DPU驅(qū)動以及之前所生成的.out文件載入目標(biāo)板。
4)運(yùn)行 CodeTEST Manager,采集數(shù)據(jù),根據(jù)目標(biāo)板 CPU等信息配置相應(yīng)選項(xiàng),然后在Tornado的shell中運(yùn)行待測程序,開始采集數(shù)據(jù)。CodeTEST Manager將顯示最終測試結(jié)果。
在沒有使用CodeTEST進(jìn)行的軟件覆蓋率測試中,因?yàn)槿狈y試充分性的衡量指標(biāo),測試可能隨時終止,測試中該軟件覆蓋率普遍較低,一般語句低于80%,分支語句低于55%,其他的覆蓋率則更低。
利用上述方法,借助于CodeTEST獲取的相應(yīng)代碼的覆蓋率的結(jié)果見圖2,從圖2中可以看到,在coverage Data窗口中清晰地顯示了系統(tǒng)每個函數(shù)的函數(shù)名、所屬文件名以及代碼覆蓋的情況,大部分程序代碼覆蓋率良好,覆蓋率可以實(shí)現(xiàn)語句完全覆蓋,以及分支覆蓋85%以上。而對于不能覆蓋到的語句或分支,在測試工具的配合下,測試人員很容易找到未覆蓋的原因。例如,由圖2可以看出,MainApp.c的覆蓋率為69.23%,這時可以通過Source窗口打開查看其源代碼,在Source窗口中源代碼中以不同的顏色區(qū)分已執(zhí)行和未執(zhí)行的語句,從而發(fā)現(xiàn)程序的設(shè)計(jì)問題。
圖2 CodeTEST測試結(jié)果圖Fig.2 Testing result diagram of CodeTEST
在使用CodeTEST進(jìn)行嵌入式軟件測試時,由于環(huán)境不同,測試的過程也不盡相同。在使用CodeTEST進(jìn)行測試過程中需要注意幾點(diǎn):
1)主機(jī)IP,DPU的IP和目標(biāo)板IP需在同一網(wǎng)段,否則可能無法正常通信。
2)下載可執(zhí)行文件到目標(biāo)板時,先載入目標(biāo)板驅(qū)動和DPU驅(qū)動,后載入.out文件。
3)對測試的某些類型的程序,為正確反映程序的運(yùn)行結(jié)果,應(yīng)該先執(zhí)行CodeTEST,否則無法獲取先運(yùn)行的用戶程序的部分信息。
4)在進(jìn)行覆蓋測試時,應(yīng)本著“先易后難”的原則。例如,應(yīng)先進(jìn)行語句測試的覆蓋用例設(shè)計(jì)并測試,其后,按照同等方式進(jìn)行條件、分支或其他等級的覆蓋測試,這樣可以避免重復(fù)性的測試工作,提高測試效率。
5)測試數(shù)據(jù)應(yīng)盡量采用寫內(nèi)存的方式獲取,避免采用寫文件的方式。由于寫文件的方式需要對文件進(jìn)行頻繁操作,這種頻繁操作會破壞嵌入式軟件的實(shí)時性,甚至?xí)斐杀粶y軟件無法繼續(xù)運(yùn)行的現(xiàn)象發(fā)生。
除了覆蓋測試,利用CodeTEST測試工具的內(nèi)存分析和代碼跟蹤能力還可以發(fā)現(xiàn)軟件實(shí)現(xiàn)中的不足之處,并對其進(jìn)行優(yōu)化。例如根據(jù)測試結(jié)果發(fā)現(xiàn)該系統(tǒng)的MainApp.c函數(shù)被多次調(diào)用,并且該函數(shù)代碼較少,就可以將其設(shè)為內(nèi)聯(lián)函數(shù),以優(yōu)化性能。
基于CodeTEST的嵌入式軟件測試技術(shù)對軟件打點(diǎn)技術(shù)和從總線上捕獲數(shù)據(jù)技術(shù)進(jìn)行了改進(jìn)和提升,正是這種原理上的優(yōu)勢,使得CodeTEST具有強(qiáng)大的性能分析、內(nèi)存分析、覆蓋率分析和代碼跟蹤能力。借助CodeTEST測試工具和適當(dāng)?shù)姆椒梢缘玫酱罅康膶?shí)時可靠的測試結(jié)果,由此可以發(fā)現(xiàn)軟件實(shí)現(xiàn)中的不足之處,并對其進(jìn)行優(yōu)化、改進(jìn)。
[1]喬文軍.嵌入式軟件測試平臺的研究與實(shí)現(xiàn)[D].南京:南京航空航天大學(xué),2007.
[2]郭群.嵌入式軟件測試設(shè)計(jì)技術(shù)[J].微處理機(jī),2008,29(4):104-106.GUO Qun.Technique of embedded software test and design[J].Microprocessors, 2008, 29(4):104-106.
[3]李偉,程朝輝.嵌入式軟件測試策略研究[J].北京化工大學(xué)學(xué)報, 2007, 34(Sup.I):43-46.LI Wei,CHENG Zhao-Hui.The research on testing strategy of embedded software[J].Journal of Beijng University of Chemical Technology,2007,34(Sup.I):43-46.
[4]Kim J E,Mosse D.Generic framework for design[J].Modeling and Simulation of Cyber Physical Systems,ACM SIGBED Review, 5(1):20-21.
[5]曹小鵬.嵌入式軟件的測試方法研究[J].西安郵電學(xué)院學(xué)報,2007,12(5):92-94.CAO Xiao-peng.The testing method studies of the embedded softwar[J].Journal of Xi'an University of Posts and Telecommunications, 2007, 12(5):92-94.