free性丰满hd毛多多,久久综合给合久久狠狠狠97色69 ,欧美成人乱码一区二区三区,国产美女久久久亚洲综合,7777久久亚洲中文字幕

0
問答首頁 最新問題 熱門問題 等待回答標(biāo)簽廣場
我要提問

嵌入式

豐田栽了的原因,嵌入式軟件工程師都該看看

【第一部分】背景簡介

前幾年鬧得沸沸揚(yáng)揚(yáng)的豐田剎不住事件最近又有新進(jìn)展。十月底俄克拉荷馬的一次庭審,2007年一輛2005年凱美瑞暴沖(Unintended Acceleration,UA)致一死一傷事件中豐田被判有責(zé)。引起廣泛關(guān)注的是庭審中主要證人Michael Barr的證詞讓陪審團(tuán)同意豐田的動力系統(tǒng)軟件存在巨大漏洞可能導(dǎo)致此類事件。這是豐田在同類事件中第一次被判有責(zé)。庭審過后豐田馬上同意支付300萬美元進(jìn)入調(diào)解程序。

出于好奇,我漫不經(jīng)心地下載了Barr的286頁證詞,卻一下子被吸引住了。幾天內(nèi)讀完,算是對這次事件進(jìn)行了一次深入了解。下面就從外行角度總結(jié)一下這份證詞并嘗試以更簡單的語言解釋里面提到的暴沖原因以及豐田犯下的錯誤。

Barr的證詞下載自他的個人博客Barr Code,但現(xiàn)在該文已經(jīng)被刪除。稍后找地方上傳。

Michael Barr是誰?他是一位擁有20年以上行業(yè)經(jīng)驗(yàn)的嵌入式系統(tǒng)工程師。在十八個月中,有12位嵌入式系統(tǒng)專家,包Barr,受原告訴訟團(tuán)所托,被關(guān)在馬里蘭州一間高度保安的房間內(nèi)對豐田動力控制系統(tǒng)軟件(主要是2005年的凱美瑞)源代碼進(jìn)行深度審查。這房間沒有英特網(wǎng),沒有手機(jī)信號,他們進(jìn)出不能攜帶任何紙張、記錄甚至皮帶。最后的調(diào)查結(jié)果被寫入一份800頁,13章的詳細(xì)報(bào)告。而鑒于保密協(xié)議,調(diào)查內(nèi)容一直沒有公布,直至俄克拉荷馬這次庭審才首度部分公開(報(bào)告本身似乎還沒公開)。

回到正題。豐田的軟件有沒有缺陷?根據(jù)Barr的調(diào)查,答案是有。這其實(shí)是廢話,任何軟件都會有缺陷,關(guān)鍵在于是什么樣的缺陷。豐田的軟件缺陷分為三類:

非常業(yè)余的結(jié)構(gòu)設(shè)計(jì)。

軟件設(shè)計(jì)的基本要求是模塊盡量簡單化,因?yàn)檫@樣可以一來更易于閱讀二來更易于維護(hù)。但豐田的工程師顯然沒有遵循這原則。Barr使用一種工具自動根據(jù)代碼的可能分支數(shù)量評估函數(shù)的復(fù)雜度,結(jié)果是豐田的軟件中至少有67條函數(shù)復(fù)雜度超過50,意味著運(yùn)行這個函數(shù)可能出現(xiàn)超過50種不同的執(zhí)行結(jié)果,屬于“非可測”級別。因?yàn)闉榱藴y試這50個不同的結(jié)果,必須準(zhǔn)備至少50條不同的測試用例以及相應(yīng)的文檔,在生產(chǎn)環(huán)境中一般是不現(xiàn)實(shí)的。作為比較,Barr表示他自己的公司嚴(yán)格執(zhí)行的其中一條規(guī)定就是任何代碼復(fù)雜度不能超過30,否則不合格。而在這67條函數(shù)中還有12條復(fù)雜度超過100,達(dá)到“非可維護(hù)”級別,意味著一旦發(fā)現(xiàn)缺陷(Bug)也無法修復(fù),因?yàn)閷?shí)在太復(fù)雜,修復(fù)缺陷的過程中會產(chǎn)生新的缺陷。其中最復(fù)雜的一條函數(shù)有超過1300行代碼,146個可能執(zhí)行路徑——正好用于根據(jù)各傳感器數(shù)值計(jì)算節(jié)氣門開關(guān)角度。

如果你不知道什么是節(jié)氣門,那么這里我稍微解釋一下。為了讓內(nèi)燃機(jī)運(yùn)行,有三大要素:燃油、空氣和點(diǎn)火時機(jī)??諝夂腿加偷幕旌衔镞M(jìn)入氣缸,被火花塞在正確的時間點(diǎn)燃推動活塞并最終推動曲軸和車輪前進(jìn)。在電噴技術(shù)發(fā)明以后直到2002年以前,三大要素的燃油和點(diǎn)火時間是由電子設(shè)備控制,節(jié)氣門機(jī)械連接加速踏板,由司機(jī)直接控制。節(jié)氣門大致是一個連接加速踏板的“空氣龍頭”——踩下去越多,“龍頭”打開得越大,允許越多的空氣進(jìn)入發(fā)動機(jī)輸出更大的動力。2002年以后,豐田引入的“電子油門”讓電子系統(tǒng)掌管了最后一個要素:空氣。加速踏板不再機(jī)械連接節(jié)氣門,而是連接一些傳感器,由行車電腦將這些傳感器數(shù)值計(jì)算成節(jié)氣門開啟角度再由馬達(dá)控制節(jié)氣門。我們稍后會再討論節(jié)氣門開合。

