入門:AUTOSAR學(xué)習(xí)路線與實(shí)戰(zhàn)指南)
好幾個(gè)朋友最近都問(wèn)過(guò)同一個(gè)問(wèn)題想做車載底層嵌入式軟件開發(fā)AutoSar到底該怎么學(xué)這個(gè)問(wèn)題看著不大但每次認(rèn)真回答起來(lái)都要聊很久。原因很簡(jiǎn)單AutoSar不是一個(gè)“知識(shí)點(diǎn)”而是一整套基于標(biāo)準(zhǔn)化架構(gòu)的開發(fā)體系和生態(tài)。你去招聘軟件上搜“嵌入式軟件開發(fā)”十個(gè)崗位里六七個(gè)都寫著“熟悉AutoSar優(yōu)先”但真要把這套東西講明白、學(xué)明白網(wǎng)上能找到的資料又散又淺很容易勸退新人。這篇文章我就把“新手如何學(xué)習(xí)車載底層嵌入式軟件開發(fā)AutoSar”這件事拆成一條相對(duì)清晰的路線來(lái)講。它解決的核心問(wèn)題是你之前沒(méi)有車載行業(yè)經(jīng)驗(yàn)或者只有單片機(jī)基礎(chǔ)怎么用一年左右的時(shí)間把AutoSar的路摸通能寫簡(jiǎn)歷、能面試、能上手干活。適合三類人看準(zhǔn)備從傳統(tǒng)嵌入式轉(zhuǎn)行做車載的工程師、剛畢業(yè)的電子或計(jì)算機(jī)相關(guān)專業(yè)學(xué)生、已經(jīng)在做車載測(cè)試想轉(zhuǎn)開發(fā)的同行。我會(huì)盡量站在“過(guò)來(lái)人”的角度把關(guān)鍵原理、實(shí)操路徑、工具鏈情況、常見(jiàn)坑都講到位你拿過(guò)去就能照著規(guī)劃。1. 學(xué)習(xí)前必須搞清楚的幾個(gè)底層問(wèn)題1.1 AutoSar到底解決的是車載軟件的什么問(wèn)題很多新手一上來(lái)就抱著AUTOSAR規(guī)范文檔啃結(jié)果看了幾百頁(yè)還是不知道這東西解決了什么問(wèn)題。我建議你先跳出標(biāo)準(zhǔn)想想一個(gè)整車廠為什么會(huì)需要AutoSar這樣一個(gè)標(biāo)準(zhǔn)化架構(gòu)。早年間一輛車上有幾十個(gè)ECU每個(gè)ECU的軟件開發(fā)方式基本是“一錘子買賣”芯片廠商給你一套底層驅(qū)動(dòng)Tier1按自己的習(xí)慣寫應(yīng)用邏輯OEM拿到手里發(fā)現(xiàn)不同供應(yīng)商的代碼風(fēng)格完全不同軟件接口對(duì)不上出了問(wèn)題互相甩鍋。最痛苦的是換一顆MCU整個(gè)軟件幾乎要推倒重來(lái)所有底層寄存器操作、驅(qū)動(dòng)庫(kù)都要適配一遍。這種模式下軟件開發(fā)成本高、周期長(zhǎng)、復(fù)用率極低。AutoSar做的事情歸結(jié)起來(lái)就一句話把汽車ECU的軟件架構(gòu)標(biāo)準(zhǔn)化讓軟件與硬件解耦讓應(yīng)用層與基礎(chǔ)軟件解耦讓不同廠商之間能用統(tǒng)一的“語(yǔ)言”協(xié)作。它規(guī)定好了分層模型、模塊劃分和接口定義供應(yīng)商按規(guī)范開發(fā)OEM按規(guī)范集成。你可以把它理解成裝修行業(yè)的“標(biāo)準(zhǔn)化插座”——不管墻里走的什么線面板上留的接口是一致的燈具和電器廠家只要按標(biāo)準(zhǔn)做插頭就能裝過(guò)去。所以學(xué)習(xí)AutoSar不能只盯著某個(gè)驅(qū)動(dòng)函數(shù)而是要建立“軟件架構(gòu)”的思維方式。這是和傳統(tǒng)裸機(jī)開發(fā)最大的不同點(diǎn)。1.2 Classic與Adaptive怎么選接觸AutoSar時(shí)你會(huì)看到兩個(gè)大方向Classic PlatformCP和Adaptive PlatformAP。我的建議很直接如果你是做“車載底層嵌入式軟件”這個(gè)方向從Classic入手暫時(shí)先不用深入Adaptive。兩者的區(qū)別可以從幾個(gè)維度來(lái)看對(duì)比維度Classic PlatformAdaptive Platform目標(biāo)硬件傳統(tǒng)MCUTC3xx、S32K、RH850等高性能SoC/MPU高通驍龍、英飛凌AURIX TC4xx等操作系統(tǒng)OSEK/VDX OS靜態(tài)調(diào)度基于POSIX的Linux/QNX類系統(tǒng)編程語(yǔ)言以C語(yǔ)言為主C為主適用場(chǎng)景車身控制、動(dòng)力、底盤、傳統(tǒng)ECU自動(dòng)駕駛、智能座艙、域控制器實(shí)時(shí)性要求高微秒到毫秒級(jí)相對(duì)高但允許一定動(dòng)態(tài)調(diào)度資源占用小運(yùn)行在裸機(jī)或輕量OS上大動(dòng)輒需要多核大內(nèi)存Classic平臺(tái)承載的是汽車電子里數(shù)量最多、生命周期最長(zhǎng)的ECUBootloader、網(wǎng)絡(luò)管理、診斷、刷新這些核心底層工作基本都跑在它上面。而且Classic的開發(fā)方式和傳統(tǒng)嵌入式貼合度更高入門門檻相對(duì)低。很多公司招聘的“車載基礎(chǔ)軟件工程師”“嵌入式軟件開發(fā)AUTOSAR方向”崗位說(shuō)的基本都是Classic平臺(tái)。先把CP吃透后面再往Adaptive發(fā)展也順理成章。1.3 沒(méi)有這些基礎(chǔ)先別急著看代碼AutoSar本身已經(jīng)是“上層建筑”它底下還壓著一大堆基礎(chǔ)知識(shí)。如果底子太薄硬去學(xué)很容易被各種配置界面和生成代碼淹沒(méi)。我認(rèn)為你在開始學(xué)AutoSar之前至少需要具備這些能力C語(yǔ)言要扎實(shí)指針、結(jié)構(gòu)體、函數(shù)指針、位操作、內(nèi)存管理這些必須過(guò)關(guān)。AutoSar生成的代碼里大量使用結(jié)構(gòu)體和函數(shù)指針看不懂這些基本沒(méi)法調(diào)式。至少熟悉一款單片機(jī)推薦STM32資料多、上手快或者直接上英飛凌AURIX TC2xx/TC3xx開發(fā)板。要懂GPIO、中斷、定時(shí)器、CAN、SPI、UART這些外設(shè)懂寄存器級(jí)別怎么操作。能看懂原理圖和芯片手冊(cè)做車載底層一定會(huì)遇到硬件相關(guān)的問(wèn)題比如CAN收發(fā)器引腳接錯(cuò)了、芯片供電電壓不對(duì)。你得能看懂一個(gè)芯片的電源域、引腳功能、喚醒邏輯。會(huì)用調(diào)試工具示波器、邏輯分析儀、USB-CAN分析儀這幾樣?xùn)|西在車載開發(fā)中就是日常吃飯的碗。知道操作系統(tǒng)基礎(chǔ)概念任務(wù)、中斷優(yōu)先級(jí)、信號(hào)量、隊(duì)列。即使還沒(méi)用過(guò)OSEK OS這些概念也必須有。如果你發(fā)現(xiàn)上面這些還有欠缺老老實(shí)實(shí)先補(bǔ)基礎(chǔ)別跳級(jí)。跳級(jí)的后果就是在實(shí)際項(xiàng)目中花幾周在一個(gè)很簡(jiǎn)單的問(wèn)題上打轉(zhuǎn)。2. 新手入門的學(xué)習(xí)路線先搭架構(gòu)再鉆細(xì)節(jié)2.1 先畫一張整體架構(gòu)圖把模塊職責(zé)標(biāo)清楚我見(jiàn)過(guò)不少初學(xué)者路徑完全反著來(lái)先看CanTp怎么配置再看NvM什么參數(shù)學(xué)了兩周還是不知道自己每天在配什么東西。其實(shí)AutoSar學(xué)習(xí)的第一步應(yīng)該是先把軟件架構(gòu)“裝進(jìn)腦子里”。Classic平臺(tái)的分層大致是這樣最上層是應(yīng)用層SWC中間是運(yùn)行時(shí)環(huán)境RTE再往下是基礎(chǔ)軟件層BSW。BSW又可以拆成三塊服務(wù)層包括Dcm、Dem、NvM、Com、CanTp、CanNm、BswM等、ECU抽象層CanIf、EthIf等、微控制器抽象層Can驅(qū)動(dòng)、MCU驅(qū)動(dòng)、Gpt驅(qū)動(dòng)等。理解這套模型千萬(wàn)別死記硬背你要能畫出數(shù)據(jù)流。舉一個(gè)最常見(jiàn)的例子診斷儀發(fā)一條UDS請(qǐng)求給ECU數(shù)據(jù)是怎么跑的診斷請(qǐng)求從CAN總線進(jìn)來(lái)被MCAL層的Can驅(qū)動(dòng)接收然后把報(bào)文交給CanIfCanIf根據(jù)CAN ID找到對(duì)應(yīng)的PDU交給PduR做路由。如果這個(gè)數(shù)據(jù)超過(guò)了一個(gè)CAN幀的長(zhǎng)度PduR會(huì)把它交給CanTp做分包和組包處理等完整數(shù)據(jù)到達(dá)后再交給上層的Dcm模塊Dcm解析這個(gè)診斷請(qǐng)求調(diào)用對(duì)應(yīng)的服務(wù)處理邏輯。如果是讀取故障碼Dcm會(huì)去Dem模塊拿DTC信息然后按原路把響應(yīng)數(shù)據(jù)發(fā)回去。我讓你畫這張圖是為了訓(xùn)練你“數(shù)據(jù)流思維”。做車載底層開發(fā)最常做的事就是在某一條數(shù)據(jù)通路上定位問(wèn)題。你腦子里沒(méi)這張地圖工具用得再熟也白搭。2.2 推薦從通信棧切入別一上來(lái)就啃診斷和存儲(chǔ)AutoSar的模塊很多新手要有取舍。我的建議是從通信棧切入先把CAN通信鏈路打通然后再去學(xué)診斷、網(wǎng)絡(luò)管理、存儲(chǔ)這些和通信強(qiáng)相關(guān)的模塊最后有余力再看OS、看RTE。為什么從通信棧入手三個(gè)原因。第一所有的ECU都要上CAN總線通信是剛需也是面試必問(wèn)第二通信鏈路的效果你可以直接用CAN卡抓報(bào)文驗(yàn)證學(xué)起來(lái)有反饋、有成就感第三通信棧的層級(jí)設(shè)計(jì)是AutoSar分層思想的最佳縮影把這個(gè)鏈路搞明白其他模塊的理解就順理成章。通信棧里最值得死磕的是CanTp傳輸層協(xié)議對(duì)應(yīng)ISO 15765-2。因?yàn)閷?shí)際的診斷刷寫等大數(shù)據(jù)傳輸都依賴這個(gè)模塊的分包和組包能力。你需要理解單幀、首幀、連續(xù)幀、流控幀的關(guān)系理解SN序列號(hào)怎么遞增理解STmin最小間隔時(shí)間和塊大小BlockSize怎么影響傳輸速率。舉個(gè)例子一次Bootloader刷寫中你要寫4KB的數(shù)據(jù)到Flash但一個(gè)CAN幀最多只能帶8字節(jié)。CanTp會(huì)先發(fā)一個(gè)首幀告訴對(duì)端“我要發(fā)一個(gè)4096字節(jié)的報(bào)文”對(duì)端回來(lái)流控幀說(shuō)“你一次最多發(fā)8幀幀間隔最小10ms”然后發(fā)送端就按這個(gè)節(jié)奏發(fā)連續(xù)幀。這個(gè)過(guò)程中如果STmin配得太小對(duì)端MCU處理不過(guò)來(lái)就會(huì)丟幀如果BlockSize配得太小傳輸就會(huì)變慢。這種調(diào)優(yōu)經(jīng)驗(yàn)恰恰是工作中最有價(jià)值的部分。學(xué)完通信棧之后可以緊接著把網(wǎng)絡(luò)管理模塊學(xué)了。這里涉及BswM基礎(chǔ)軟件模式管理器和CanNmCAN網(wǎng)絡(luò)管理。你需要理解ECU的幾種網(wǎng)絡(luò)狀態(tài)Bus-Sleep模式、Prepare Bus-Sleep模式、Network模式。ECU想睡覺(jué)時(shí)不是直接睡的需要走一套流程先停止收發(fā)應(yīng)用報(bào)文然后經(jīng)過(guò)一段等待時(shí)間確認(rèn)總線上沒(méi)有其他節(jié)點(diǎn)在“挽留”它才能進(jìn)入睡眠。這套狀態(tài)切換邏輯是面試高頻考點(diǎn)也是實(shí)際項(xiàng)目中“靜態(tài)電流超標(biāo)”問(wèn)題的高發(fā)區(qū)域。2.3 學(xué)習(xí)資料別貪多按“概念-規(guī)范-工程”三層來(lái)選很多新手在資料選擇上特別糾結(jié)總覺(jué)得要收集齊所有文檔才夠。實(shí)際上AutoSar資料要按層次來(lái)用不建議一開始就抱著幾百頁(yè)的官方SWS文檔硬啃。我建議的資料使用思路是第一層建立概念??匆恍〢utoSar架構(gòu)介紹類的視頻或文章把上面說(shuō)的分層模型、模塊職責(zé)搞清楚。這個(gè)階段不用深入細(xì)節(jié)能達(dá)到“看到模塊縮寫能知道它是干什么的”程度就行。第二層按需查閱官方文檔。AUTOSAR官方發(fā)布的標(biāo)準(zhǔn)文檔本身是非常好的工具書但不適合通讀。你需要訓(xùn)練“檢索式閱讀”遇到某個(gè)參數(shù)搞不懂去對(duì)應(yīng)模塊的標(biāo)準(zhǔn)里查定義。比如配置CanTp時(shí)遇到N_Ar到底是干嘛的就打開CanTp標(biāo)準(zhǔn)文檔翻一翻只看相關(guān)章節(jié)。第三層動(dòng)手做工程。找一個(gè)demo工程或者自己搭建一個(gè)最小工程對(duì)照配置界面逐步看它生成的代碼長(zhǎng)什么樣這是理解和記憶最有效的方式。順帶提一句很多工具廠商比如Vector、EB官網(wǎng)都有公開的培訓(xùn)材料和示例工程多去翻翻往往比看二手博客強(qiáng)得多。3. 開發(fā)環(huán)境與工具鏈沒(méi)有商業(yè)工具也能學(xué)著做項(xiàng)目3.1 商業(yè)工具鏈長(zhǎng)什么樣心里要有數(shù)車載底層軟件開發(fā)和普通的嵌入式開發(fā)有一個(gè)很大的區(qū)別AutoSar是“配置驅(qū)動(dòng)”的絕大多數(shù)代碼不是手寫的而是通過(guò)配置工具生成的。商用領(lǐng)域最主流的兩套工具Vector的DaVinci Configurator Pro DaVinci Developer和EB的tresos Studio。拿著工具怎么做開發(fā)大致流程是這樣的OEM會(huì)提供一個(gè)ECU Extract一個(gè)關(guān)于整車通信矩陣和診斷規(guī)范的配置文件描述這個(gè)ECU該有哪些報(bào)文、哪些診斷服務(wù)你把它導(dǎo)入到配置工具里然后在這個(gè)基礎(chǔ)上配置各個(gè)BSW模塊。比如配置Can驅(qū)動(dòng)要選用哪個(gè)CAN通道、波特率是多少配置CanIf要定義哪些CAN ID對(duì)應(yīng)哪條PDU配置CanTp要設(shè)置STmin、BS、SN等參數(shù)。配置完成后工具會(huì)直接生成一堆C代碼你再把自己的業(yè)務(wù)邏輯比如Bootloader的Flash驅(qū)動(dòng)、網(wǎng)絡(luò)管理回調(diào)集成進(jìn)去最后編譯、鏈接、刷寫。舉個(gè)例子BswM下電配置在Vector DaVinci里大概長(zhǎng)什么樣你需要在BswM里定義模式請(qǐng)求源和模式切換規(guī)則。比如當(dāng)CanNm進(jìn)入Bus-Sleep模式時(shí)BswM要釋放CommUser停止應(yīng)用報(bào)文發(fā)送然后延遲一段時(shí)間確認(rèn)沒(méi)有新的請(qǐng)求再通過(guò)EcuM調(diào)用MCU驅(qū)動(dòng)關(guān)閉外設(shè)和時(shí)鐘最后讓電源管理單元進(jìn)入低功耗狀態(tài)。這個(gè)過(guò)程涉及BswM的ModeCondition、ActionList、LogicalExpression等配置項(xiàng)如果之前沒(méi)接觸過(guò)確實(shí)容易一頭霧水。Ecuc模塊是整個(gè)配置工具的核心。你可以把它理解成一個(gè)巨大的“參數(shù)倉(cāng)庫(kù)”所有BSW模塊的關(guān)鍵參數(shù)都集中在這個(gè)單元里管理每個(gè)參數(shù)都有路徑、類型、取值范圍。配置工具的本質(zhì)就是把我們以前手寫驅(qū)動(dòng)時(shí)那些散落在代碼里的宏定義由規(guī)范定義后集中管理起來(lái)。3.2 沒(méi)有商業(yè)授權(quán)怎么動(dòng)手練商用工具很貴個(gè)人學(xué)習(xí)通常拿不到授權(quán)。那是不是就學(xué)不了了并不是。我推薦的方案是“兩個(gè)腿走路”。第一用帶基礎(chǔ)軟件包的開發(fā)板?,F(xiàn)在英飛凌、NXP這些芯片廠商都有自己的開發(fā)板生態(tài)。比如英飛凌AURIX TC3xx系列有對(duì)應(yīng)的MCAL驅(qū)動(dòng)包和部分BSW示例你可以先在這個(gè)環(huán)境里練習(xí)MCAL層的配置和驅(qū)動(dòng)調(diào)試。雖然BSW的功能可能不完全但至少能讓你理解“底層驅(qū)動(dòng)到底在干什么”。第二用普通單片機(jī)自己實(shí)現(xiàn)一個(gè)簡(jiǎn)化版通信協(xié)議棧。比如拿STM32F407的開發(fā)板自己寫一個(gè)基于CAN外設(shè)的CanTp協(xié)議處理程序處理單幀和流控幀或者自己寫一個(gè)簡(jiǎn)化版的CAN網(wǎng)絡(luò)管理狀態(tài)機(jī)。這一套做下來(lái)你對(duì)AutoSar里面那些狀態(tài)機(jī)的理解會(huì)非常深之后去套商業(yè)工具只是“換一層皮”的問(wèn)題。我特意強(qiáng)調(diào)“先理解狀態(tài)機(jī)再學(xué)配置”。因?yàn)榕渲霉ぞ咧皇前褷顟B(tài)機(jī)和參數(shù)變成圖形化界面你如果不知道底層協(xié)議邏輯是什么工具上那些超時(shí)時(shí)間、節(jié)點(diǎn)地址、重復(fù)次數(shù)配置對(duì)你來(lái)說(shuō)只是“玄學(xué)旋鈕”。3.3 從零到一配置一個(gè)最小工程假設(shè)你手上已經(jīng)有一塊開發(fā)板、一個(gè)CAN分析儀和一套可以使用的AutoSar配置工具哪怕是試用版或?qū)W校授權(quán)我想帶你過(guò)一遍從零配出最小系統(tǒng)的完整流程。第一步新建工程導(dǎo)入ECU Extract。ECU Extract里包含總線矩陣、DBC、診斷描述這是所有報(bào)文的“源頭”。第二步配置MCU模塊。先配時(shí)鐘鎖相環(huán)、看門狗、時(shí)鐘樹、端口、以及用到的外設(shè)。第三步配置通信底層。配置Can驅(qū)動(dòng)選擇通道、波特率例如500kbps、CAN控制器模式。再配置CanIf把總線上的CAN ID映射到軟件上的PDU ID。第四步配置PduR。PduR是路由中心你要明確每個(gè)PDU是發(fā)到CanTp做長(zhǎng)報(bào)文還是直接發(fā)到Com做信號(hào)。第五步配置CanTp。參數(shù)包括N_As、N_Ar、N_Bs、N_Cr這些超時(shí)時(shí)間以及STmin、默認(rèn)塊大小等。第六步配置Dcm和Dem。Dcm里要添加支持的服務(wù)例如0x10會(huì)話控制、0x27安全訪問(wèn)、0x22讀取數(shù)據(jù)、0x2E寫入數(shù)據(jù)、0x34請(qǐng)求下載等。Dem里要預(yù)定義DTC事件。第七步配置NvM、BswM、CanNm。NvM要做存儲(chǔ)塊的劃分和地址映射BswM要配置模式判斷邏輯CanNm要設(shè)置網(wǎng)絡(luò)管理報(bào)文ID和超時(shí)參數(shù)。第八步生成代碼編譯下載用CAN卡發(fā)一些診斷請(qǐng)求驗(yàn)證鏈路。這套流程走完你會(huì)發(fā)現(xiàn)一個(gè)很有意思的現(xiàn)象大部分時(shí)間不是寫代碼而是在“畫配置”。這就是AutoSar風(fēng)格你要適應(yīng)它。配置一個(gè)模塊時(shí)一定要看它的“依賴關(guān)系”。比如配置PduR時(shí)你發(fā)現(xiàn)需要填CanTp的PDU ID你還沒(méi)配CanTp就配不了PduR。所以配置順序很重要否則界面報(bào)錯(cuò)就能把人搞崩潰。4. 用實(shí)戰(zhàn)項(xiàng)目檢驗(yàn)學(xué)習(xí)成果越早動(dòng)手越好4.1 項(xiàng)目一做一個(gè)支持UDS刷寫的Bootloader如果說(shuō)只做一個(gè)項(xiàng)目來(lái)檢驗(yàn)AutoSar學(xué)習(xí)成果我一定推薦“UDS Bootloader”。因?yàn)橐粋€(gè)完整的刷寫功能能把診斷、通信、存儲(chǔ)、任務(wù)調(diào)度、狀態(tài)管理這些核心模塊全部串起來(lái)相當(dāng)于一次“畢業(yè)設(shè)計(jì)”。這個(gè)Bootloader的工作流程大概是ECU上電后進(jìn)入Bootloader先初始化時(shí)鐘和CAN然后啟動(dòng)一個(gè)診斷任務(wù)不斷監(jiān)聽總線上是否有診斷請(qǐng)求。如果收到0x10 02進(jìn)入編程會(huì)話?cǎi)R上切換會(huì)話之后會(huì)收到0x27安全訪問(wèn)請(qǐng)求你要實(shí)現(xiàn)密鑰算法來(lái)解鎖權(quán)限解鎖之后刷寫工具會(huì)發(fā)0x34請(qǐng)求下載和0x36傳輸數(shù)據(jù)這些數(shù)據(jù)會(huì)經(jīng)過(guò)CanTp分包到達(dá)Dcm后再寫入到外部Flash。等所有數(shù)據(jù)傳輸完成發(fā)0x31例程控制做校驗(yàn)校驗(yàn)通過(guò)后置一個(gè)APP有效性標(biāo)志最后執(zhí)行軟件復(fù)位跳到APP。這個(gè)鏈路中每一個(gè)環(huán)節(jié)都有坑。首當(dāng)其沖的是Flash驅(qū)動(dòng)和擦寫策略擦除時(shí)間長(zhǎng)Dcm那邊可能已經(jīng)超時(shí)了你要決定同步擦還是異步擦怎么通知上位機(jī)“我現(xiàn)在忙你別發(fā)數(shù)據(jù)”。第二個(gè)常見(jiàn)坑是安全訪問(wèn)算法和上位機(jī)約定不清就會(huì)導(dǎo)致解鎖失敗。第三個(gè)坑是跳轉(zhuǎn)APP前要做棧指針和首指令校驗(yàn)否則跳過(guò)去直接hardfault。做這個(gè)項(xiàng)目時(shí)我建議你每天給自己設(shè)定一個(gè)小目標(biāo)今天打通0x10會(huì)話明天把0x27搞定后天能收到0x34并寫進(jìn)Flash。這樣成就感能維持住不會(huì)中途放棄。4.2 項(xiàng)目二實(shí)現(xiàn)網(wǎng)絡(luò)管理狀態(tài)機(jī)并做到低功耗做過(guò)Bootloader之后你基本已經(jīng)把“診斷鏈路”吃透了。接下來(lái)我建議做“網(wǎng)絡(luò)管理低功耗管理”項(xiàng)目這個(gè)是量產(chǎn)ECU落地時(shí)極為關(guān)鍵的環(huán)節(jié)也是面試官特別愛(ài)深挖的點(diǎn)。整車對(duì)靜態(tài)電流要求很嚴(yán)格車停在那里所有ECU必須盡快進(jìn)入休眠。在AutoSar里這由BswM、EcuM、CanNm和Can驅(qū)動(dòng)協(xié)同完成。你要實(shí)現(xiàn)的核心場(chǎng)景是上電后ECU處于Network模式周期性發(fā)送網(wǎng)絡(luò)管理報(bào)文告訴其他ECU“我醒著呢”。當(dāng)整車上電結(jié)束后不再需要通信CanNm進(jìn)入Ready Sleep狀態(tài)開始等待總線上是否還有遠(yuǎn)程喚醒請(qǐng)求。如果等了一個(gè)超時(shí)周期沒(méi)有收到NM報(bào)文就進(jìn)入Prepare Bus-Sleep模式此時(shí)BswM會(huì)停止應(yīng)用報(bào)文發(fā)送釋放通信通道。最后EcuM調(diào)用底層驅(qū)動(dòng)關(guān)掉CAN收發(fā)器進(jìn)入Bus-Sleep。這個(gè)項(xiàng)目里涉及一個(gè)很實(shí)用的器件支持部分網(wǎng)絡(luò)式喚醒的CAN收發(fā)器比如TJA1145。它和普通CAN收發(fā)器不一樣帶一個(gè)INH引腳可以控制外部穩(wěn)壓器的供電。ECU要休眠時(shí)MCU通過(guò)SPI或引腳給收發(fā)器配置成待機(jī)模式然后把INH拉低把整個(gè)通信域的電源切斷靜態(tài)電流可以降到微安級(jí)別。喚醒的時(shí)候外圍的硬線信號(hào)或總線活動(dòng)會(huì)把INH拉高重新上電MCU因此被喚醒。我在實(shí)際項(xiàng)目中就踩過(guò)這個(gè)坑CAN總線上明明已經(jīng)沒(méi)有任何報(bào)文了ECU卻遲遲不進(jìn)休眠。排查了大半天最后發(fā)現(xiàn)是TJA1145的INH引腳沒(méi)有正確配置導(dǎo)致整個(gè)收發(fā)器一直在給穩(wěn)壓器供電當(dāng)然睡不下去。這種問(wèn)題你光看軟件代碼是看不出來(lái)的必須對(duì)著硬件數(shù)據(jù)手冊(cè)和示波器去查。4.3 項(xiàng)目三給ECU做一套DTC管理第三個(gè)項(xiàng)目相對(duì)簡(jiǎn)單但同樣重要DTC診斷故障碼管理。Dem模塊管的就是這件事。你需要做的是在Dem里定義幾個(gè)事件比如“傳感器電壓過(guò)高”“CAN通信丟失”然后設(shè)置事件的狀態(tài)位TestFailed、ConfirmedDTC、PendingDTC等。在代碼里當(dāng)檢測(cè)到故障時(shí)調(diào)用Dem_SetEventStatus報(bào)告給Dem故障消失時(shí)調(diào)用Dem_ResetEventStatus。Dem會(huì)把故障狀態(tài)存到NvM里保證下電不掉。做完這個(gè)項(xiàng)目你就能理解為什么診斷儀能讀出“歷史故障”。里面有個(gè)老化Aging機(jī)制故障不是一好就立刻消失必須滿足一定條件才清除。很多新手搞不清楚PendingDTC和ConfirmedDTC的區(qū)別實(shí)操一遍就明白了。這三個(gè)項(xiàng)目做完你的基礎(chǔ)軟件能力已經(jīng)能和很多社招候選人拉開差距了。4.4 車載以太網(wǎng)和SOME/IP可以放到第二年再看車載以太網(wǎng)是熱詞很多人問(wèn)我現(xiàn)在要不要學(xué)。我的真實(shí)建議是如果你是剛?cè)腴T的新手先別急著鋪太大攤子把CAN這條線吃透再說(shuō)。但如果你想往域控制器、智能駕駛方向發(fā)展那車載以太網(wǎng)這塊遲早要補(bǔ)。車載以太網(wǎng)的物理層和普通以太網(wǎng)不一樣用的是單對(duì)雙絞線支持100BASE-T1或1000BASE-T1。應(yīng)用層常跑SOME/IP協(xié)議它的核心是基于服務(wù)的通信ECU之間通過(guò)服務(wù)發(fā)現(xiàn)SOME/IP-SD機(jī)制互相發(fā)現(xiàn)。比如一個(gè)ECU對(duì)外提供服務(wù)它會(huì)周期性廣播OfferService報(bào)文另一個(gè)ECU需要這個(gè)服務(wù)就發(fā)SubscribeEvent雙方建立通信關(guān)系。如果你有STM32開發(fā)板可以買一個(gè)車載以太網(wǎng)PHY模塊比如博通或NXP的百兆T1收發(fā)器做一些基礎(chǔ)實(shí)驗(yàn)先理解PHY芯片怎么配置、怎么通過(guò)MII/RMII口和MAC對(duì)接。入門資料可以從IEEE 802.3bw標(biāo)準(zhǔn)看起比直接看SOME/IP協(xié)議好理解。5. 面試、求職與職業(yè)路線規(guī)劃5.1 高頻面試題把知識(shí)樹檢查一遍學(xué)了那么多最后要落到面試。我梳理了一下車載底層軟件開發(fā)崗位的高頻面試方向你可以在找工作前按這個(gè)表格自查。面試方向高頻問(wèn)題答題要點(diǎn)AutoSar架構(gòu)畫一下CP的分層架構(gòu)RTE起到什么作用要能完整畫出SWC-RTE-BSW說(shuō)明解耦思想CAN通信CAN幀結(jié)構(gòu)、波特率計(jì)算、位時(shí)序會(huì)算采樣點(diǎn)知道CAN_H/CAN_L差分電壓CanTp單幀/首幀/連續(xù)幀/流控幀的區(qū)別STmin作用結(jié)合一次UDS刷寫過(guò)程講分包流程診斷UDS 0x10、0x27、0x34、0x36的服務(wù)流程能說(shuō)清每個(gè)服務(wù)請(qǐng)求和響應(yīng)的格式網(wǎng)絡(luò)管理節(jié)點(diǎn)狀態(tài)有哪些怎么進(jìn)入總線睡眠能畫出Bus-Sleep到Network Mode的狀態(tài)跳轉(zhuǎn)NvM寫入策略掉電保護(hù)怎么做提到雙Block管理、校驗(yàn)和、立即寫/延遲寫OSOSEK OS任務(wù)調(diào)度中斷優(yōu)先級(jí)設(shè)計(jì)能說(shuō)出優(yōu)先級(jí)反轉(zhuǎn)的概念就更好了工具用過(guò)哪些配置工具和調(diào)試工具如實(shí)說(shuō)沒(méi)商用工具就講自己用開源方案做的項(xiàng)目面試時(shí)比背誦知識(shí)點(diǎn)更重要的是能講出一個(gè)完整的故事。哪怕只是一個(gè)Bootloader項(xiàng)目你能把架構(gòu)、分工、遇到的問(wèn)題、最后的解決方案講清楚面試官對(duì)你的評(píng)價(jià)就會(huì)很高。5.2 車載測(cè)試崗位要不要考慮我在熱詞里看到大量“車載測(cè)試”相關(guān)的搜索說(shuō)明很多新人最先接觸到的崗位是測(cè)試。我的觀點(diǎn)是測(cè)試崗位完全可以作為入行切入點(diǎn)但它和開發(fā)崗位的工作方式差別很大。車載測(cè)試的核心是驗(yàn)證功能、找Bug你會(huì)接觸到各種測(cè)試工具CANoe、CANalyzer等熟悉各種協(xié)議流程也能快速了解一個(gè)ECU的完整功能邏輯。這些經(jīng)驗(yàn)對(duì)后續(xù)轉(zhuǎn)開發(fā)是很有幫助的尤其是“測(cè)試思維”——開發(fā)時(shí)你會(huì)下意識(shí)考慮異常輸入和邊界情況寫出更穩(wěn)健的代碼。但也要提醒你如果你最終目標(biāo)是做底層開發(fā)別在純測(cè)試崗位停留太久。測(cè)試和開發(fā)使用的工具鏈重疊度其實(shí)沒(méi)那么高測(cè)試久了容易手生。我的建議是測(cè)試崗位做半年到一年期間保持寫代碼、看代碼的習(xí)慣然后主動(dòng)申請(qǐng)轉(zhuǎn)崗或跳槽到開發(fā)崗。5.3 學(xué)習(xí)周期規(guī)劃怎么定給你一個(gè)參考的學(xué)習(xí)周期表可以根據(jù)自己的時(shí)間靈活調(diào)整時(shí)間段學(xué)習(xí)目標(biāo)重點(diǎn)產(chǎn)出第1-2月補(bǔ)基礎(chǔ)C語(yǔ)言、STM32裸機(jī)外設(shè)開發(fā)能自己寫CAN收發(fā)程序第3-4月建立AutoSar架構(gòu)概念學(xué)習(xí)通信棧能畫出整體數(shù)據(jù)流理解CanTp核心第5-6月配置工具入門跑通一個(gè)最小工程能用CAN卡收到自己ECU發(fā)送的報(bào)文第7-8月完成UDS Bootloader項(xiàng)目能用診斷工具刷寫APP第9-10月完成網(wǎng)絡(luò)管理低功耗項(xiàng)目能實(shí)現(xiàn)ECU正常休眠喚醒第11-12月綜合演練整理簡(jiǎn)歷和面試題完成DTC管理復(fù)盤所有項(xiàng)目簡(jiǎn)歷上寫項(xiàng)目時(shí)別只寫“參與開發(fā)”“負(fù)責(zé)配置”。要寫清楚項(xiàng)目背景、你負(fù)責(zé)的模塊、具體解決的技術(shù)難題、用了哪些工具、最后達(dá)到什么效果。比如“我在Bootloader項(xiàng)目中負(fù)責(zé)CanTp參數(shù)調(diào)優(yōu)通過(guò)分析流控幀時(shí)序?qū)⑺懰俣忍嵘?0%”這種描述比“熟悉CanTp配置”有說(shuō)服力得多。6. 新手最容易踩的坑我先替你踩一遍6.1 坑一一上來(lái)就啃AUTOSAR官方標(biāo)準(zhǔn)文檔這是新手最常見(jiàn)的誤區(qū)。AUTOSAR官方文檔動(dòng)輒幾百頁(yè)語(yǔ)言極其抽象里面全是模塊接口和參數(shù)定義。沒(méi)有充足的上下文和實(shí)操經(jīng)驗(yàn)看兩頁(yè)就犯困看完一章啥也記不住。我的建議是把它當(dāng)工具書不要當(dāng)教材。平時(shí)查某個(gè)參數(shù)的含義、看某個(gè)接口的定義可以翻但系統(tǒng)的學(xué)習(xí)路徑應(yīng)以“架構(gòu)圖demo工程項(xiàng)目實(shí)踐”為主。6.2 坑二只理解概念不動(dòng)手配置眼睛會(huì)了手不會(huì)AutoSar是“配置驅(qū)動(dòng)”的開發(fā)模式所有模塊都需要在配置工具里一步步搭起來(lái)。很多同學(xué)看視頻、看文章覺(jué)得挺明白一到自己開個(gè)工程就傻眼。我建議你無(wú)論如何也要想辦法搞到能用的配置工具或者demo工程哪怕只是把別人的工程重新編譯一遍、改幾個(gè)參數(shù)燒進(jìn)去觀察變化也比純看書強(qiáng)十倍。你至少要完整跑通過(guò)一次“配置-生成-編譯-燒錄-驗(yàn)證”的閉環(huán)。6.3 坑三只盯軟件不看硬件出了問(wèn)題沒(méi)法定位有一次我調(diào)試一個(gè)ECU進(jìn)入不了網(wǎng)絡(luò)模式軟件配置檢查了無(wú)數(shù)遍狀態(tài)機(jī)邏輯也推演了好幾輪都沒(méi)發(fā)現(xiàn)問(wèn)題。后來(lái)拿了示波器去量TJA1145收發(fā)器的VCC引腳發(fā)現(xiàn)電壓根本沒(méi)有。再看原理圖發(fā)現(xiàn)這個(gè)收發(fā)器的供電是受INH引腳控制的而INH信號(hào)來(lái)自一個(gè)GPIO初始化時(shí)序不對(duì)導(dǎo)致收發(fā)器供電一直被切斷。這雖然是個(gè)硬件問(wèn)題但如果你沒(méi)有硬件排查的意識(shí)只會(huì)在軟件里打轉(zhuǎn)轉(zhuǎn)可能幾天都出不來(lái)。所以我一直建議做底層開發(fā)的朋友至少要學(xué)會(huì)看原理圖、查數(shù)據(jù)手冊(cè)、用示波器量關(guān)鍵波形。這不僅是硬件工程師的事底層軟件離硬件太近你必須兩條腿走路。6.4 常見(jiàn)問(wèn)題速查表現(xiàn)象可能原因排查方法ECU無(wú)法進(jìn)入總線睡眠NM仍在發(fā)送報(bào)文BswM睡眠條件不滿足本地喚醒源一直有效用CAN卡抓總線看NM幀是否消失查BswM邏輯量收發(fā)器INH和供電診斷儀發(fā)0x34報(bào)錯(cuò)CanTp塊大小和STmin配置不當(dāng)Flash不可寫安全訪問(wèn)算法不對(duì)先抓CanTp幀看流控時(shí)序再查Flash地址區(qū)間刷寫完成后無(wú)法跳轉(zhuǎn)APPAPP有效性標(biāo)志位未置位跳轉(zhuǎn)地址錯(cuò)誤棧指針?lè)欠z查0x31服務(wù)有沒(méi)有執(zhí)行成功讀APP首地址內(nèi)容喚醒時(shí)間太長(zhǎng)BswM超時(shí)配置過(guò)大總線喚醒檢測(cè)周期過(guò)長(zhǎng)按時(shí)間軸打日志定位在哪一步延遲最大配置工具生成后編譯報(bào)一堆錯(cuò)模塊依賴未配齊ECU Extract和工具版本不匹配按依賴關(guān)系重新梳理配置順序優(yōu)先修MCAL層CAN報(bào)文發(fā)不出去CAN控制器波特率沒(méi)對(duì)上收發(fā)器供電異常CAN_H/CAN_L接反示波器量波形確認(rèn)顯性位電平檢查原理圖學(xué)習(xí)車載底層嵌入式開發(fā)這件事確實(shí)不像學(xué)Linux驅(qū)動(dòng)那樣有大量現(xiàn)成教程可以刷很多經(jīng)驗(yàn)要靠踩坑才能獲得。但換個(gè)角度看正因?yàn)殚T檻高、資料少這個(gè)方向才值得投入。我個(gè)人在實(shí)際過(guò)程中的最大體會(huì)是AutoSar知識(shí)體系雖然龐大但它的核心思想并不復(fù)雜就是一套經(jīng)過(guò)工業(yè)實(shí)踐檢驗(yàn)的軟件分層和接口規(guī)范。你不需要一開始把每個(gè)模塊都學(xué)到精通完全可以只抓住一條主線——從CAN通信棧切入打通一條數(shù)據(jù)通路再逐步擴(kuò)展。這一條路走通之后你會(huì)發(fā)現(xiàn)自己看所有AutoSar資料都不再那么困難了。最后再分享一個(gè)小技巧學(xué)習(xí)過(guò)程中務(wù)必保持“輸出”。每學(xué)完一個(gè)模塊就用自己的話寫一篇筆記或者做一個(gè)小測(cè)試程序驗(yàn)證一次。因?yàn)榭炊妥龅街g的差距只有在你親自動(dòng)手做完一個(gè)完整工程的那一瞬間才能真正感受到。做完之后你會(huì)覺(jué)得車載底層的世界其實(shí)就那么大你完全能hold住。