一根信號線,代碼版本來相見
楔子
本文引用地址:http://butianyuan.cn/article/201908/404193.htm嵌入式系統(tǒng)是硬件搭臺、軟件唱戲,就像你可以在同一個舞臺上演出不同的劇目一樣,嵌入式設(shè)備的硬件做好后,只要硬件上支持,你可以根據(jù)不同的功能要求燒寫不同的代碼。
在嵌入式軟件的開發(fā)階段,需要經(jīng)過多次更新迭代,軟件版本可以以“里程碑”的形式,通過版本標(biāo)號(x.y)對各個軟件版本進(jìn)行標(biāo)識和區(qū)分。而且,一般情況下,不同的軟件版本中可能會隱藏不同表現(xiàn)形式的缺陷,為了提高軟件的可靠性和完善性能,需要查找缺陷或者定位缺陷的引入時間,這個時候就需要對不同版本的軟件進(jìn)行并行測試,以定位缺陷的原因和具體位置。
相比而言,硬件版本相對固定,分不出大哥和二哥,從而無法通過辨認(rèn)硬件電路特征判斷當(dāng)前被測試的軟件的版本,進(jìn)而無法進(jìn)一步分析。如果軟件本身包含版本信息,通過一種手段從軟件中獲得版本信息,便可以解決上述問題。
顯然,這里有一個不言自明的需求:獲取當(dāng)前的代碼版本信息。對于存在多個代碼版本的嵌入式硬件而言,這是一個“剛需”。
1
曾幾何時,讀取軟件版本只是中高端嵌入式設(shè)備的專利,責(zé)任越大,能力越大,中高端如它,總有讀取軟件版本信息并呈現(xiàn)出來的方法。
低端設(shè)備忝列鄙視鏈的末端,它要么只有一種軟件實(shí)現(xiàn)的版本,從而根本不存在獲取代碼版本信息的需求,要么雖然有幾個版本,但是“有心殺賊,無力回天”,只能把代碼版本信息隱藏在卑微的塵埃里。
但是,在很多情況下,低端設(shè)備也有獲取代碼版本信息的訴求。
灑家需要做一款信號轉(zhuǎn)換器,其中,要把電機(jī)轉(zhuǎn)速信息(單位是rpm,轉(zhuǎn)/分鐘)轉(zhuǎn)換成車速信息(單位為km/h),根據(jù)公式,車速信息由變速箱的減速比、車輪直徑和電機(jī)轉(zhuǎn)速計算得來。
這個信號轉(zhuǎn)換器非常之簡單,沒有任何通信端口,故而無法通過通信的方式、以配置的手段將不同的減速比和車輪直徑下載到信號轉(zhuǎn)換器中,讓信號轉(zhuǎn)換器根據(jù)不同的配置計算車速。
為了實(shí)現(xiàn)信號轉(zhuǎn)換器的通用性,讓它可以適應(yīng)不同的速比和輪徑,灑家采取的笨辦法是在同一個硬件上設(shè)計幾種不同的軟件版本,分別對應(yīng)不同的減速比和車輪直徑,這樣一來,在相應(yīng)的代碼中求同存異,就可以復(fù)用硬件資源并提高產(chǎn)品的開發(fā)效率。
這種思路固然是好,可是問題是,在日常的生產(chǎn)、庫存管理中,如何從一群已經(jīng)燒錄了代碼又長得一模一樣的信號轉(zhuǎn)換器中,辨認(rèn)出它到底支持哪種速比和輪徑呢?
于是,獲取代碼版本信息以就變得十分必要而且迫切了。
2
可是,沒有任何通信端口,沒有任何顯示界面,還想要獲取代碼版本信息,其可得乎?于是,灑家向周邊的同仁征詢意見。
左邊的張工譏我癡人說夢,右邊的李工說我異想天開,前邊的徐工笑我癡心妄想,后面的趙工卻神秘兮兮地豎起一根手指,在我眼前晃來晃去,口中念念有詞:波羅波羅蜜,醒起!
嘩啦啦四周潑下幾盆涼水來,眨眼間澆了我一個透心涼。在這鬧鬧哄哄的冷嘲熱諷中,灑家倒橫下一條心來:世界千奇百怪,眾生千差萬別,但是佛曰,眾生平等。代碼版本就像是人類的身份信息,怎么就答不得別人的一句-“尊兄臺甫?”
獲取代碼版本的基本操作就是“你來問,我來答”,需要和外部世界進(jìn)行交互。說到交互,自然需要借助信號轉(zhuǎn)換器當(dāng)前的接口。接口接口,顧名思義,設(shè)備內(nèi)部連接外部的端口。
如前所述,這個信號轉(zhuǎn)換器是一個很簡單的產(chǎn)品,連接器上的端口都是一些普通的模擬輸入輸出端口、數(shù)字輸入輸出口、脈沖輸入和PWM輸出端口。
看官們也許已經(jīng)模模糊糊地想到了,可以從未使用的端子上下手,一個輸進(jìn)去,就是“你來問”,一個輸出來,就是“我來答”。按鍵形式輸入,LED形式輸出,操作起來方便,顯示方式也直觀。
灑家一開始也是這么想的,而且想得更為細(xì)致。
可以在信號轉(zhuǎn)換器的外接線纜上用夾線針把其中兩根線的信號取出來,另一邊一個接按鍵,一個接LED。同時,當(dāng)然要在信號轉(zhuǎn)換器的硬件上添加兩處電路,一處實(shí)現(xiàn)按鍵采集,一個實(shí)現(xiàn)LED輸出驅(qū)動,這些電路都很簡單,自不待言。
想好解決方案后,灑家起身環(huán)顧,把張李諸工叫過來,鼓著腮幫子、噴著唾沫星子和他們講起了我的方案。當(dāng)其時也,灑家突然心下一凜,想起了一個關(guān)鍵的問題:端口夠用否?
我趕緊數(shù)了數(shù)信號轉(zhuǎn)換器連接器上還未曾使用過的端子,倒霉催的,沒有用過的端口居然只剩下一路了!待我把目光投向MCU的IO上時,更加心驚地發(fā)現(xiàn),除了用過的IO口和仿真編程口,可用的IO口也只有一個了!
3
一支穿云箭,千軍萬馬來相見。斧頭幫的混混可以把牛皮吹破了天,可我現(xiàn)在只能對著板子大眼瞪著小眼。
說出去的話,潑出去的水。大話已經(jīng)出口,再難收回,怎么辦?
只剩一根線,既要輸入,又得輸出,既可檢測出按鍵狀態(tài),還要輸出得了LED的驅(qū)動,除了復(fù)用別無他途。而且,除了接口端子上要實(shí)現(xiàn)復(fù)用之外,MCU的IO那里也必須一腳兩用。
大概而言,MCU IO長時間處于輸入狀態(tài),檢測到按鍵按下后便切換為輸出模式,通過LED按照一定的規(guī)律顯示完代碼版本信息之后,便再次切換回輸入狀態(tài)。
具體怎么實(shí)現(xiàn)就頗有些燒腦了。灑家調(diào)整好呼吸,正襟危坐,如入禪定,一點(diǎn)一滴地思索著。
MCU的IO分時切換輸入和輸出方向,初始方向設(shè)置為輸入。周期性地讀取IO狀態(tài),檢測按鍵的按下和彈起狀態(tài)。
檢測到有效的按鍵按下時,等待按鍵彈起引發(fā)的IO狀態(tài)切換。當(dāng)彈起時將IO口的方向設(shè)置為輸出,然后以脈沖的方式驅(qū)動LED。
為了區(qū)分版本號中的大版本(又稱“基線版本”)和小版本(又稱“更新版本”),需要以不同的頻率輸出相應(yīng)數(shù)量的方波脈沖,以方便觀察者判斷大版本和小版本號。
比如,當(dāng)版本號為2.4時,基線版本/大版本號為2,更新版本/小版本號為4。可以讓LED以頻率為2Hz、占空比為50%的PWM形式輸出2個周期方波,間歇2秒后,再以頻率為1Hz、占空比為50%的PWM形式輸出4個周期的方波脈沖。
更一般的,版本號是a.b時,LED的閃爍方式為a個2Hz頻率方波+間歇2秒+b個1Hz頻率方波。
當(dāng)LED的顯示完成后,需要再次將IO腳設(shè)置為輸入方向,以等待下一次按鍵形式的問詢。通過在按鍵按下并彈起后統(tǒng)計2s間歇時間前后的LED閃爍次數(shù),便可以得到基線版本和更新版本號。
4
相信經(jīng)過上面的描述,各位看官已經(jīng)大致了解了如何用一個IO口一個外接端子獲取代碼版本信息。但是,從硬件上怎么實(shí)現(xiàn)還有些摸不著頭腦。
幫人幫到底,送佛送到西,灑家也不藏私,把電路圖貼上來。
平時,IO口處于輸入狀態(tài),按鍵處于彈起狀態(tài),IO口處電平為低,LED處于熄滅狀態(tài)。當(dāng)按下按鍵,R1上處短接VCC,IO口處電壓為高,而LED被反向截止,故而繼續(xù)處于熄滅狀態(tài)。對LED而言,只要IO口是輸入方向,無論按鍵按下還是彈起都是熄滅狀態(tài)。
當(dāng)將IO設(shè)置為輸出方向時,在按鍵處于彈起狀態(tài)的條件下,IO電平為高時,LED導(dǎo)通點(diǎn)亮,IO電平為低時,LED截止熄滅。
如此一來,通過在單個IO管腳上實(shí)現(xiàn)按鍵檢測與LED驅(qū)動的復(fù)用,以最少的資源實(shí)現(xiàn)了便實(shí)現(xiàn)了軟件版本的獲取,該方案在資源極其受限的低端嵌入式設(shè)備領(lǐng)域上肯定具有廣泛的適用性。
后記
我和同事們通報了這種方案后,諸工依然不置可否,但灑家卻按捺不住地志得意滿。這種方式簡單高效,易于實(shí)現(xiàn),正所謂:一根信號線,代碼版本來相見。
評論