極復(fù)雜的代碼帶來的是極復(fù)雜的功能。下面說一下被稱為“廚房洗滌盆”的Task X。這里先解釋一下,豐田的軟件系統(tǒng)和很多別的軟件系統(tǒng)一樣,都是由一個統(tǒng)領(lǐng)程序(稱之為“操作系統(tǒng)”)和若干小程序(稱之為Task)組成。就好比電腦上跑的Windows是統(tǒng)領(lǐng)全局的操作系統(tǒng),網(wǎng)絡(luò)瀏覽器和記事本是跑在操作系統(tǒng)上的小程序。豐田的系統(tǒng)里每個Task都有自己的名字,但這些名字非常敏感,敏感到每次被提及的時候律師都要求法庭內(nèi)的沒有閱讀代碼權(quán)限的人全部清場。為了減少清場次數(shù),Barr將這個最重要的小程序稱為Task X。這個Task X有多重要呢?跟廚房里的洗滌盆一樣重要。它負(fù)責(zé)非常多的事情,包括計(jì)算節(jié)氣門開啟角度、速度監(jiān)測和保持、定速巡航監(jiān)測等等。Task X的不正常運(yùn)行被認(rèn)為是暴沖事件的元兇。稍后會再繼續(xù)討論Task X。

還有一些別的匪夷所思的發(fā)現(xiàn)。比如豐田的軟件包含了超過一萬一千個全局變量。如果你不知道什么是全局變量,那么只需要知道軟件設(shè)計(jì)的一般原則是要盡量少使用全局變量,因?yàn)橛锌赡軒頍o法預(yù)測的結(jié)果。這里的“少”的意思是“盡量接近零”,絕對不會是一萬一千個。

不符合軟件開發(fā)規(guī)范。

如同很多行業(yè)一樣,汽車行業(yè)也有自己的規(guī)范。更具體一點(diǎn),由于汽車的危險性質(zhì),汽車控制系統(tǒng)被劃分為“安全關(guān)鍵性系統(tǒng)(Safety Critical System)”——說白了就是安全性非常重要,弄不好會死人的。為了達(dá)到這一特殊要求,汽車相關(guān)軟件開發(fā)人員定期舉行會議討論并發(fā)布編程規(guī)范,稱為MISRA C。該規(guī)范的2004年版的感謝列表里還能看到豐田員工的名字,至少讓外界認(rèn)為豐田確實(shí)也在遵循這些規(guī)范。

真的嗎?根據(jù)源代碼來看,答案是否定的。對此之前的NASA報(bào)告也有所提及,豐田辯稱他們遵循的不是行業(yè)規(guī)范,而是豐田內(nèi)部編程規(guī)范。這一規(guī)范與行業(yè)規(guī)范的吻合程度達(dá)到50%。但是Barr認(rèn)為根據(jù)他的調(diào)查,兩個規(guī)范之間吻合度小于10%,甚至有若干規(guī)范條目相互沖突。后來發(fā)現(xiàn)豐田的代碼甚至沒有遵循豐田內(nèi)部規(guī)范,當(dāng)然比起別的問題這個已經(jīng)無關(guān)緊要了。

MISRA C擁有超過100條規(guī)范,NASA的調(diào)查只使用了到其中35條進(jìn)行校對,發(fā)現(xiàn)超過7000處違規(guī)代碼。Barr使用全部條目,對照結(jié)果是豐田的程序擁有超過80000處違規(guī)代碼。

這些數(shù)字說明了什么?根據(jù)統(tǒng)計(jì),違規(guī)數(shù)量可以用于預(yù)測代碼中暗藏的缺陷(Bug)數(shù)量。在之前提到的汽車相關(guān)軟件開發(fā)人員會議中,有人就這一主題發(fā)表過專題演講,提出每30處違規(guī)代碼可能包含一個重大缺陷和十個輕微缺陷。諷刺的是這人是豐田員工。

特別需要指出MISRA C其中一個規(guī)則的內(nèi)容是不得使用遞歸。

如果你不知道什么是遞歸,那么這里我稍微解釋一下。遞歸是一種計(jì)算方法。但一般計(jì)算方法要么是自己算,要么詢問別的計(jì)算模塊索要結(jié)果。而遞歸則是通過問一層層問自己的方法完成計(jì)算。好處是代碼簡單,壞處是計(jì)算層數(shù)不固定??赡軙?層就出結(jié)果了,也可能會是10000層,在設(shè)計(jì)程序的時候無從得知。

軟件計(jì)算需要消耗存儲器。越繁瑣、越長的計(jì)算自然需要占用越多的存儲器。遞歸的問題在于其嵌套層數(shù)無法預(yù)測,從而導(dǎo)致可能消耗的存儲器容量無法控制。稍后會再討論存儲器。

對關(guān)鍵變量缺乏保護(hù)。

