基于ARM的LCU測(cè)試系統(tǒng)的設(shè)計(jì)
隨著我國(guó)機(jī)車(chē)控制水平的不斷提高,微機(jī)控制已經(jīng)成為我國(guó)機(jī)車(chē)控制的重要控制方式,而邏輯控制單元LCU(Logic Control Unit)作為主要完成機(jī)車(chē)運(yùn)行邏輯控制、電路故障記錄控制等功能的控制模塊,是關(guān)系機(jī)車(chē)安全運(yùn)行的重要部件。與傳統(tǒng)觸點(diǎn)控制電路相比,LCU具有可靠性高、體積小、通用性好、維護(hù)簡(jiǎn)單方便等優(yōu)點(diǎn)。
傳統(tǒng)的LCU檢測(cè)包括人力檢測(cè)、單片機(jī)檢測(cè)和PC機(jī)通過(guò)串口控制開(kāi)發(fā)板檢測(cè)[1]。但是隨著LCU生產(chǎn)制造水平的提高,傳統(tǒng)的檢測(cè)方法已經(jīng)不能很好地完成測(cè)試任務(wù)。
ARM具有設(shè)計(jì)開(kāi)發(fā)周期短、功耗低、性能優(yōu)越等特點(diǎn),能夠滿(mǎn)足LCU檢測(cè)的要求。基于Linux操作系統(tǒng)開(kāi)發(fā)的通用LCU檢測(cè)軟件,可以提供多層次、多場(chǎng)合的復(fù)用,可節(jié)省設(shè)備成本,具有巨大的市場(chǎng)前景和經(jīng)濟(jì)效益。
1 系統(tǒng)設(shè)計(jì)原理
LCU檢測(cè)就是對(duì)LCU內(nèi)部運(yùn)行邏輯做出測(cè)試并進(jìn)行故障診斷。測(cè)試系統(tǒng)通過(guò)向被測(cè)試的LCU發(fā)出初始命令,并查看其輸出結(jié)果是否與參考輸出相同,從而判斷被測(cè)試的LCU邏輯是否正確。
本文沿用傳統(tǒng)繼電器控制中的部分概念進(jìn)行軟件分析。傳統(tǒng)硬件繼電器觸點(diǎn)分為“常開(kāi)觸點(diǎn)”和“常閉觸點(diǎn)”兩類(lèi)。一條線路的運(yùn)行結(jié)果會(huì)反映到另外一個(gè)線圈上,因此,繼電器控制的輸出可以用線圈表示。本文沿用硬件繼電器中的名稱(chēng)進(jìn)行軟件邏輯分析。在程序中以BOOL變量TRUE表示觸點(diǎn)開(kāi)狀態(tài),F(xiàn)ALSE表示觸點(diǎn)閉狀態(tài)。
線路上的信號(hào)都可以采用二進(jìn)制表達(dá),所以測(cè)試的范圍會(huì)根據(jù)線路上觸點(diǎn)個(gè)數(shù)呈現(xiàn)指數(shù)增長(zhǎng)。對(duì)于要求不太嚴(yán)格的控制信號(hào),只要求在適當(dāng)?shù)臈l件下,得到開(kāi)通或閉合的結(jié)果,其動(dòng)作的條件為充分不必要條件。對(duì)于要求嚴(yán)格的控制信號(hào),不僅要求在確定的條件下得到應(yīng)有的結(jié)果,而且要保證這個(gè)條件是充分必要條件。因此,很大程度上測(cè)試可能會(huì)遍歷觸點(diǎn)的所有組合,測(cè)試的總體消耗時(shí)間就會(huì)擴(kuò)充到很大的時(shí)間范圍。假設(shè)一條線路的信號(hào)流動(dòng)經(jīng)過(guò)時(shí)間值為ns, 則計(jì)算一條包含20個(gè)觸點(diǎn)的線路的全部測(cè)試時(shí)間為220ns。
可見(jiàn),測(cè)試情況的選擇十分重要。測(cè)試復(fù)雜性的主要矛盾在于:需要證明充分必要條件的線路的多少以及該線路的觸點(diǎn)的多少。工業(yè)標(biāo)準(zhǔn)反映在程序中的情況就是保留測(cè)試的選擇性,便于在后續(xù)工作中進(jìn)行選擇和修改。此外,控制程序的算法,進(jìn)行復(fù)合運(yùn)算,提高測(cè)試的效率也是關(guān)鍵所在。本系統(tǒng)的硬件框圖如圖1所示。
2 嵌入式Linux操作系統(tǒng)移植
交叉編譯器的設(shè)置是嵌入式系統(tǒng)開(kāi)發(fā)的第一步。所謂交叉編譯就是在一種體系結(jié)構(gòu)的機(jī)器上編譯出能夠運(yùn)行于另一種體系機(jī)器上的代碼。若要開(kāi)發(fā)在ARM目標(biāo)板上運(yùn)行的程序,無(wú)論是操作系統(tǒng)還是應(yīng)用程序,都必須是基于ARM體系指令的二進(jìn)制代碼[2]。但是直接在ARM目標(biāo)板上開(kāi)發(fā)程序,無(wú)論是程序運(yùn)行速度還是調(diào)試手段,都嚴(yán)重制約了開(kāi)發(fā)效率,有些程序的編寫(xiě)更需要在PC機(jī)上才能完成。交叉編譯的作用,就在于在PC機(jī)上開(kāi)發(fā)程序,交叉編譯后,再放置到ARM目標(biāo)板上去執(zhí)行。編譯順序如圖2所示。
搭建ARM交叉編譯器的步驟:(1)編譯安裝binutils;(2)安裝linux 的頭文件;(3)編譯安裝gcc的c 編譯器;(4)編譯安裝 glibc;(5)編譯安裝gcc的c、c++編譯器。
Boot-loader是RAM芯片的引導(dǎo)程序,它的作用是加載操作系統(tǒng)。兩個(gè)著名的開(kāi)源Boot-loader,其中一個(gè)是U-boot,它的形式就是一個(gè)代碼包,包中按照Linux一般的編程習(xí)慣和不同的目標(biāo)板,將相應(yīng)的匯編和C語(yǔ)言代碼羅列在對(duì)應(yīng)的文件夾下,讓開(kāi)發(fā)人員自行配置。
修改U-boot的過(guò)程:(1)基本的硬件初始化;(2)跳轉(zhuǎn)到 Stage2 的 C 入口點(diǎn);(3)定義函數(shù)Nand_init;(4)跳轉(zhuǎn)到Kernel。
Linux內(nèi)核就是一個(gè)可執(zhí)行的Linux操作系統(tǒng)的套件集合,簡(jiǎn)稱(chēng)內(nèi)核[3]。套件的選擇,就是內(nèi)核的配置。內(nèi)核的配置表明了內(nèi)核的可調(diào)整性。根據(jù)Linux軟件的開(kāi)發(fā)規(guī)則,可到Linux內(nèi)核源碼包的路徑下,在終端使用配置命令進(jìn)行內(nèi)核配置。在配置內(nèi)核的時(shí)候,需要定義內(nèi)核啟動(dòng)的命令行。
3 LCU檢測(cè)系統(tǒng)應(yīng)用程序
3.1 軟件設(shè)計(jì)及其要素
軟件的應(yīng)用設(shè)計(jì),就是確定軟件的各個(gè)部分及各部分之間的相互關(guān)系,信息在其中發(fā)送、傳遞和接收,以及部分運(yùn)動(dòng)發(fā)展的走向和趨勢(shì),最終得到可以預(yù)見(jiàn)的結(jié)果[4]。它應(yīng)該遵循下面四個(gè)基本要素:名稱(chēng)、問(wèn)題、解決方案效果。
面向?qū)ο蟮能浖_(kāi)發(fā),從不同的對(duì)待問(wèn)題的層次出發(fā)能得到不同問(wèn)題的解決方案。其基本工作流程如圖3所示。
3.2 定義基本的類(lèi)和對(duì)象及人機(jī)界面的設(shè)計(jì)
在需求分析的說(shuō)明中,最常出現(xiàn)的三個(gè)名詞分別是觸點(diǎn)、測(cè)試和線圈。每個(gè)測(cè)試包含了不同的線圈,每個(gè)線圈又分別由觸點(diǎn)組成。所以,觸點(diǎn)、線圈和測(cè)試能夠分別抽象出來(lái)做成單獨(dú)的類(lèi)。觸點(diǎn)必須有ID、常開(kāi)/常閉的類(lèi)型和運(yùn)行中處于的值都應(yīng)該在屬性中出現(xiàn)。測(cè)試的ID應(yīng)該能夠區(qū)分是哪一次測(cè)試,并且記錄下所包含觸點(diǎn)的初始值以及標(biāo)準(zhǔn)情況下結(jié)果的預(yù)計(jì)值。線圈則以觸點(diǎn)和測(cè)試作為成員變量。
首先設(shè)計(jì)用二維數(shù)組來(lái)模擬測(cè)試與觸點(diǎn)的關(guān)系。假設(shè)數(shù)組的橫向和縱向表示分別為測(cè)試和觸點(diǎn),則某個(gè)線圈的設(shè)計(jì)如圖4所示。
對(duì)照實(shí)際情況,可以使用二維數(shù)組進(jìn)行描述。觸點(diǎn)的加入和刪除就是列的插入和刪除運(yùn)算,測(cè)試的加入和刪除就是行的插入和刪除運(yùn)算。對(duì)某線圈的實(shí)驗(yàn)就是把每行遍歷一遍,結(jié)果對(duì)照預(yù)計(jì)值進(jìn)行邏輯判斷。但這僅僅是表達(dá)了單個(gè)線圈的情況,多個(gè)線圈則呈現(xiàn)如圖5所示的書(shū)頁(yè)式的結(jié)構(gòu)。
直觀上看,重疊配置的線圈就像是檢查手冊(cè)的一封封頁(yè)面,測(cè)試整個(gè)系統(tǒng)的方法就是翻弄這本“書(shū)”,從頭至尾把所有的線圈遍歷一遍。
3.3 序列化存儲(chǔ)類(lèi)serial和鏈表類(lèi)
如果延續(xù)這樣的思路,則關(guān)于數(shù)組的操作會(huì)產(chǎn)生新的問(wèn)題:C語(yǔ)言中定義數(shù)組必須先確定數(shù)組的大小才能分配合適的內(nèi)存。例如,要得到一個(gè)m×n二維數(shù)組,則必須在編譯時(shí)確定m和n的大小,但實(shí)際上要求m和n是可變的。
由于文件是測(cè)試系統(tǒng)內(nèi)部調(diào)用的接口,應(yīng)該先沿著采用文件來(lái)登記測(cè)試項(xiàng)目的結(jié)論進(jìn)行分析。采用序列化技術(shù)能夠簡(jiǎn)單而方便地實(shí)現(xiàn)文件存儲(chǔ)。序列化是指將對(duì)象實(shí)例的狀態(tài)存儲(chǔ)到可持久保持信息的物理設(shè)備的過(guò)程,其特點(diǎn)就是線性存儲(chǔ)。序列化技術(shù)實(shí)現(xiàn)了文件的存儲(chǔ),同時(shí)它也給出了一種思路:把所有一切都統(tǒng)一對(duì)待,變成一根主線。應(yīng)用到“二維結(jié)構(gòu)”上就是將二維表變成一維的大表,同時(shí)用指針來(lái)保持邏輯的連接。如圖6所示。
但序列化只提供鏈型的存儲(chǔ)形式,只能用一維的鏈表模擬二維數(shù)組,因?yàn)椴恢蓝S鏈表的指針應(yīng)該如何安排。
決定采用鏈?zhǔn)铰?lián)系的方法:用指針來(lái)實(shí)現(xiàn)連接。但是指針的傳遞跨越了類(lèi),因此有必要把鏈?zhǔn)浇Y(jié)構(gòu)直接抽象成類(lèi),產(chǎn)生定義觸點(diǎn)鏈表類(lèi)、測(cè)試鏈表類(lèi)和線圈鏈表類(lèi),并將它們抽象出一個(gè)基本的鏈表類(lèi),實(shí)現(xiàn)鏈表基本的操作,再?gòu)乃缮錾鲜鋈齻€(gè)鏈表類(lèi)。
3.4 計(jì)算預(yù)計(jì)值
測(cè)試隨意地更改其所包含的觸點(diǎn),隨之變動(dòng)的是測(cè)試的預(yù)計(jì)值。這可以采取人工輸入來(lái)實(shí)現(xiàn),但是如果用表達(dá)式字符串來(lái)表達(dá)測(cè)試的邏輯計(jì)算,可以通過(guò)字符替換的方法讓機(jī)器來(lái)實(shí)現(xiàn)。
表達(dá)式字符串中間必須有觸點(diǎn)的ID名字,常閉觸點(diǎn)的名字前加“~”,測(cè)試線路的“與”邏輯用字符“*”來(lái)表示,或邏輯用字符“|”來(lái)表示(也可以選擇其他的計(jì)算字符),用括號(hào)表示優(yōu)先的線路邏輯,空格是人性化的適應(yīng)性定義。這樣即可以表達(dá)出線路的邏輯。
計(jì)算預(yù)計(jì)值的算法如下:
(1) 輸入目標(biāo)字符串。
(2) 首先去空格。
(3) 用觸點(diǎn)的狀態(tài)值替換觸點(diǎn)ID,如果是FALSE,替換成F,如果是TRUE,替換成T。
(4) 開(kāi)始循環(huán): F*F 替換成F
F*T 替換成F
T*F 替換成F
T*T 替換成T
F|F 替換成F
F|T 替換成T
T|F 替換成T
T|T 替換成T
(T) 替換成T
(F) 替換成F
測(cè)量字符串長(zhǎng)度,如果和上次相比變小,則重新開(kāi)始循環(huán);如果沒(méi)有變化,則跳出循環(huán)進(jìn)行下一步。
(5) 判斷:如果字符串==T,則說(shuō)明預(yù)計(jì)值是TRUE;如果字符串==F,則說(shuō)明預(yù)計(jì)值是FALSE;如果字符串是其他值,說(shuō)明輸入的表達(dá)式有誤,提示重新確定表達(dá)式。
評(píng)論