嵌入式軟件可靠性設計要注意的問題
發布時間:2019-08-02 15:41:35來源:
嵌入式軟件的比較大特點是以控制為主,軟硬結合的較多,功能性的操作較多,模塊相互間調用的較多,外部工作環境復雜容易受到干擾或干擾別的設備,且執行錯誤的后果不僅僅是數據錯誤而是有可能導致不可估量的災難,所以總結起來,嵌入式軟件可靠性設計需注意的問題有四個方面:
1、軟件接口
先說軟件接口中容易出問題的地方和編程人員容易犯的錯誤。
軟件接口調用一般會有數據的賦值,賦值變量的數據類型可能會存在強制的數據轉換;需加以檢查。如果為了防范出問題的話,可以添加對數據范圍和數據類型的檢查。
賦值數據的數量不對路,多了少了的都不好,會出現意外的賦值結果,不過還好,這項錯誤比較好檢查。
軟件編程中,會有對某一功能操作代碼的復用,比如對某個端口的數據檢查和控制,在整個程序中只會發生兩次,為了圖省事,可能就直接把該段代碼直接插入實際程序模塊中去了,這樣,在源程序代碼中,就出現了兩段完全相同,完成相同功能,只是服務于不同模塊的代碼,按道理來說,這樣設計其實也沒啥問題,是的,你沒錯,但你的行為會使別人無意中犯錯。就像青年男女相處,女孩子純粹是想和男孩子充分享受溫馨的氣氛和心情,并不想更深入的發生什么,但女孩子邀請男生去的是她的家,在家里換上了家居的睡衣,窗戶緊閉,放著的還是曖昧的音樂,被男孩子半強迫發生后,無限哀怨地說“我沒想到結果會是這樣的”,那怪得誰來呢?在代碼方面,您的這種做法與貌似引誘男孩上鉤的^^無異。
有人會說了,我這樣寫代碼怎么就算引誘呢?原因是程序可能會升級,您這幾行代碼在實際應用過程中也不能保證是盡善盡美的,發現不完善的地方后,勢必會修改,如果你還能想得起來,可能不會遺漏,如果修改此代碼的是別的人,改了一個地方,別的地方沒改,是不是還留著隱患?那如何做呢?方法不難,把這段功能單獨做成一個模塊即可,對此端口的讀取和控制賦值均由此獨立模塊完成,如果數據的正確性影響大的話,還需要對端口數據的正確性進行檢查和判斷。嵌入式軟件可靠性編程方法的四個目的是防錯、判錯、糾錯、容錯。對端口數據的判斷屬于判錯的內容,如果數據有錯的話,糾錯和容錯的設計方法應該不用我深入講解了吧?
2、軟硬件接口
硬件如男人,對外的執行都靠它來實現,一旦出現問題,執行后的后果就不可控了,周總理說過“外交無小事”。但如何注意呢?
對讀進來的硬件接口的數據要判斷其真偽;
對輸出的數據的執行效果要檢測;
對輸出的數據的可能后果要進行預防性設計,數據輸出的過程,我們從設計上要做一個分析,分析的思路是一般容易局限在穩態過程,忽視了過渡過程。舉例說明,比如我們控制一個支路的供電,從軟件控制來說,直接給繼電器一個啟動信號,讓開狀態的觸點閉合就可以了,非“關”即“開”,是受控繼電器的兩個穩態狀態,但事實上,在從開到閉合的過程中,支路供電的電壓并不是一個簡單0V—24V(24V為示例而已)的跳變狀態,而是一個抖動,有沖擊信號的過程,這種情況在硬件上的防護是必不可少的,但在軟件上也不是可以事不關己、高高掛起的。
另外在邏輯上,宜將容易被干擾和容易產生的干擾控制動作從時序上控制好,予以分開隔離。比如,控制繼電器的過程是容易產生抖動尖峰脈沖而干擾數據總線和控制信號總線的,這時候從控制上,不宜同時實施數據的發送和接收工作,不宜作出其他的控制動作,惹不起咱躲得起,躲過這一陣干擾的時候總可以了吧?
3、軟件代碼
軟件的可靠性是隨著時間的推移,可靠性逐漸增加的,這一點區別于電子可靠性、機械可靠性。電子可靠性服從指數分布,在整個生命周期內,其失效率為一個常數;機械可靠性因為磨損、腐蝕、運動等因素的存在,隨時間推移可靠度會下降。因此也就有了軟件可靠性設計的一個特定規律和注意事項。
既然需要通過時間推移,通過不斷改進,軟件可靠性得到提升。那么軟件的可維護性就是一個大問題了。這也是為什么軟件工程管理方面特別關注軟件文檔、注釋的原因了。但做這些要求的人只是人云亦云,并不理解如此做法的真正動機。至于注釋如何去做、變量如何命名、軟件配置管理如何操作,這里面既有很常規的方法,也有一些我們司空見慣然而是錯誤的做法。信手舉上幾個值得注意的細節供參考。
變量定義時宜將變量類型的變量名程中體現于其中;如AD_result_int、Cal_result_float等。這樣為的好檢查,防止數據類型的強制轉換或強制賦值時出現數據類型的錯誤;
注釋要充分;
代碼的布局風格宜統一,便于閱讀查找;
不可出現非受控的default流程,所有數值和變量,不論是調用函數時賦予的、讀取接口讀進來的、還是中間變量計算出來的,在應用前都宜作數據有效性的判斷,并對判定的所有可能結果均做受控的對應處理。
關于軟件可維護性編程方法方面的文章資料在網上是鋪天蓋地,不予贅述,綜合采用之即可。很多文章把軟件可維護性編程規范推薦做成企業的嵌入式軟件可靠性設計規范,實在是有點以偏概全,有失偏頗的,用一句娛樂圈的話來說,“愛情是生活的重要內容,但它不是生活的全部”,軟件可維護性編程方法亦然。
軟件代碼在執行中容易出現的下一個問題是跑飛,程序指針受到干擾,跳轉到了一個非受控位置,執行了不該執行的代碼。如果執行了不該執行的代碼,如果在程序中加入了足夠的變量判斷、讀值判斷、狀態檢測判斷等,那倒還好了,后果也不會太嚴重,甚至比較終還是可能自己跑回來的。但有一種跑飛是比較可怕的,一般我們在ROM中存放的程序目標代碼是1-3字節的指令,就是比較多3條字段的目標碼組成了執行動作,如果程序指針跑飛到了某個3字節指令的第2個字節上的時候,執行的后果是什么,可就真的沒人知道了,即使在程序上作了足夠的數據判錯、邏輯跳轉的防范措施,結果也不會好。而且ROM一般是不可能全部都被程序代碼填滿的,總有富余空間,富余空間中的默認內容是啥,這些默認字節是否也會導致一些操作呢?單片機中的默認空間是0FFH,DSP的我沒查過,大家有興趣查一下,跳到這些字段里,也是容易出麻煩的。
好了,不再羅嗦,直接給出解決方法吧,就是每隔一段程序代碼或控制區域,就人為放置上幾個NOP指令,在NOP指令后放置一個長跳轉的ERR處理程序。注意NOP比較少放置3個,這樣任何的跑飛比較多只能占用2個NOP,第三個NOP一樣還是能把程序代碼揪回來,揪回來后就執行ERR處理程序。
如果碰到安全性、可靠性等級要求比較高的程序,推薦的處理方法可以采用熱備份的處理方法,即用兩段代碼同時執行同一個功能,執行的結果進行對比,如果一致則放行通過,如果結果不一致,咋處理就看您的嘍。但是… …國人有的是辦法,為了圖省事,你領導不是要求我編熱備份程序嗎,那好,我就把原來的代碼復制一遍,重新插入到某個地方,您這和明朝時代馮保太監(還是嚴嵩、張居正阿?拿不準了,大家有興趣的翻看《明朝那些事兒》查閱下)玩的沒啥兩樣,自己寫奏章,自己給自己審批奏章。既然是備份就是為了防止一個人出問題,那比較好的辦法自然是不同的人來編這段,如果原理計算方法上也不同,數據采集通道也不同,那就過年帶娶媳婦的,好上加好了。
安全性和可靠性的編程細節注意事項還有很多,窺一斑難見全豹呵,諸位仁兄一起努力鉆研了。
【|中心,維修電話:15515598858 】