什么是變量?變量就是存在一段存儲器的0和1的集合。這些變量既可以是一些函數(shù)的處理結(jié)果,也可以是另一些函數(shù)的處理原材料。比方說前面提到有一條程序?qū)iT計(jì)算節(jié)氣門開合角度,比如說是20度,這個20就是一個變量,存在存儲器的一個指定位置。另一個程序?qū)iT負(fù)責(zé)開合節(jié)氣門,它知道去那個指定位置讀取這個20,然后把節(jié)氣門開啟20度。

什么是保護(hù)?嵌入式系統(tǒng),或者任何系統(tǒng),都會在一定條件下發(fā)生硬件或者軟件錯誤。客觀上這是無法避免的。而且汽車作為一個時常在震動、發(fā)熱、位移的系統(tǒng),它的內(nèi)部環(huán)境不能說不惡劣,發(fā)生硬件錯誤的可能性甚至更高。什么樣的硬件錯誤呢?別忘了變量都是0和1的組合,這些0和1由存儲器上的高低電平代表。由于某些不可抗原因,一個電平從高變成低,或者反過來,那么這個變量就被更改了。這被稱為“位反轉(zhuǎn)(Bit Flip)”。為了對抗這樣的事情發(fā)生,需要對變量進(jìn)行保護(hù)。保護(hù)的方法一般是鏡像法。簡單來說就是在兩個不同的地方寫入同一個變量,讀取的時候兩邊都讀,比較是不是一致。如果不一致,那么可以得知這個變量已經(jīng)不可靠,需要進(jìn)行容錯處理。

豐田的程序總體上對其上萬個變量進(jìn)行了有效保護(hù),但問題出在操作系統(tǒng)上。前面提到豐田的軟件本質(zhì)上分為操作系統(tǒng)和Task。Task是由豐田自己開發(fā),但是操作系統(tǒng)則是由芯片供應(yīng)商提供,固化在芯片里的。豐田在這里的過失是沒有對供應(yīng)商提供的代碼進(jìn)行深度審核,拿到什么用什么。

另一個保護(hù)措施是錯誤校驗(yàn)碼(Error Detective and Correction Codes,EDAC)。這是一個硬件層面的數(shù)據(jù)保護(hù)措施。簡而言之就是給內(nèi)存中每一個字節(jié)(8比特)后面物理地增加幾比特校驗(yàn)碼。這樣萬一變量出錯了,可以通過校驗(yàn)碼得知,甚至可以通過校驗(yàn)碼修復(fù)一些輕微錯誤。這個措施十分簡單有效,但是在2005年款凱美瑞的系統(tǒng)中完全沒有使用,豐田卻告訴NASA他們用了。而在2008年款凱美瑞中使用了3比特長的EDAC。Barr認(rèn)為是為了節(jié)省成本,否則應(yīng)該使用5比特長。

還有值得一提的是,汽車相關(guān)的軟件行業(yè)有那么幾家操作系統(tǒng)供應(yīng)商,早已形成了一套成熟標(biāo)準(zhǔn)稱為OSEK。各供應(yīng)商開發(fā)的符合OSEK認(rèn)證的操作系統(tǒng)至少都能達(dá)到一定的質(zhì)量。但豐田選用的操作系統(tǒng)卻沒有通過認(rèn)證,讓人不解。

現(xiàn)在我們知道豐田在編寫軟件的時候至少有三種缺陷。那么重點(diǎn)問題:豐田的這些軟件缺陷是否會導(dǎo)致車輛暴沖?根據(jù)Barr的調(diào)查,答案是有可能。暴沖的起因需要結(jié)合上述三種缺陷來說明。

汽車正常運(yùn)行需要倚靠若干程序(這里叫Task)的同時運(yùn)作。Task有很多,CPU只有一塊,在任何時刻只能處理一個Task,怎么辦呢?這需要操作系統(tǒng)的統(tǒng)籌規(guī)劃,合理分配CPU的任務(wù),讓每個Task都能按時執(zhí)行。如果出現(xiàn)某種意外,讓某個Task突然不執(zhí)行了,那么就稱為這個Task“死亡”。Task死了,自然不能執(zhí)行它的任務(wù)。根據(jù)Barr的測試,在某些特定情況下,Task X的死亡可以導(dǎo)致節(jié)氣門敞開——因?yàn)門ask X的其中一個任務(wù)就是根據(jù)司機(jī)的操作計(jì)算節(jié)氣門開合角度,它死了也就沒法重新計(jì)算這個角度,即使司機(jī)把腳挪開加速踏板,節(jié)氣門也無法關(guān)閉。此為暴沖的直接原因。更糟糕的是,節(jié)氣門的開合角度這個數(shù)值,被Task X算出來以后保存在一個變量中。這個特定的變量正好沒有被保護(hù)(缺陷3)。意味著萬一Task X死亡并且停止計(jì)算,這個數(shù)值有可能因?yàn)椴豢煽乖虮桓淖?,而程序無從得知。

