作者 | Elektor
譯者 | 禾沐
國(guó)內(nèi)嵌入式軟件開(kāi)發(fā)一直比較傳統(tǒng),除涉及關(guān)鍵系統(tǒng)外的多數(shù)項(xiàng)目,都是在“編程”優(yōu)先的開(kāi)發(fā)方式驅(qū)動(dòng)下實(shí)施的。
這背后的原因有很多,除了產(chǎn)品上市壓力大、建模和仿真工具價(jià)格不菲之外,還有一個(gè)重要因素——嵌入式
軟件開(kāi)發(fā)的思維方式轉(zhuǎn)變需要漫長(zhǎng)時(shí)間和教育過(guò)程才能完成。
本篇譯文詳細(xì)闡述了如何改變嵌入式軟件開(kāi)發(fā)思維方式,并結(jié)合幾款很實(shí)用的工具和汽車電子實(shí)例進(jìn)行了具體分析。
嵌入式軟件開(kāi)發(fā)者們總是喜歡躲開(kāi)關(guān)于
軟件架構(gòu)、
抽象化、
建模和
模擬的討論,直接開(kāi)始進(jìn)行編程,而嵌入式軟件代碼往往一旦發(fā)布就不能進(jìn)行改動(dòng)了,出錯(cuò)的余地非常小。
既然我們都知道測(cè)試對(duì)嵌入式軟件非常重要,也有很多進(jìn)行建模/仿真的工具,那么,為什么還會(huì)先編程,然后等待很久才開(kāi)始測(cè)試呢?
啄木鳥(niǎo)帶來(lái)的危險(xiǎn)
那是一次“原來(lái)是這樣!”的頓悟。當(dāng)時(shí)正在為了一個(gè)培訓(xùn)課程進(jìn)行準(zhǔn)備,我在想,為什么嵌入式軟件工程師如此不愿意使用在其他軟件開(kāi)發(fā)過(guò)程中常見(jiàn)的概念和方法呢?
在微控制器相關(guān)的工程中,我時(shí)常會(huì)遇到這樣的工程師:他們既不定義代碼風(fēng)格標(biāo)準(zhǔn)(盡管軟件開(kāi)發(fā)有多個(gè)工程師參與),也不會(huì)定義任何幫助提高代碼可移植性和可用性的設(shè)計(jì)準(zhǔn)則,更不會(huì)關(guān)心面向?qū)ο笤O(shè)計(jì)、建模和仿真。
我的腦海中浮現(xiàn)出了下面這句話:“
如果木匠用程序員編程的方法建造建筑,只需要一只啄木鳥(niǎo)就可以摧毀整個(gè)人類文明?!?
這句話從溫伯格法則稍微修改而來(lái),它著實(shí)引起了我的共鳴。為什么嵌入式軟件開(kāi)發(fā)者們不
借鑒計(jì)算機(jī)科學(xué)研究成果,使用正確的方式構(gòu)建代碼,或者借力建模/仿真技術(shù)呢?
編程太快了嗎?
一個(gè)原因可能是來(lái)自這一代程序員的經(jīng)歷。他們的生涯從資源受限的8位微控制器開(kāi)始,用匯編語(yǔ)言最高程度地利用硬件的性能是王道,抽象化和工具自動(dòng)生成的代碼只能意味著代碼冗余和失去對(duì)代碼的完全控制。轉(zhuǎn)移到C語(yǔ)言對(duì)于一些人來(lái)說(shuō)都有難度,盡管C語(yǔ)言已經(jīng)非常貼近硬件了。
另一個(gè)角度是C語(yǔ)言的教學(xué)方式往往注重語(yǔ)法,而不是如何最佳地使用這門語(yǔ)言。但是,就像自然語(yǔ)言一樣,精通語(yǔ)法并不能讓你成為一位演說(shuō)家。
物聯(lián)網(wǎng)(IoT)應(yīng)用出現(xiàn)以前,升級(jí)微控制器的固件基本意味著親自前往設(shè)備的所在地,代碼出錯(cuò)的余地非常小。即便如此,許多嵌入式程序員的開(kāi)發(fā)方式也始終沒(méi)有改變。
推廣新的開(kāi)發(fā)方式?
過(guò)去,運(yùn)行在微控制器上的代碼往往可以用一個(gè)簡(jiǎn)單的
狀態(tài)機(jī)表示,如今微控制器需要解決多維的問(wèn)題。今天的微控制器可以通過(guò)磁場(chǎng)導(dǎo)向控制(FOC)技術(shù)對(duì)電動(dòng)機(jī)進(jìn)行換向操作,并同時(shí)運(yùn)行其他任務(wù)。
雖然相關(guān)的代碼已經(jīng)存在,但是,實(shí)時(shí)確定電動(dòng)機(jī)的角度和計(jì)算下次換向的時(shí)機(jī)就已經(jīng)非常復(fù)雜了。
這樣的微控制器如果出現(xiàn)在家用洗衣機(jī)中的話,我們還需要考慮IEC 60730標(biāo)準(zhǔn)(自動(dòng)電子控制 – 第1部分:一般要求)。大多數(shù)微控制器廠商會(huì)提供能夠執(zhí)行CPU寄存器、程序計(jì)數(shù)器、內(nèi)存完整性和時(shí)鐘測(cè)試的“B類”庫(kù),庫(kù)代碼應(yīng)該在運(yùn)行實(shí)時(shí)電動(dòng)機(jī)控制的同時(shí)執(zhí)行。
系統(tǒng)中一般還會(huì)有能快速響應(yīng)的通訊接口和人機(jī)交互界面,嵌入式開(kāi)發(fā)者也許可以保證每個(gè)部分都能單獨(dú)運(yùn)行,但是
整合在一起后系統(tǒng)是否依然可靠呢?
一個(gè)選項(xiàng)是用
統(tǒng)一建模語(yǔ)言(UML)針對(duì)應(yīng)用進(jìn)行建模并運(yùn)行仿真。嵌入式軟件開(kāi)發(fā)者往往非常不喜歡這種方式,他們認(rèn)為這樣做是浪費(fèi)時(shí)間:如果有時(shí)間建模和運(yùn)行仿真,還不如直接把代碼寫出來(lái)。
一些人還在系統(tǒng)設(shè)計(jì)中濫用UML,導(dǎo)致UML染上了不好的名聲。抽象的設(shè)計(jì)方式還意味著不同的開(kāi)發(fā)過(guò)程,說(shuō)服一個(gè)開(kāi)發(fā)團(tuán)隊(duì)轉(zhuǎn)變開(kāi)發(fā)過(guò)程并不是一件容易的事情。
對(duì)于在設(shè)計(jì)和實(shí)現(xiàn)中各編程一次的擔(dān)心,我們稱為過(guò)程的不連續(xù)性(phase discontinuity)。理想狀況下,建模過(guò)程應(yīng)該解決這一問(wèn)題,比如實(shí)時(shí)面向?qū)ο蠼#≧OOM)領(lǐng)域特定語(yǔ)言(DSL)。
ROOM專門針對(duì)事件驅(qū)動(dòng)的實(shí)時(shí)系統(tǒng),它支持建模和模擬,還能夠生成針對(duì)目標(biāo)硬件的代碼。
ROOM從三個(gè)維度描述軟件:結(jié)構(gòu)、行為和繼承。結(jié)構(gòu)可以用角色(actor)通過(guò)端口(port)互相通信表示,消息通過(guò)運(yùn)行時(shí)軟件庫(kù)進(jìn)行傳遞。角色的行為通過(guò)多層有限狀態(tài)機(jī)進(jìn)行表示,并可以圖表形式輸出。
進(jìn)入和離開(kāi)狀態(tài)的代碼可以用代碼生成器(比如針對(duì)微控制器的C編譯器)的目標(biāo)語(yǔ)言進(jìn)行定義。當(dāng)端口接收消息或者收到回應(yīng)時(shí),狀態(tài)改變會(huì)發(fā)生。
繼承提供了ROOM中面向?qū)ο蟮牟糠?,既將角色看作可以多次?shí)例化的類。每個(gè)實(shí)例繼承狀態(tài)機(jī),需要的話,狀態(tài)機(jī)還可以進(jìn)一步擴(kuò)展。最后一個(gè)概念是分層(layering),它允許應(yīng)用互相進(jìn)行通信,或者通過(guò)服務(wù)訪問(wèn)點(diǎn)(SAP)使用服務(wù)(比如定時(shí)器)。
Eclipse集成開(kāi)發(fā)環(huán)境插件eTrice支持這一
軟件開(kāi)發(fā)方式。模型可以通過(guò)圖形或者文本創(chuàng)建,并可以輸出C、C 或者Java代碼。在模型上運(yùn)行模擬將會(huì)輸出消息序列圖(MSC),UML工具Trace2UML(Astade[8]的一部分)可以將序列圖進(jìn)行可視化。
圖1所示的是一個(gè)簡(jiǎn)單的“乒乓” 樣例應(yīng)用,其中定時(shí)器SAP決定了響應(yīng)延遲的時(shí)間。通過(guò)圖像和ROOM DSL可以檢查應(yīng)用的結(jié)構(gòu)和行為。執(zhí)行模型將會(huì)在命令行上輸出結(jié)果,模擬的輸出是MSC(見(jiàn)圖2)。
圖1 eTrice“乒乓”樣例工程,可以看到“乒”和“乓”的角色(左)以及它們的行為(右)
圖2 在“乒乓”模型上運(yùn)行模擬所產(chǎn)生的消息序列圖
為什么測(cè)試開(kāi)始得很晚?
在匆匆開(kāi)始編程之后,許多嵌入式開(kāi)發(fā)團(tuán)隊(duì)往往會(huì)等到已經(jīng)編寫了不少代碼后才考慮開(kāi)始測(cè)試問(wèn)題,這樣做的背后有很多繁雜的原因,比如錯(cuò)誤地認(rèn)為測(cè)試必須由一個(gè)團(tuán)隊(duì)或者部門負(fù)責(zé),或是缺乏清晰、易于測(cè)試的軟件需求。
集成開(kāi)發(fā)環(huán)境強(qiáng)大的調(diào)試器也可能讓我們產(chǎn)生了虛假的安全感。
Lisa Simone在《If I Only Changedthe Software, Why is the Phone on Fire?》一書(shū)[9]中用幽默的方式探討了程序錯(cuò)誤帶來(lái)的后果。在一個(gè)例子中,不當(dāng)?shù)臄?shù)據(jù)類型導(dǎo)致了溫度控制算法的錯(cuò)誤。
雖然Simone完整地描述了尋找這類問(wèn)題根源的過(guò)程,但事實(shí)上,這些問(wèn)題在單元測(cè)試中就應(yīng)該被發(fā)現(xiàn)。
單元測(cè)試是一種白盒風(fēng)格測(cè)試,即編寫測(cè)試的工程師有源代碼的知識(shí),往往編寫者就是源代碼的作者。在微控制器上,單元測(cè)試需要一個(gè)能夠執(zhí)行測(cè)試和分析輸出的應(yīng)用,最終結(jié)果往往通過(guò)串口輸出到控制臺(tái)上。
這意味著,我們需要能夠執(zhí)行測(cè)試的硬件平臺(tái)。Arduino和其他類似的平臺(tái)提供UART到USB轉(zhuǎn)換,這讓在控制臺(tái)上輸出測(cè)試結(jié)果變得更容易。但是,針對(duì)每個(gè)軟件模塊開(kāi)發(fā)和維護(hù)一個(gè)測(cè)試應(yīng)用確實(shí)是很大的工作量。
iSYSTEM開(kāi)發(fā)的testIDEA提供了顯著降低測(cè)試難度的方法。iSYSTEM開(kāi)發(fā)的調(diào)試工具意味著開(kāi)發(fā)環(huán)境不僅能訪問(wèn)源代碼,還可以通過(guò)調(diào)試接口訪問(wèn)微控制器的環(huán)境。使用testIDEA只需要提供能夠?qū)懭胛⒖刂破鏖W存的編譯過(guò)的應(yīng)用代碼(ELF格式)。
在testIDEA中定義的測(cè)試用預(yù)定義的參數(shù)單獨(dú)測(cè)試函數(shù)(圖3)。在軟件中我們能夠任意修改RAM,從而注入任何類型的數(shù)據(jù)和指針。
測(cè)試的通過(guò)與否取決于函數(shù)的的返回值是否正確,測(cè)試中還可以通過(guò)跟蹤功能提供代碼覆蓋的數(shù)據(jù)。
工具中有對(duì)C 的支持,但是在測(cè)試各類方法之前需要先調(diào)用構(gòu)造函數(shù)。測(cè)試還可以輸出進(jìn)入Python環(huán)境,幫助測(cè)試的自動(dòng)化。
圖3 通過(guò)testIDEA測(cè)試在微控制器上運(yùn)行的軟件函數(shù)
testIDEA的一大功能是所有內(nèi)部和私有變量值都可以在測(cè)試時(shí)進(jìn)行注入,當(dāng)你調(diào)試時(shí)可以想做什么就做什么。
這對(duì)于在編譯中優(yōu)化過(guò)的代碼非常有幫助:我們都知道無(wú)用代碼的移除和代碼段的重組意味著優(yōu)化后代碼的行為和優(yōu)化前并不完全一致,換言之,代碼和二進(jìn)制代碼的關(guān)系會(huì)變得模糊,這讓調(diào)試變得更加有挑戰(zhàn)性。
通過(guò)在testIDEA中運(yùn)行同樣的測(cè)試,你可以在進(jìn)行系統(tǒng)整合前確定基礎(chǔ)代碼的行為沒(méi)有變化。
多少測(cè)試才足夠?
對(duì)初次接觸測(cè)試的工程師來(lái)說(shuō),確定最佳的策略并不簡(jiǎn)單。像《愛(ài)麗絲夢(mèng)游仙境》中的兔子洞一深入研究測(cè)試的方法,你會(huì)覺(jué)得需要測(cè)試的東西越來(lái)越多。
軟件的多維性和復(fù)雜的依賴關(guān)系意味著我們很難預(yù)估多少測(cè)試是足夠的。參與過(guò)安全關(guān)鍵項(xiàng)目的工程師都知道,相關(guān)的標(biāo)準(zhǔn)都不是絕對(duì)的,比如汽車相關(guān)的ISO 26262和醫(yī)療相關(guān)的ISO 14971、IEC 60601。
舉例來(lái)說(shuō),ISO 26262“非常推薦”代碼分支覆蓋作為測(cè)試覆蓋的基準(zhǔn),然后只是“推薦”語(yǔ)句覆蓋和MC/DC(修改條件、決策覆蓋)。只有和測(cè)試領(lǐng)域的專家合作,才能確定在你的應(yīng)用中如何測(cè)試才是最佳的。
為了確保代碼的全部分支都被覆蓋,所有可能的代碼組合都要被測(cè)試到,我們可以借助sepp.med GmbH公司的MBTsuite產(chǎn)品。其基于模型的測(cè)試框架能夠幫助確定所有可能的測(cè)試組合,因而非常適合系統(tǒng)集成和測(cè)試。
確定測(cè)試范圍的第一步是將系統(tǒng)需求輸入到Enterprise Architect這類的工具中。接下來(lái)構(gòu)造系統(tǒng)的模型,將其和系統(tǒng)需求鏈接在一起。設(shè)計(jì)中較為復(fù)雜的部分可以用子模型來(lái)表示,從而保持模型整體的抽象程度和簡(jiǎn)潔性(見(jiàn)圖4和圖5)。
圖4 電子駐車制動(dòng)裝置的EnterpriseArchitect模型
圖5 釋放剎車部分的Enterprise Architect子模型,可以看到模型到要求間的鏈接
接下來(lái)將完成的模型導(dǎo)入到MBTsuite中。軟件允許你定義不同的測(cè)試策略,全路徑覆蓋(Full Path Coverage)會(huì)生成覆蓋整個(gè)模型的測(cè)試方案,最短路覆蓋(Shortest Path)用最短的路徑遍歷模型(見(jiàn)圖6)。
此外,隨機(jī)策略可以幫助發(fā)現(xiàn)形式化策略可能無(wú)法發(fā)現(xiàn)的問(wèn)題,也可以作為在目標(biāo)硬件上驗(yàn)證測(cè)試機(jī)制的冒煙測(cè)試(smoke test )的一部分。
圖6 MBTsuite中電子駐車剎車的模型產(chǎn)生全路徑覆蓋測(cè)試方案
從電子駐車剎車(EPB)的模型(見(jiàn)圖4)可以看出,遍歷節(jié)點(diǎn)的過(guò)程中可能會(huì)進(jìn)入無(wú)限循環(huán)。循環(huán)數(shù)目(number of loop)和最長(zhǎng)路徑長(zhǎng)度(maximum path length)參數(shù)可以用來(lái)避免這一情況的產(chǎn)生。你也可以通過(guò)指定模型的區(qū)域來(lái)生成針對(duì)特定功能的測(cè)試。
MBTsuite最簡(jiǎn)單的用法是產(chǎn)生Word或Excel文檔詳述測(cè)試的步驟和各個(gè)驗(yàn)證點(diǎn)預(yù)期的結(jié)果,手動(dòng)測(cè)試時(shí)可以勾選每一步的完成情況,最終給出通過(guò)/失敗的結(jié)果。自動(dòng)化測(cè)試的情形下,軟件根據(jù)模板生成合適的格式,比如Python代碼。
在硬件上快速測(cè)試
理想條件下,應(yīng)用在開(kāi)發(fā)過(guò)程中應(yīng)該進(jìn)行硬件在環(huán)(HIL)測(cè)試,這對(duì)于在高壓、高電流或者有活動(dòng)部件的環(huán)境中運(yùn)行的應(yīng)用尤其重要。
但是,這樣的測(cè)試機(jī)制可能會(huì)很昂貴,許多團(tuán)隊(duì)也可能需要在同一套硬件上測(cè)試多種產(chǎn)品。其結(jié)果是HIL測(cè)試的瓶頸效應(yīng)導(dǎo)致測(cè)試直到開(kāi)發(fā)末期才進(jìn)行。在當(dāng)前新冠疫情的影響下,HIL測(cè)試甚至可能完全無(wú)法進(jìn)行。
為了應(yīng)對(duì)這一挑戰(zhàn),PROTOS Software GmbH開(kāi)發(fā)了miniHIL平臺(tái)。平臺(tái)包括一個(gè)A4紙大小的硬件板,其上右側(cè)是安裝STM32 Nucleo開(kāi)發(fā)板的位置,左側(cè)有一個(gè)強(qiáng)力的STM32H743微控制器,中間則是連接兩側(cè)的針腳矩陣。
STM32H743的作用是模擬STM32 Nucleo控制的設(shè)備,并產(chǎn)生同樣的信號(hào)。這一平臺(tái)非常適用于在沒(méi)有實(shí)體洗衣機(jī)或者電鉆的情況下測(cè)試電動(dòng)機(jī)控制應(yīng)用。
miniHIL環(huán)境支持eTrice和CaGe(Case Generator)語(yǔ)言進(jìn)行測(cè)試的開(kāi)發(fā)。這既讓開(kāi)發(fā)者可以快速檢查代碼改動(dòng)的正確性,也允許整個(gè)平臺(tái)和持續(xù)集成(CI)平臺(tái)相結(jié)合,比如Jenkins。這樣一來(lái),自動(dòng)測(cè)試可以定期在硬件上執(zhí)行,比如每晚執(zhí)行測(cè)試,第二天一早在儀表盤上檢查結(jié)果(見(jiàn)圖7)。
圖7 miniHIL和運(yùn)行Jenkins持續(xù)集成平臺(tái)服務(wù)器的PC整合(來(lái)源:PROTOS SoftwareGmbH)
尋找偶發(fā)失效
今天的汽車應(yīng)用非常復(fù)雜,在一輛汽車上運(yùn)行的代碼量和Windows NT類似。代碼開(kāi)發(fā)的分布性意味著很多供應(yīng)商(甚至客戶)都參與到了其中。偶發(fā)的失效往往和定時(shí)有關(guān),而不是功能,多核處理器和虛擬機(jī)的廣泛應(yīng)用更是加劇了這一情況。
即使在測(cè)試充分的情況下,即將發(fā)貨的硬件上,甚至是客戶環(huán)境中,奇怪的事情還是時(shí)而發(fā)生。一個(gè)汽車電子的實(shí)例:兩個(gè)通過(guò)CAN總線相連的電子控制單元(ECU)會(huì)偶發(fā)錯(cuò)誤,ECU A和B連接偶爾會(huì)出錯(cuò),但是和C連接不會(huì),ECU B和C能正常協(xié)同工作。
問(wèn)題的根本原因是ECU石英頻率的微小不同,運(yùn)行時(shí)間足夠長(zhǎng)的情況下,兩個(gè)微控制器的時(shí)鐘差異會(huì)導(dǎo)致CAN消息的偶爾丟失。
Inchron AG[17]的chronSIM和chronVIEW,以及Vector InfomatikGmbH的TA Tool Suite等工具將定時(shí)看得和功能一樣重要。它們?cè)试S在編寫任何代碼前在目標(biāo)系統(tǒng)上構(gòu)建模型,從而幫助系統(tǒng)架構(gòu)師針對(duì)多種不同的硬件設(shè)計(jì)最佳的系統(tǒng)架構(gòu)。
這些工具會(huì)分析在不同處理器核上運(yùn)行代碼的影響,這對(duì)于在核心頻率不同的異構(gòu)多核處理器上運(yùn)行的應(yīng)用而言至關(guān)重要。最后,工具分析事件鏈(見(jiàn)圖8),并測(cè)量事件從傳感器到達(dá)系統(tǒng),并最終到達(dá)執(zhí)行器的時(shí)間。這些工作對(duì)于整合若干數(shù)據(jù)速率不同的傳感器數(shù)據(jù)的自動(dòng)駕駛系統(tǒng)而言尤為重要。
圖8 Inchron Tool Suite通過(guò)建模、仿真和分析等方法突出定時(shí)的重要性,圖中展示的是一個(gè)事件鏈的分析(來(lái)源:INCHRON AG)
通過(guò)定義代碼段的超時(shí)時(shí)間,以及同時(shí)注意功能和定時(shí)特性,與時(shí)間相關(guān)的ECU通過(guò)CAN連接的問(wèn)題可以在設(shè)計(jì)層面上解決。在模型中,可以理解時(shí)鐘頻率變動(dòng)、核心分配、代碼執(zhí)行時(shí)間和時(shí)鐘頻率變化的影響。
這些工具還可以分析在實(shí)際硬件上運(yùn)行的微控制器產(chǎn)生的跟蹤數(shù)據(jù),檢查在不同測(cè)試條件下代碼段的執(zhí)行時(shí)間是否合乎需求。
是更加重視建模的時(shí)候了?
嵌入式軟件開(kāi)發(fā)領(lǐng)域一直比較傳統(tǒng)?!凹庇诰幊獭钡乃季S方式被微控制器供應(yīng)商提供的編程和調(diào)試工具鏈所加劇,這些工具多是免費(fèi)的,這樣一來(lái)其他付費(fèi)授權(quán)的工具鏈就失去了存在的意義。
支持嵌入式系統(tǒng)建模和仿真的工具提供了一個(gè)在開(kāi)始編程前后退一步、進(jìn)一步抽象化的機(jī)會(huì)。這一方式的背后是重復(fù)性的分析和測(cè)試,它因此可以幫助在開(kāi)發(fā)太過(guò)深入前以較低的成本糾正設(shè)計(jì)上的問(wèn)題。
桌面HIL還允許通過(guò)壓縮的測(cè)試周期快速驗(yàn)證小的代碼改動(dòng),而不是在整合后的代碼上運(yùn)行完整的測(cè)試。最后,雖然最復(fù)雜的實(shí)時(shí)應(yīng)用(比如汽車)開(kāi)發(fā)中建模和測(cè)試手段已經(jīng)被廣為應(yīng)用,我們還是應(yīng)該在功能要求的基礎(chǔ)上添加定時(shí)的要求。
采用這些基于模型的工具的最大挑戰(zhàn),是對(duì)改變的畏懼。它們的抽象性讓傳統(tǒng)嵌入式開(kāi)發(fā)者不得不離開(kāi)他們熟悉和喜歡的硬件,前往一個(gè)陌生的地方。它們還需要開(kāi)發(fā)過(guò)程做出改變,這導(dǎo)致了很多負(fù)面的意見(jiàn)。
這些工具從紙面上看非常合理,但只有真正開(kāi)始使用,我們才能知道在實(shí)際操作中它們帶來(lái)的益處。許多此類工具已經(jīng)存在了十年或者更久,它們的地位和作用已經(jīng)建立起來(lái)了。
這些工具可以降低開(kāi)發(fā)時(shí)間和開(kāi)銷、提高產(chǎn)品的質(zhì)量,開(kāi)發(fā)者們需要從實(shí)際的開(kāi)發(fā)過(guò)程出發(fā),分析這類選項(xiàng)是否適用于他們的產(chǎn)品。
相關(guān)鏈接
[1]https://quoteinvestigator.com/2019/09/19/woodpecker/.
[2]IEC 60730-1:2013. https://webstore.iec.ch/publication/3117.
[3]例如Hitex B類庫(kù):http://www2.hitex.com/dl-classb-sam-d2x.
[4]A. E. Bell. Death by UML Fever. https://queue.acm.org/detail.cfm?id=984495.
[5]B. Selic, G. Gullekson, P. Ward, Real-TimeObject-Oriented Modeling, Wiley, 1994.
[6]https://en.wikipedia.org/wiki/Real-Time_Object-Oriented_Modeling.
[7]https://www.eclipse.org/etrice/downloads/.
[8]https://wiki.astade.de/dokuwiki/doku.php?id=start.
[9]L. Simone, If I Only Changed the Software,Why is the Phone on Fire?, Newnes, 2007.
[10]https://www.isystem.com/products/software/testidea.html.
[11]Feabhas Ltd, “A Quick Guide to ISO 26262,”2016. https://www.feabhas.com/sites/default/files/2016-06/A quick guide to ISO 26262[1]_0_0.pdf.
[12]https://mbtsuite.com/.
[13]https://sparxsystems.com/.
[14]https://docs.protossoftware.de/minihil/latest/Reference/CaGe/index.html.
[15]https://www.jenkins.io/.
[16]https://www.visualcapitalist.com/millions-lines-of-code/.
[17]https://www.inchron.com/.
[18]https://www.vector.com/int/en/products/products-a-z/software/ta-tool-suite/.
往期推薦:
往期推薦
實(shí)用 | 一個(gè)簡(jiǎn)單易用的菜單框架
實(shí)用 | 手頭上無(wú)LCD卻又急著開(kāi)發(fā)UI?LCD模擬器了解一下~
基于EasyX寫的一個(gè)小應(yīng)用,源碼拿走不謝~
分享一款嵌入式人必備繪圖工具,讓你的工作匯報(bào)更精彩!(附安裝、踩坑、填坑教程)
基于vs2019的lvgl模擬器使用
wireshark抓包工具的使用及分析