那么Task X為何會死亡呢?一般是因?yàn)閮?nèi)存出錯。這個出錯可能是一個小小的位反轉(zhuǎn),也可能是內(nèi)存里的數(shù)值被別的程序錯誤覆蓋。同一系統(tǒng)內(nèi)同時運(yùn)行了若干程序,這些程序需要共享一塊內(nèi)存,內(nèi)存內(nèi)部必然要被劃分成若干塊。比如第一塊給程序1,第二塊給程序2,等等。如果程序1因?yàn)槟承┰颍ū热鏐ug)寫到第二塊內(nèi)存上去,就會導(dǎo)致程序2讀取了錯誤的信息。這就是所謂的內(nèi)存出錯。豐田的系統(tǒng)里,正好有這么兩塊相鄰的內(nèi)存塊。第一塊被稱為“堆棧(Stack)”,這是所有Task存儲它們運(yùn)行狀態(tài)的地方,大小為4KB。與之相鄰的地方儲存了操作系統(tǒng)進(jìn)行任務(wù)分配的記錄。那么可以想象,如果很多Task給堆棧里寫入太多東西,超過4KB,那么就會錯誤地寫入與之相鄰的任務(wù)分配表。這種錯誤被稱為“堆棧溢出”。操作系統(tǒng)拿到了錯誤的任務(wù)分配表,就會錯誤地分配任務(wù),造成某些Task多執(zhí)行幾次,某些Task少執(zhí)行幾次,某些Task甚至就再也不執(zhí)行——死了!必須指出的是,程序死亡并不罕見,甚至可以認(rèn)為是正常現(xiàn)象。稍后解釋處理方法。

那么堆棧為什么會溢出呢?顯然是因?yàn)橐獙懭氲臄?shù)據(jù)超過了堆棧的容量。在設(shè)計(jì)程序的時候要計(jì)算最壞的情況并且允許冗余。即使作出了正確的設(shè)計(jì),這種錯誤也相對常見,所以NASA在他們的調(diào)查中重點(diǎn)排查堆棧溢出的可能性。于是NASA問豐田,豐田的回復(fù)是最壞的情況下4KB堆棧只寫入了41%的數(shù)據(jù),換句話說發(fā)生溢出的可能性非常低。NASA直接取信了這個數(shù)字并沒有再深入調(diào)查。但Barr他們發(fā)現(xiàn)豐田的回答有嚴(yán)重低估,實(shí)際上最壞的情況會達(dá)到94%,而且還不算遞歸。豐田在代碼中使用了遞歸(缺陷2)。因而實(shí)際數(shù)字有可能超過94%而且無法預(yù)計(jì)上限,因?yàn)檫f歸計(jì)算的嵌套層數(shù)是無法預(yù)測的。所以實(shí)際情況下堆棧溢出的可能性相當(dāng)可觀。一旦溢出,相鄰的任務(wù)分配表不可避免就會遭到破壞。此為暴沖的根本原因其中之一。之所以說“其中之一”,是因?yàn)槎褩R绯鰞H僅是損壞任務(wù)分配表的其中一個原因,別的還有許多可能性并沒有被Barr在法庭上深入解釋。而且任務(wù)分配表的損壞也僅僅是導(dǎo)致Task死亡的原因之一。

順便提一句,2005年的凱美瑞的這部分供應(yīng)商是電裝,沒有搭載堆棧實(shí)時監(jiān)測功能——溢出了也不知道。同年的卡羅拉卻搭載了,因?yàn)楣?yīng)商是通用。

到這里我小結(jié)一下,串鏈子。左邊是原因,右邊是后果。

堆棧溢出→(可能導(dǎo)致)→任務(wù)分配表被改寫→(可能導(dǎo)致)→Task X死亡→(可能導(dǎo)致)→節(jié)氣門敞開→(導(dǎo)致)→汽車暴沖

必須指出的是,這條鏈子從最左邊一直到Task X死亡,都還算是嵌入式系統(tǒng)的常見故障。雖然程序代碼寫得不好也許導(dǎo)致更容易出錯,客觀上豐田并沒有特別大的過錯。只要處理得當(dāng),這些故障都不會導(dǎo)致暴沖。

到此為止還只是前奏而已,接下來我們來看看豐田到底做錯了什么。

提問者:jiyuyin 地點(diǎn):- 瀏覽次數(shù):8655 提問時間:10-26 16:17
我有更好的答案
提 交
2條回答
不堪一擊zz 11-10 16:53
【第二部分】豐田之罪

上面反復(fù)提到,嵌入式系統(tǒng)中內(nèi)存出錯或者程序死亡其實(shí)是一種正?,F(xiàn)象——至少從Barr的證詞可以得出這個結(jié)論——現(xiàn)在連我們都知道了,嵌入式工程師肯定比我們更清楚才對。確實(shí),為了使系統(tǒng)正常運(yùn)行不被錯誤干擾,一般的做法是設(shè)置若干層防護(hù)措施(Failsafe),讓運(yùn)行中出現(xiàn)的錯誤無法輕易突破,得到妥善處理。豐田的工程師自然也懂得這一點(diǎn)。很可惜,他們搞砸了。

上面那條鏈子應(yīng)該修改成這樣:
(防護(hù)措施0)→堆棧溢出→(防護(hù)措施1)→(可能導(dǎo)致)→任務(wù)分配表被改寫→(防護(hù)措施2)→(可能導(dǎo)致)→Task X死亡→(防護(hù)措施3)→(可能導(dǎo)致)→節(jié)氣門敞開→(防護(hù)措施4)→(導(dǎo)致)→汽車暴沖

可以看到,防護(hù)措施不可謂不多。只要處理得當(dāng),這鏈條應(yīng)該是走不通的?,F(xiàn)在讓我們從左到右看一個小小的內(nèi)存錯誤是如何一層層突破防護(hù)最終導(dǎo)致汽車暴沖的。

首先防護(hù)措施0。這個其實(shí)上面提到了,因?yàn)樵O(shè)計(jì)缺陷低估了最大占用的存儲容量,并且不符合規(guī)范地使用了遞歸,最終可能導(dǎo)致堆棧溢出。

然后到防護(hù)措施1。上面也提到了,任務(wù)分配表緊鄰堆棧。作為外行我都覺得這是個十分危險的設(shè)計(jì)——既然堆棧這么容易溢出,好歹應(yīng)該將任務(wù)分配表放遠(yuǎn)一點(diǎn)啊。當(dāng)然我是外行,可能實(shí)際上比想象中復(fù)雜很多。這段Barr的證詞中并未特別提到,屬于我的個人理解。

防護(hù)措施2。從這里開始豐田的錯誤越發(fā)嚴(yán)重。任務(wù)表被改寫導(dǎo)致某些Task運(yùn)行異常,在軟件層應(yīng)該有若干檢測措施,比方說用特殊的監(jiān)視Task來監(jiān)視別的Task是否正常。但豐田是怎么做的呢?還記得上面的“廚房洗滌盆”Task X嗎?它是如此復(fù)雜(缺陷1),除了控制汽車運(yùn)行的任務(wù)之外竟然還兼任大部分的監(jiān)視任務(wù),比如生成DTC。
DTC(diagnostic trouble codes),是汽車電腦系統(tǒng)會根據(jù)情況生成的錯誤代碼。有的車主可能會遇到汽車某報(bào)警燈常亮,修車師傅拿個儀器插在行車電腦上得出一個代碼,再查表就知道哪個元件壞了——這就是DTC。除了用于修車,DTC還被用于檢測行車電腦和各傳感器的異常狀態(tài)。
可以想象,這個既是運(yùn)動員又是裁判的Task X一旦死亡,軟件層的檢測措施大部分就失效了。

防護(hù)措施3。在這里豐田的錯誤開始到達(dá)頂峰。即使設(shè)置正確無誤,上面提到的監(jiān)視Task也只不過是另一個Task而已,與它的監(jiān)視對象算是平級——監(jiān)視Task自己同樣有可能出現(xiàn)故障。嵌入式系統(tǒng)的一般做法是在所有程序之上再設(shè)置一道屏障,被稱為“看門狗(Watchdog)”。所謂看門狗,是一個優(yōu)先級很高的倒計(jì)時程序。別的程序需要在運(yùn)行的時候特意去重置一下這個計(jì)時器讓它重新開始倒計(jì)時,這個動作被稱為“喂狗”。如果因?yàn)槌绦虺鰡栴}太長時間不喂狗,倒計(jì)時完成,看門狗知道什么地方卡住了,馬上采取措施,比如重啟整個系統(tǒng)。重啟系統(tǒng)聽起來似乎很嚴(yán)重,實(shí)際上卻是一件相當(dāng)普通的事情。嵌入式系統(tǒng)的重啟非???,時速100公里的汽車中動力系統(tǒng)可以在半米之內(nèi)完成重啟——車上的人根本覺察不到。
通過閱讀代碼和擬真實(shí)驗(yàn),Barr驚訝地發(fā)現(xiàn)上述嵌入式系統(tǒng)的常識性做法竟然在豐田軟件系統(tǒng)內(nèi)不存在!豐田的軟件確實(shí)有一只看門狗,但它竟然不是用于監(jiān)視Task異常,而是用于防止CPU過載。首先這個做法不能說后無來者至少算是前無古人。還記得上面提到的800頁13章的報(bào)告嗎?目瞪口呆的Barr將豐田看門狗的分析結(jié)果寫入了報(bào)告的第一章,因?yàn)樗麑?shí)在太震驚。其次,豐田看門狗的防止CPU過載功能也相當(dāng)蹩腳,在擬真測試發(fā)現(xiàn)即使它正常工作,還是會允許CPU過載時間長達(dá)1.5秒——時速100公里的車能跑40米以上。CPU一旦過載,就會導(dǎo)致所有的Task進(jìn)入一種“假死”狀態(tài),無法處理信息,這時司機(jī)無法控制汽車動力,十分危險
另外,豐田的工程師還犯了一個嵌入式課堂上被反復(fù)提到的經(jīng)典錯誤:使用硬件時鐘中斷喂狗。硬件中斷擁有非常高的優(yōu)先級,即使Task卡?。ū热绯霈F(xiàn)死循環(huán))也不能阻止硬件中斷——可想而知這樣一來看門狗就等于完全白瞎了。
這里也提一句,同年的普銳斯卻令人意外地搭載了一只運(yùn)作正常的看門狗,反而讓人摸不著頭腦。
還沒完。這一層防護(hù)是嵌入式系統(tǒng)的關(guān)鍵陣地。前面都是電子系統(tǒng),后面馬上進(jìn)入機(jī)械運(yùn)作,足以造成災(zāi)難了。所以僅僅擁有軟件級別的防護(hù)還不足夠,豐田的做法是在主CPU之外單獨(dú)設(shè)置了一塊監(jiān)視芯片,從硬件級別對系統(tǒng)的運(yùn)作進(jìn)行監(jiān)視。監(jiān)視芯片有兩個任務(wù)。第一,它運(yùn)行一種叫做系統(tǒng)衛(wèi)士(System Guard)的程序,原理上來說是專門用于防止暴沖。主CPU和監(jiān)視芯片上都會運(yùn)行系統(tǒng)衛(wèi)士,可是研究發(fā)現(xiàn)Task X一旦死亡,這些系統(tǒng)衛(wèi)士統(tǒng)統(tǒng)都不起作用了。第二,它運(yùn)行一個被稱為“剎車回聲檢查(Brake Echo Check)”的程序。這個程序從代碼上來看似乎可以檢測出Task X的死亡,并且采取相應(yīng)措施:關(guān)閉節(jié)氣門。聽起來像是好消息,但是同樣有問題:首先這個程序不太可靠,即使正常運(yùn)行,理論上也有失效的可能。最關(guān)鍵的是該程序不會自動運(yùn)行,需要司機(jī)先對剎車踏板有“動作”才會觸發(fā)。注意這里我特意沒用“踩剎車”這個詞,因?yàn)楦鶕?jù)分析“觸發(fā)動作”十分令人困惑。它分兩種情況:如果Task X死亡的那一刻司機(jī)的腳不在剎車踏板上,那么觸發(fā)動作是踩剎車。還算可以理解。另一種情況,如果Task X死亡那一刻司機(jī)的腳踩在剎車踏板上,那么觸發(fā)動作是完全釋放剎車踏板。沒錯,察覺車子在不正常加速的司機(jī)需要停止踩剎車才能讓控制系統(tǒng)關(guān)閉節(jié)氣門!這種違背人類認(rèn)知的行為應(yīng)該不是豐田工程師特意設(shè)計(jì)的。如果是,他們到底在想什么?。?br/>到此為止,上面提到的都算是“戰(zhàn)術(shù)層面”的錯誤,都是“小錯”。在講解這塊監(jiān)視芯片的時候,可以發(fā)現(xiàn)豐田犯下最嚴(yán)重的“戰(zhàn)略層面”錯誤——基礎(chǔ)設(shè)計(jì)。Barr認(rèn)為,如果基礎(chǔ)設(shè)計(jì)正確,上述那些小錯都完全不會導(dǎo)致汽車暴沖——不管代碼寫得多業(yè)余,不管內(nèi)存錯誤多嚴(yán)重,不管Task死得多頻繁,統(tǒng)統(tǒng)不會致命。讓我們回到2002年以前,沒有電子油門的時候。那時候的拉線油門是由油門踏板機(jī)械連接的。當(dāng)駕駛員的右腳踩下剎車,他的右腳必然不在油門踏板上,節(jié)氣門自然而然地被關(guān)閉。這個動作如此自然,甚至算不上安全措施,僅僅因?yàn)槊咳酥挥幸恢挥夷_,不可能同時踩油門和剎車。當(dāng)豐田設(shè)計(jì)電子油門的時候,只要稍微有點(diǎn)常識,都應(yīng)該從設(shè)計(jì)階段就將這一“自然而然”發(fā)生的動作考慮進(jìn)去。但是很顯然,他們沒這么做。監(jiān)視芯片上運(yùn)行的代碼是用匯編語言(一種更加接近機(jī)器執(zhí)行代碼,遠(yuǎn)離人類語言,更加難懂的編程語言)編寫的,運(yùn)行層次比主CPU的C語言更低。Barr認(rèn)為如果設(shè)計(jì)得當(dāng),現(xiàn)有的監(jiān)視芯片完全有能力勝任上述功能,需要的僅僅是幾百行代碼,別的什么都不用更改——不會提高任何生產(chǎn)成本。很遺憾,他們沒有做到。


防護(hù)措施4?,F(xiàn)在已經(jīng)脫離電子系統(tǒng),節(jié)氣門已經(jīng)敞開,發(fā)動機(jī)全速運(yùn)轉(zhuǎn),需要使用機(jī)械運(yùn)作來組織機(jī)械運(yùn)作了。如何讓向前沖的車子停下來?不開車的人都知道,剎車!現(xiàn)代汽車都裝備了剎車助力,助力來自于發(fā)動機(jī)運(yùn)轉(zhuǎn)的時候產(chǎn)生的負(fù)壓。我們知道發(fā)動機(jī)需要吸入空氣,吸入體積等于排氣量乘以轉(zhuǎn)速。節(jié)氣門又是用來阻擋空氣的,那么節(jié)氣門關(guān)閉而發(fā)動機(jī)轉(zhuǎn)速相對高的時候(比如高速丟油門),發(fā)動機(jī)的實(shí)際空氣吸入量比它能吸入的體積要少,那么從節(jié)氣門到氣缸進(jìn)氣口之間會形成明顯低氣壓(所謂負(fù)壓,比大氣壓力?。x車助力就是利用了這個負(fù)壓推動氣鼓產(chǎn)生更大的推力帶動剎車片抓緊剎車盤。但是如果節(jié)氣門敞開讓空氣隨便進(jìn)來,低氣壓就不存在了,這時剎車助力大大減弱,剎車效率也大大降低。這就是為什么暴沖事件當(dāng)事人都說全油門的時候根本剎不住的重要原因。這個現(xiàn)象稱為“真空損失(Vacuum Loss)”,存在于所有自然吸氣的汽油發(fā)動機(jī)汽車(柴油和增壓發(fā)動機(jī)沒影響),不算豐田的錯。但豐田遲遲不搭載剎車優(yōu)先系統(tǒng)(Brake Override System)允許剎車的同時敞開節(jié)氣門,毫無疑問是這個現(xiàn)象的幫兇。
所謂剎車優(yōu)先系統(tǒng),指的是保證同時踩下剎車油門兩個踏板的時候無條件關(guān)閉節(jié)氣門的功能。這么做很顯然主要是為了降低發(fā)動機(jī)輸出,同時也保證剎車助力。豐田在2010年的凱美瑞上終于搭載了剎車優(yōu)先系統(tǒng),但是別高興得太早。根據(jù)Barr的調(diào)查,豐田竟然將如此重要的修改“理所當(dāng)然”地寫入了他們的“廚房洗滌盆”——Task X。我只能“啞然失笑,扼腕嘆息”。


好了,到此為止都還是Barr的一面之詞,而且大部分都是在那間守衛(wèi)森嚴(yán)的房間內(nèi)進(jìn)行擬真測試得出的“理論結(jié)果”。那么實(shí)車測試情況如何呢?豐田對Barr的證詞如何反駁呢?


先說說實(shí)車測試。為了證明理論,他們把2008年和2005年的凱美瑞放在馬力機(jī)上,固定車身架起前輪模擬車輛運(yùn)行情況。他們的做法是首先讓車子運(yùn)行在時速68英里(110公里),啟動巡航,腳離開油門踏板。然后暫停巡航,速度開始下降。下降到一定程度恢復(fù)巡航,速度開始上升。在到達(dá)68英里的設(shè)定時速以前,他們用一臺連接行車電腦的筆記本“注入”錯誤。所謂注入錯誤,就是人為地翻轉(zhuǎn)一個特定字節(jié)——將0改成1,或者反過來——模擬內(nèi)存損壞。結(jié)果完全符合理論,時速超過68英里也不停止加速,直至?xí)r速90英里(145公里),測試人員踩下剎車。大約1秒以后節(jié)氣門被關(guān)閉,Barr認(rèn)為這是上述“剎車回聲檢查”的功勞。


實(shí)車測試證明了Barr的理論,卻并不是全無破綻。豐田辯護(hù)律師就兩點(diǎn)提出質(zhì)疑:
實(shí)車測試使用人工注入錯誤的方法,并不能證明現(xiàn)實(shí)中這種錯誤就一定會發(fā)生。
對此Barr的回答是測試的局限性。因?yàn)闇y試時間、樣本有限,而待測試的樣本空間無窮大。如果要等待那個特定的錯誤自然出現(xiàn),可能需要成百萬上億小時的不間斷測試,顯然是不現(xiàn)實(shí)的。更何況從科學(xué)上而言,沒有辦法對這個錯誤證偽——就好比無法證明宇宙里沒有外星人,最多只能證明火星上找不到而已。但是這個測試足以證明一個小小的位翻轉(zhuǎn)確實(shí)可以突破重重障礙最終導(dǎo)致暴沖,足以證明豐田的軟件存在不能容忍的隱患。
Bookout女士(本案原告)聲稱,在她駕駛汽車離開高速的時候發(fā)現(xiàn)不受控加速,她拼命反復(fù)踩下剎車并且拉起手剎,現(xiàn)場留下了剎車痕跡。但并沒有跡象表明發(fā)動機(jī)動力中斷——換言之“剎車回聲檢測”沒起作用。暗指Barr的理論站不住。
對此Barr的回答是首先盡管在實(shí)車測試中每次都生效,但代碼分析表明“剎車回聲檢查”這一功能在理論上靠不住。其次這一功能的另外一個觸發(fā)動作是要讓腳完完全全離開剎車踏板。試想車子正在不受控地往前沖,任何人都會不由自主地踩剎車,讓人完全不踩剎車踏板根本就是違背認(rèn)知的。Bookout女士即使如同她所稱反復(fù)踩剎車,很可能只是一直將腳放在踏板上往復(fù)運(yùn)動,從未完全挪開。Barr還引用一位豐田自己的軟件專家的證詞。該專家承認(rèn),如果發(fā)生暴沖的時刻腳正好接觸到剎車踏板,并且之后一直沒挪開,那么汽車的暴沖距離“取決于還剩多少汽油”。

最后順帶說一下那份800頁,13章的詳細(xì)報(bào)告完成后,Barr將其提交給了豐田的軟件部門,等待他們的反駁。最終結(jié)果是“非常少(Very little)”,13章中的11章,包括堆棧溢出的部分、代碼混亂的部分、違反開發(fā)規(guī)范的部分、Task X過于臃腫甚至兼任節(jié)氣門控制和防護(hù)措施的部分、看門狗形同虛設(shè)的部分、無EDAC的部分、重要變量缺乏保護(hù)的部分、使用了非標(biāo)準(zhǔn)化操作系統(tǒng)的部分,全部沒受到任何形式的反駁。


【第三部分】后記


寫到這里,談?wù)勅藗儽容^關(guān)心的幾點(diǎn)。當(dāng)然還是外行眼光。
NASA / NHTSA怎么沒發(fā)現(xiàn)這些問題?
NHTSA本身不具備檢驗(yàn)電子系統(tǒng)的能力,于是委托NASA。NASA檢驗(yàn)的是整個電控系統(tǒng),包括電控傳動部分,范圍比較寬,只有很少一部分資源被用于檢驗(yàn)軟件系統(tǒng),也沒有投入足夠的人力進(jìn)行逐行代碼審閱。更何況在很多關(guān)鍵問題,比如之前提到的EDAC的使用、堆棧的設(shè)計(jì),NASA都直接采信豐田的回復(fù),最終被證明不正確。甚至NASA從來都沒拿到過監(jiān)視芯片的源代碼,豐田的說法是“他們沒說要啊”。NASA報(bào)告雖然沒能找到軟件系統(tǒng)導(dǎo)致暴沖的確切原因,但沒有否定其可能性。與之相比Barr的團(tuán)隊(duì)全部都是嵌入式系統(tǒng)專家,投入上千小時,深入程度甚至超過豐田自身對這個系統(tǒng)的理解(比如豐田沒看過供應(yīng)商的OS代碼,Barr看了)。
能否100%確定本案就是由軟件錯誤造成的?
不能。并沒有直接證據(jù)。訴訟團(tuán)認(rèn)為,軟件錯誤造成該事故的可能性比軟件錯誤沒造成該事故的可能性大(原文:more likely than not)。
這里再提一句,2005年款的凱美瑞沒有搭載行車數(shù)據(jù)記錄器(俗稱“黑盒子”),后來的車款漸漸開始搭載。但是Barr發(fā)現(xiàn)這個記錄功能并不可靠,完全有可能記錄錯誤信息。比如司機(jī)踩剎車了可能會被記錄成沒踩。
本案的意義
之前雖然豐田賠了不少錢,但是從未在涉及人身傷害的案件上承責(zé)。所以本案意義在于開先例。美國的法律又特別注重先例,今后豐田的法務(wù)部門要頭疼了。
本案提到的有缺陷軟件涉及了哪些車型?
全部是美國的車型。Barr的調(diào)查重點(diǎn)是2005年款凱美瑞,另外審閱過的包括雷克薩斯ES、Tacoma、卡羅拉和普銳斯等等,生產(chǎn)年份大致在2002年(電子油門元年)與2010年之間。其中凱美瑞、雷克薩斯ES和Tacoma使用的軟件系統(tǒng)大致接近(原文:Substantially similar)。另外根據(jù)統(tǒng)計(jì),汽車暴沖投訴中與2004年款以后的凱美瑞有關(guān)的案件數(shù)量激增400%。



最后的最后,放上本案關(guān)鍵證人Michael Barr的獨(dú)家訪談:


我:這么看來似乎手動檔汽車更安全,你怎么認(rèn)為?
Barr:很多專家都這么認(rèn)為,離合器至少可以物理斷開動力系統(tǒng)。但是我翻閱卷宗,發(fā)現(xiàn)其中有個案例是受害者開手動檔凱美瑞載著家人,突然巡航系統(tǒng)失靈,無法取消。他踩下離合,同時試圖躲避前方慢速車輛結(jié)果失控沖出路面造成單車事故。幸運(yùn)的是沒死人。


我:現(xiàn)在我們都知道豐田的軟件很糟糕。可是你對整個汽車行業(yè)的軟件水平有什么看法?豐田的軟件在同行內(nèi)屬于什么水平?
Barr:我沒有接觸過豐田以外的軟件代碼。但是請注意,這次發(fā)現(xiàn)的最嚴(yán)重問題是豐田在設(shè)計(jì)源頭上沒有考慮安全,軟件質(zhì)量反倒沒有那么重要。只要一個安全為先的設(shè)計(jì),比如剎車和關(guān)閉節(jié)氣門的可靠互動、防止節(jié)氣門開啟降低剎車效率的機(jī)制等等,不管軟件有多差勁也不會造成致命結(jié)果。只是我真不知道軟件還能怎么差。


我:終極問題,你開什么車?
Barr:我不開豐田。接觸該案以來我沒買過新車。老實(shí)說我現(xiàn)在非常害怕買新車。我倒是問過一個與車企斗爭了三十多年的職業(yè)狀棍同樣的問題,他開寶馬。


【全文完】
344868615qq 11-13 16:33


"就算是一個while(1);的循環(huán),都不定什么時候就會跑飛。"? ?-- 這是PC指針飛了!和內(nèi)存無關(guān)。
硬件不穩(wěn)定,要從硬件上解決,能從純軟件上解決的,都是些數(shù)據(jù)濾波之類的非致命問題。
撰寫答案
提 交
1 / 3
1 / 3
相關(guān)嵌入式
作為一個新人,怎樣學(xué)習(xí)嵌入式Linux
一種嵌入式汽車數(shù)字儀表電路設(shè)計(jì)
嵌入式多屏異顯在卡拉OK點(diǎn)唱機(jī)中的運(yùn)用
嵌入式操作系統(tǒng) 文件系統(tǒng)
優(yōu)秀的嵌入式程序特點(diǎn)