機(jī)制詳解:從Profile選型到DaVinci配置實(shí)戰(zhàn))
1. 為什么汽車?yán)锏耐ㄐ判枰话选懊艽a鎖”第一次接觸AUTOSAR E2EEnd-to-End保護(hù)機(jī)制的人多半會(huì)有個(gè)疑問(wèn)CAN總線本來(lái)就有CRC校驗(yàn)以太網(wǎng)也有幀校驗(yàn)為什么還要在應(yīng)用層再疊一層保護(hù)這不是脫褲子放屁嗎我當(dāng)初也是這么想的直到有一次在臺(tái)架上復(fù)現(xiàn)了一個(gè)通信故障——網(wǎng)關(guān)路由轉(zhuǎn)發(fā)時(shí)因?yàn)榫彌_區(qū)溢出把兩幀報(bào)文的數(shù)據(jù)段拼接錯(cuò)了CRC居然沒(méi)報(bào)錯(cuò)因?yàn)镃RC只覆蓋單幀內(nèi)容拼接后的幀CRC是重新算過(guò)的。結(jié)果就是一個(gè)剎車扭矩請(qǐng)求被錯(cuò)誤地映射成了驅(qū)動(dòng)扭矩請(qǐng)求。這個(gè)場(chǎng)景讓我徹底理解了E2E存在的意義。E2E保護(hù)的核心目標(biāo)不是防黑客而是防“系統(tǒng)性失效”。它要解決的是數(shù)據(jù)在ECU內(nèi)部軟件棧、總線傳輸、網(wǎng)關(guān)路由、接收端軟件棧這一整條鏈路上可能出現(xiàn)的數(shù)據(jù)損壞、重復(fù)、丟失、亂序、延遲這五類問(wèn)題。CRC只管傳輸介質(zhì)上的比特翻轉(zhuǎn)管不了軟件層面的邏輯錯(cuò)誤。E2E就是在應(yīng)用層給數(shù)據(jù)加一把“密碼鎖”讓接收方能夠驗(yàn)證這幀數(shù)據(jù)是不是發(fā)送方真正發(fā)出來(lái)的、是不是最新的、有沒(méi)有被篡改或重復(fù)。在AUTOSAR體系里E2E保護(hù)由E2E LibraryE2E_Lib和E2E TransformerE2E_Transformer配合實(shí)現(xiàn)。E2E Library提供算法E2E Transformer負(fù)責(zé)在RTE層自動(dòng)調(diào)用這些算法對(duì)Signal Group進(jìn)行保護(hù)和解保護(hù)。這套機(jī)制在ISO 26262的功能安全語(yǔ)境下是達(dá)到ASIL D等級(jí)通信的必備手段。這篇文章適合誰(shuí)看如果你是剛接觸AUTOSAR的嵌入式軟件工程師正在被DaVinci Configurator里那一堆E2E參數(shù)搞得頭大或者你是系統(tǒng)架構(gòu)師需要決定哪些信號(hào)組需要E2E保護(hù)、選哪種Profile又或者你是測(cè)試工程師想理解E2E故障注入該怎么設(shè)計(jì)——那這篇內(nèi)容應(yīng)該能幫你省下不少翻規(guī)范的時(shí)間。2. E2E保護(hù)的整體設(shè)計(jì)思路與Profile選型2.1 E2E在AUTOSAR通信棧中的位置要理解E2E先得搞清楚它在整個(gè)通信棧里站在哪一層。AUTOSAR的通信棧從下往上大致是CAN Driver → CAN Interface → CAN Transport Protocol → PDU Router → COM → RTE → SWC。E2E Transformer是掛在RTE和COM之間的一個(gè)轉(zhuǎn)換層它不改變PDU的布局而是在原有數(shù)據(jù)的基礎(chǔ)上往PDU的頭部或尾部插入E2E Header包含CRC、Counter、Data ID等信息。發(fā)送方向SWC通過(guò)RTE發(fā)送Signal Group → E2E Transformer調(diào)用E2E_Lib的Protect函數(shù) → 計(jì)算CRC、遞增Counter、填入Data ID → 修改后的PDU交給COM → 最終發(fā)到總線上。接收方向總線上的PDU到達(dá)COM → COM交給E2E Transformer → E2E Transformer調(diào)用E2E_Lib的Check函數(shù) → 驗(yàn)證CRC、檢查Counter連續(xù)性、比對(duì)Data ID → 驗(yàn)證通過(guò)則把原始數(shù)據(jù)交給SWC驗(yàn)證失敗則丟棄或上報(bào)。這個(gè)架構(gòu)的關(guān)鍵在于E2E保護(hù)對(duì)SWC是透明的。SWC只管收發(fā)數(shù)據(jù)不需要知道E2E Header的存在。E2E Transformer在RTE生成代碼時(shí)自動(dòng)插入保護(hù)邏輯這也是為什么DaVinci Configurator里配置完E2E后必須重新生成RTE代碼的原因。2.2 Profile選型不是越復(fù)雜越好AUTOSAR定義了多種E2E Profile從Profile 1到Profile 7還有Profile 4和5的變體每種Profile的CRC算法、Counter位數(shù)、Header長(zhǎng)度、Data ID模式都不一樣。選型的時(shí)候不能拍腦袋得根據(jù)實(shí)際需求來(lái)。ProfileCRC算法Counter位數(shù)Header長(zhǎng)度適用場(chǎng)景Profile 1CRC-8 (0x1D)4 bit1字節(jié)小數(shù)據(jù)量、低實(shí)時(shí)性要求Profile 2CRC-8 (0x2F)4 bit1字節(jié)與Profile 1類似CRC多項(xiàng)式不同Profile 4CRC-328 bit3字節(jié)大數(shù)據(jù)量、高安全性要求Profile 5CRC-168 bit2字節(jié)中等數(shù)據(jù)量、平衡安全與開(kāi)銷Profile 6CRC-168 bit2字節(jié)支持多路復(fù)用信號(hào)Profile 7CRC-6432 bit8字節(jié)極高安全性要求、以太網(wǎng)場(chǎng)景Profile 11CRC-88 bit2字節(jié)兼容舊版E2E逐步淘汰Profile 22CRC-88 bit2字節(jié)兼容舊版E2E逐步淘汰選型的核心考量因素有三個(gè)數(shù)據(jù)長(zhǎng)度、安全等級(jí)要求、總線負(fù)載容忍度。Profile 1和2的Header只有1字節(jié)開(kāi)銷最小但Counter只有4 bit意味著最多只能區(qū)分16個(gè)連續(xù)幀。如果通信周期是10ms16幀就是160ms超過(guò)這個(gè)窗口就無(wú)法檢測(cè)重復(fù)幀了。所以Profile 1/2適合那些對(duì)實(shí)時(shí)性要求不高、但總線負(fù)載緊張的場(chǎng)景比如車身控制模塊的燈光狀態(tài)廣播。Profile 4的CRC-32強(qiáng)度最高但Header占3字節(jié)對(duì)于8字節(jié)的CAN報(bào)文來(lái)說(shuō)有效數(shù)據(jù)只剩5字節(jié)開(kāi)銷太大。Profile 4通常用在以太網(wǎng)通信或者CAN FD的大數(shù)據(jù)幀場(chǎng)景。Profile 5是我個(gè)人最推薦的“甜點(diǎn)”選擇。CRC-16的檢錯(cuò)能力足夠應(yīng)對(duì)大多數(shù)場(chǎng)景2字節(jié)Header在8字節(jié)CAN報(bào)文里占25%可以接受。Counter是8 bit能區(qū)分256個(gè)連續(xù)幀覆蓋的窗口足夠大。Profile 5還支持Data ID的兩種模式Both模式發(fā)送方和接收方都校驗(yàn)Data ID和Alt模式只校驗(yàn)Counter和CRC靈活性好。Profile 7的CRC-64和32 bit Counter是為以太網(wǎng)SOME/IP通信設(shè)計(jì)的CAN場(chǎng)景基本用不上。注意Profile 6和Profile 5的區(qū)別在于Profile 6支持多路復(fù)用信號(hào)Multiplexed Signal如果你的Signal Group里有Mux信號(hào)必須選Profile 6。這個(gè)坑我在一個(gè)項(xiàng)目里踩過(guò)當(dāng)時(shí)選了Profile 5結(jié)果Mux切換時(shí)E2E校驗(yàn)一直失敗查了兩天才發(fā)現(xiàn)是Profile選錯(cuò)了。2.3 Data ID的分配策略Data ID是E2E保護(hù)里的一個(gè)關(guān)鍵參數(shù)它相當(dāng)于這組信號(hào)的“身份證號(hào)”。發(fā)送方把Data ID填進(jìn)Header接收方比對(duì)收到的Data ID是否和自己配置的一致。如果不一致說(shuō)明這幀數(shù)據(jù)可能來(lái)自錯(cuò)誤的發(fā)送方或者PDU被錯(cuò)誤路由了。Data ID的分配有兩種模式Both模式發(fā)送方和接收方都配置相同的Data ID接收方會(huì)校驗(yàn)。這種模式安全性更高但要求發(fā)送方和接收方的配置嚴(yán)格一致。如果發(fā)送方改了Data ID而接收方?jīng)]改通信直接斷掉。Alt模式發(fā)送方不填Data ID或者填0接收方也不校驗(yàn)Data ID只校驗(yàn)CRC和Counter。這種模式配置簡(jiǎn)單但安全性略低適合那些PDU路由路徑固定、不會(huì)出現(xiàn)錯(cuò)誤路由的場(chǎng)景。我的經(jīng)驗(yàn)是跨ECU的通信一律用Both模式ECU內(nèi)部的SWC間通信可以用Alt模式??鏓CU通信時(shí)PDU可能經(jīng)過(guò)網(wǎng)關(guān)路由存在被錯(cuò)誤路由的風(fēng)險(xiǎn)Data ID校驗(yàn)是必要的。ECU內(nèi)部通信路徑固定Alt模式足夠。Data ID的取值也有講究。AUTOSAR規(guī)范建議Data ID不要用0x0000和0xFFFF這兩個(gè)值容易和未初始化內(nèi)存混淆。我通常會(huì)用信號(hào)的CAN ID作為Data ID的基礎(chǔ)值再加上一個(gè)偏移量確保唯一性。3. E2E核心細(xì)節(jié)解析與DaVinci配置實(shí)操3.1 E2E Library的集成方式在DaVinci Configurator里配置E2E第一步是確認(rèn)E2E Library已經(jīng)集成到工程里。E2E Library通常以靜態(tài)庫(kù).a或.lib的形式提供需要手動(dòng)添加到鏈接器配置里。有些版本的DaVinci Configurator會(huì)自動(dòng)集成但大多數(shù)情況下需要手動(dòng)操作。具體步驟打開(kāi)DaVinci Configurator → 進(jìn)入Project Settings → Linker → Additional Libraries → 添加E2E_Lib的路徑。如果是Vector的MICROSAR系列E2E Library通常在MICROSAR/E2E/目錄下文件名類似E2E_Lib.a。添加完庫(kù)之后需要在E2E模塊的配置里指定使用的Profile。每個(gè)Profile對(duì)應(yīng)一個(gè)獨(dú)立的配置容器比如E2EProfile5、E2EProfile4等。你用了哪些Profile就只配置哪些容器沒(méi)用的不用管。實(shí)操心得E2E Library的版本必須和DaVinci Configurator的版本匹配。我有一次用了舊版的E2E Lib配新版的Configurator編譯能過(guò)但運(yùn)行時(shí)報(bào)CRC校驗(yàn)一直失敗查了半天發(fā)現(xiàn)是CRC查表算法的實(shí)現(xiàn)變了。版本不匹配這個(gè)問(wèn)題很隱蔽建議在項(xiàng)目初期就鎖定版本。3.2 E2E Transformer的配置E2E Transformer的配置是核心環(huán)節(jié)。在DaVinci Configurator的ECUC配置樹(shù)里找到E2E模塊下面會(huì)有E2ETransformer和E2EProfileX兩類容器。E2ETransformer配置每個(gè)需要E2E保護(hù)的Signal Group對(duì)應(yīng)一個(gè)E2ETransformer容器。容器里需要配置E2EProfile選擇使用的Profile比如E2E_PROFILE_5。DataIdData ID的值Both模式下發(fā)送方和接收方要一致。DataIdModeBoth或Alt。CounterOffsetCounter在PDU中的字節(jié)偏移。CRCOffsetCRC在PDU中的字節(jié)偏移。DataIdOffsetData ID在PDU中的字節(jié)偏移Profile 5的Data ID是隱含在CRC計(jì)算里的不需要單獨(dú)占字節(jié)。這里有個(gè)容易搞混的地方CounterOffset和CRCOffset是相對(duì)于PDU起始位置的字節(jié)偏移不是相對(duì)于Signal Group的偏移。E2E Header通常放在PDU的頭部所以CounterOffset一般是0CRCOffset是1Profile 5的Header是2字節(jié)1字節(jié)Counter 1字節(jié)CRC。E2EProfile5配置這個(gè)容器里配置Profile 5的全局參數(shù)主要是WindowSize接收窗口大小和MaxDeltaCounter最大Counter跳變值。WindowSize決定了接收方在判定通信失敗前能容忍多少個(gè)連續(xù)的錯(cuò)誤幀通常設(shè)為3到5。MaxDeltaCounter用于檢測(cè)Counter跳變?nèi)绻盏降腃ounter和期望值差距超過(guò)這個(gè)閾值就判定為通信故障。3.3 RTE生成與代碼集成E2E配置完成后必須重新生成RTE代碼。在DaVinci Configurator里點(diǎn)擊“Generate RTE”按鈕工具會(huì)自動(dòng)在RTE代碼里插入E2E Transformer的調(diào)用。生成的代碼里發(fā)送方向的E2E保護(hù)邏輯通常在Rte_Write_SignalGroup()函數(shù)里接收方向的解保護(hù)邏輯在Rte_Read_SignalGroup()或Rte_Receive_SignalGroup()函數(shù)里。你可以打開(kāi)生成的Rte.c文件搜索E2E_Protect和E2E_Check關(guān)鍵字確認(rèn)調(diào)用已經(jīng)插入。如果發(fā)現(xiàn)RTE代碼里沒(méi)有E2E調(diào)用通常是兩個(gè)原因一是E2ETransformer容器沒(méi)有關(guān)聯(lián)到對(duì)應(yīng)的Signal Group二是Signal Group沒(méi)有正確配置為“E2E保護(hù)”類型。在Signal Group的配置里有一個(gè)E2EProtection屬性必須設(shè)為true。避坑指南RTE生成后不要手動(dòng)修改Rte.c里的E2E調(diào)用代碼。下次重新生成RTE時(shí)手動(dòng)修改會(huì)被覆蓋。如果需要調(diào)整E2E行為應(yīng)該改E2E Transformer的配置而不是改生成的代碼。3.4 參數(shù)計(jì)算CRC和Counter的具體實(shí)現(xiàn)Profile 5的CRC-16算法使用的是CRC-16/CCITT-FALSE多項(xiàng)式0x1021初始值0xFFFF不反轉(zhuǎn)輸入輸出。這個(gè)算法在E2E Library里已經(jīng)實(shí)現(xiàn)好了你不需要自己寫但理解它的計(jì)算過(guò)程有助于排查問(wèn)題。CRC的計(jì)算范圍包括Data ID如果DataIdMode是Both、Counter、以及Signal Group的所有數(shù)據(jù)字節(jié)。注意CRC不覆蓋PDU里的其他字節(jié)比如其他Signal Group的數(shù)據(jù)。這也是為什么E2E Transformer需要知道Signal Group的精確布局——它只對(duì)屬于這個(gè)Signal Group的字節(jié)計(jì)算CRC。Counter的遞增邏輯每次發(fā)送時(shí)Counter加1到達(dá)最大值后回繞到0。Profile 5的Counter是8 bit所以回繞周期是256。接收方維護(hù)一個(gè)期望Counter值收到幀后計(jì)算(ReceivedCounter - ExpectedCounter) mod 256如果結(jié)果在MaxDeltaCounter范圍內(nèi)則認(rèn)為Counter正常更新期望值否則判定為通信故障。這里有個(gè)細(xì)節(jié)Counter的初始值不是0而是1。AUTOSAR規(guī)范規(guī)定Counter從1開(kāi)始0保留給“未初始化”狀態(tài)。如果你在測(cè)試時(shí)發(fā)現(xiàn)第一幀總是校驗(yàn)失敗檢查一下發(fā)送方的Counter初始值是不是設(shè)成了0。4. 完整實(shí)操流程從零配置一個(gè)E2E保護(hù)的Signal Group4.1 前提條件與工程準(zhǔn)備假設(shè)你已經(jīng)有一個(gè)可以正常編譯和運(yùn)行的AUTOSAR工程CAN通信已經(jīng)調(diào)通COM和PDU Router配置完畢。現(xiàn)在需要給一個(gè)已有的Signal Group加上E2E保護(hù)。這個(gè)Signal Group的場(chǎng)景是一個(gè)電機(jī)控制器通過(guò)CAN向整車控制器發(fā)送電機(jī)轉(zhuǎn)速和扭矩信息CAN ID是0x123數(shù)據(jù)長(zhǎng)度8字節(jié)周期10ms。轉(zhuǎn)速占2字節(jié)偏移0-1扭矩占2字節(jié)偏移2-3其余4字節(jié)保留。4.2 第一步創(chuàng)建E2E Profile 5配置容器在DaVinci Configurator的ECUC配置樹(shù)里展開(kāi)E2E模塊右鍵E2EProfile5→Add E2EProfile5。新建的容器命名為E2EProfile5_MotorCtrl。在容器里配置參數(shù)WindowSize設(shè)為3。這意味著接收方連續(xù)3幀校驗(yàn)失敗后才上報(bào)通信故障避免偶發(fā)干擾導(dǎo)致誤報(bào)。MaxDeltaCounter設(shè)為1。正常情況下Counter每次加1允許跳變1是為了容忍偶爾的丟幀。CRCFailureThreshold設(shè)為3。連續(xù)3次CRC失敗后觸發(fā)故障回調(diào)。4.3 第二步創(chuàng)建E2E Transformer容器右鍵E2ETransformer→Add E2ETransformer命名為E2ETransformer_MotorCtrl。配置參數(shù)E2EProfile選擇E2E_PROFILE_5。DataId設(shè)為0x123和CAN ID一致方便追溯。DataIdMode選擇BOTH。CounterOffset設(shè)為0。CRCOffset設(shè)為1。DataIdOffsetProfile 5不需要單獨(dú)的Data ID字節(jié)這個(gè)參數(shù)留空或設(shè)為0xFFFF。4.4 第三步關(guān)聯(lián)Signal Group找到這個(gè)Signal Group的配置容器通常在Com模塊下的ComSignalGroup里打開(kāi)它的屬性頁(yè)。找到E2EProtection屬性設(shè)為true。然后在E2ETransformerRef屬性里選擇剛才創(chuàng)建的E2ETransformer_MotorCtrl。這一步是關(guān)鍵Signal Group必須同時(shí)配置E2EProtection和E2ETransformerRef缺一不可。只設(shè)E2EProtection不設(shè)E2ETransformerRefRTE生成時(shí)不會(huì)插入E2E調(diào)用只設(shè)E2ETransformerRef不設(shè)E2EProtectionE2E Transformer不會(huì)生效。4.5 第四步調(diào)整PDU布局E2E Header需要占用PDU的字節(jié)。Profile 5的Header是2字節(jié)Counter CRC所以原本8字節(jié)的PDU現(xiàn)在只有6字節(jié)可用于有效數(shù)據(jù)。但我們的Signal Group只用了4字節(jié)轉(zhuǎn)速2字節(jié)扭矩2字節(jié)所以還有2字節(jié)余量不需要調(diào)整PDU長(zhǎng)度。如果Signal Group的數(shù)據(jù)超過(guò)了PDU長(zhǎng)度減去Header長(zhǎng)度就需要擴(kuò)展PDU長(zhǎng)度。比如CAN FD場(chǎng)景下PDU長(zhǎng)度可以從8字節(jié)擴(kuò)展到16字節(jié)或64字節(jié)。具體操作在PduR模塊里找到對(duì)應(yīng)的PDU修改PduLength參數(shù)。然后在Com模塊里調(diào)整Signal Group的布局把E2E Header占用的字節(jié)讓出來(lái)。通常的做法是把Signal Group的起始偏移從0改為2讓Header占據(jù)前2字節(jié)。4.6 第五步生成RTE并驗(yàn)證點(diǎn)擊“Generate RTE”等待生成完成。打開(kāi)生成的Rte.c搜索E2E_Protect應(yīng)該能看到類似這樣的代碼/* E2E Protection for Signal Group MotorCtrl */ E2E_P05ProtectStateType E2E_P05ProtectState_MotorCtrl; E2E_P05ProtectConfigType E2E_P05ProtectConfig_MotorCtrl { .DataId 0x123, .DataIdMode E2E_P05_DATAID_BOTH, .CounterOffset 0, .CRCOffset 1, .DataLength 6 };在發(fā)送函數(shù)里會(huì)看到E2E_P05Protect(E2E_P05ProtectConfig_MotorCtrl, E2E_P05ProtectState_MotorCtrl, PduData[0]);接收方向的E2E_P05Check調(diào)用類似。確認(rèn)這些代碼存在后編譯工程下載到目標(biāo)板。4.7 第六步用CANoe驗(yàn)證E2E保護(hù)用CANoe或類似的總線分析工具抓包觀察0x123報(bào)文。你會(huì)看到前2字節(jié)是E2E Header第1字節(jié)是Counter從1開(kāi)始遞增第2字節(jié)是CRC。Counter每幀加1到255后回繞到0。在CANoe里可以寫一個(gè)簡(jiǎn)單的CAPL腳本驗(yàn)證CRCon message 0x123 { byte counter this.byte(0); byte crc this.byte(1); byte data[6]; for (int i 0; i 6; i) { data[i] this.byte(i 2); } // 調(diào)用E2E Library的CRC計(jì)算函數(shù)驗(yàn)證 // 實(shí)際項(xiàng)目中通常用CANoe的E2E插件自動(dòng)驗(yàn)證 }如果CRC校驗(yàn)通過(guò)說(shuō)明E2E保護(hù)配置正確。如果失敗檢查Data ID、CounterOffset、CRCOffset是否和配置一致。5. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄5.1 E2E校驗(yàn)一直失敗但CRC計(jì)算看起來(lái)沒(méi)問(wèn)題這是最常見(jiàn)的問(wèn)題通常有以下幾個(gè)原因原因一Data ID不匹配。發(fā)送方和接收方的Data ID配置不一致或者DataIdMode選錯(cuò)了一方是Both另一方是Alt。排查方法用CANoe抓包手動(dòng)計(jì)算CRC對(duì)比發(fā)送方填的CRC值。如果手動(dòng)算出來(lái)的CRC和發(fā)送方填的不一樣說(shuō)明發(fā)送方的Data ID或DataIdMode配置有問(wèn)題。原因二Counter初始值不對(duì)。AUTOSAR規(guī)定Counter從1開(kāi)始如果發(fā)送方從0開(kāi)始接收方期望的是1第一幀就會(huì)失敗。排查方法抓包看第一幀的Counter值應(yīng)該是1。原因三Signal Group布局和E2E配置不匹配。E2E Transformer需要知道Signal Group在PDU里的精確位置。如果Signal Group的起始偏移是2但E2E配置里DataLength設(shè)成了8CRC計(jì)算范圍就錯(cuò)了。排查方法檢查Signal Group的ComBitPosition和E2E Transformer的DataLength是否一致。原因四字節(jié)序問(wèn)題。CAN通信通常是大端序Motorola但有些ECU配置成小端序Intel。如果發(fā)送方和接收方的字節(jié)序不一致CRC計(jì)算會(huì)出錯(cuò)。排查方法確認(rèn)Signal Group的ComSignalEndianness配置。5.2 Counter跳變導(dǎo)致通信中斷Counter跳變通常發(fā)生在ECU重啟或通信中斷恢復(fù)后。比如ECU A重啟Counter從1重新開(kāi)始但ECU B期望的Counter是100差距99超過(guò)了MaxDeltaCounter設(shè)為1ECU B判定通信故障。解決方法有兩種一是增大MaxDeltaCounter但這會(huì)降低安全性二是實(shí)現(xiàn)Counter同步機(jī)制ECU A重啟后先發(fā)送幾幀“同步幀”讓ECU B重置期望Counter。AUTOSAR規(guī)范里沒(méi)有定義同步機(jī)制需要自己實(shí)現(xiàn)。我的做法是在ECU啟動(dòng)后的前10幀里接收方不校驗(yàn)Counter只校驗(yàn)CRC。10幀之后開(kāi)始正常校驗(yàn)。這個(gè)邏輯可以通過(guò)E2E Library的E2E_P05Check返回值來(lái)實(shí)現(xiàn)——如果返回E2E_P05STATUS_SYNC說(shuō)明還在同步階段不報(bào)故障。5.3 E2E保護(hù)導(dǎo)致總線負(fù)載升高E2E Header占用了PDU字節(jié)如果PDU長(zhǎng)度不變有效數(shù)據(jù)就減少了。對(duì)于CAN 2.08字節(jié)Profile 5的2字節(jié)Header占25%Profile 4的3字節(jié)Header占37.5%。如果總線負(fù)載本來(lái)就高加上E2E后可能超過(guò)80%的警戒線。解決方案一是換用CAN FDPDU長(zhǎng)度擴(kuò)展到64字節(jié)Header占比降到3%左右二是優(yōu)化Signal Group布局把不重要的信號(hào)移出E2E保護(hù)范圍三是降低通信周期但這對(duì)實(shí)時(shí)性有影響。我個(gè)人的經(jīng)驗(yàn)是對(duì)于CAN 2.0場(chǎng)景優(yōu)先用Profile 5而不是Profile 4。Profile 5的CRC-16強(qiáng)度對(duì)于大多數(shù)車身和動(dòng)力總成應(yīng)用已經(jīng)足夠2字節(jié)Header比3字節(jié)更友好。5.4 常見(jiàn)問(wèn)題速查表現(xiàn)象可能原因排查方法解決方案第一幀就校驗(yàn)失敗Counter初始值不是1抓包看Counter值修改發(fā)送方Counter初始值為1偶發(fā)校驗(yàn)失敗總線干擾導(dǎo)致CRC錯(cuò)誤統(tǒng)計(jì)失敗率增大WindowSize容忍偶發(fā)錯(cuò)誤通信中斷后無(wú)法恢復(fù)Counter跳變超過(guò)MaxDeltaCounter抓包看Counter跳變幅度實(shí)現(xiàn)Counter同步機(jī)制或增大MaxDeltaCounterRTE代碼里沒(méi)有E2E調(diào)用Signal Group未關(guān)聯(lián)E2ETransformer檢查E2EProtection和E2ETransformerRef補(bǔ)全配置重新生成RTECRC計(jì)算范圍錯(cuò)誤DataLength配置不對(duì)對(duì)比Signal Group布局和E2E配置修改DataLength為Signal Group的實(shí)際字節(jié)數(shù)編譯報(bào)錯(cuò)找不到E2E函數(shù)E2E Library未鏈接檢查鏈接器配置添加E2E Lib到鏈接器5.5 獨(dú)家避坑技巧技巧一用CANoe的E2E插件自動(dòng)驗(yàn)證。Vector的CANoe有E2E插件可以自動(dòng)解析E2E Header并驗(yàn)證CRC和Counter。配置方法在CANoe的Simulation Setup里添加E2E節(jié)點(diǎn)導(dǎo)入E2E配置通常是從DaVinci導(dǎo)出的.arxml文件插件會(huì)自動(dòng)校驗(yàn)。這比手動(dòng)寫CAPL腳本效率高得多。技巧二在E2E失敗回調(diào)里加日志。E2E Library提供了失敗回調(diào)函數(shù)E2E_P05Check返回非OK時(shí)觸發(fā)可以在回調(diào)里記錄失敗原因CRC錯(cuò)誤、Counter錯(cuò)誤、Data ID錯(cuò)誤。這些日志在排查現(xiàn)場(chǎng)問(wèn)題時(shí)非常有用。技巧三用Data ID的Alt模式做過(guò)渡。如果項(xiàng)目從無(wú)E2E升級(jí)到有E2E發(fā)送方和接收方的升級(jí)時(shí)間可能不同步。可以先用Alt模式不校驗(yàn)Data ID等雙方都升級(jí)完再切到Both模式。這樣避免升級(jí)過(guò)程中的通信中斷。技巧四注意E2E Header和SecOC的沖突。如果同時(shí)用了SecOCSecure Onboard CommunicationSecOC也會(huì)在PDU里加Header通常是8字節(jié)的認(rèn)證器。E2E Header和SecOC Header的偏移不能重疊。通常SecOC Header放在PDU末尾E2E Header放在PDU頭部?jī)烧卟粵_突。但如果PDU長(zhǎng)度不夠就需要擴(kuò)展PDU或調(diào)整布局。技巧五E2E配置變更后必須重新生成RTE。E2E Transformer的配置是在RTE生成時(shí)靜態(tài)展開(kāi)的改了E2E配置不重新生成RTE代碼里的E2E參數(shù)還是舊的。這個(gè)坑我踩過(guò)不止一次每次都是編譯通過(guò)但運(yùn)行行為不對(duì)查半天才發(fā)現(xiàn)是忘了重新生成RTE。6. E2E與NvM、網(wǎng)絡(luò)管理的協(xié)同6.1 E2E保護(hù)的數(shù)據(jù)在NvM里的存儲(chǔ)E2E保護(hù)的數(shù)據(jù)通常也需要存儲(chǔ)到NvMNon-Volatile Memory里比如電機(jī)的故障碼、整車的配置參數(shù)。但E2E HeaderCounter和CRC不應(yīng)該存到NvM里因?yàn)镃ounter是通信相關(guān)的重啟后應(yīng)該重置CRC是每幀計(jì)算的存儲(chǔ)沒(méi)有意義。正確的做法是在NvM存儲(chǔ)前先剝離E2E Header只存有效數(shù)據(jù)。讀取時(shí)從NvM讀出有效數(shù)據(jù)再重新加上E2E Header發(fā)送。這個(gè)剝離和添加的過(guò)程需要在SWC里手動(dòng)實(shí)現(xiàn)AUTOSAR沒(méi)有自動(dòng)機(jī)制。具體實(shí)現(xiàn)在SWC的Runnable里調(diào)用Rte_Read讀取E2E保護(hù)的數(shù)據(jù)時(shí)RTE已經(jīng)自動(dòng)剝離了HeaderSWC拿到的是有效數(shù)據(jù)。SWC把有效數(shù)據(jù)寫入NvM。上電時(shí)SWC從NvM讀出有效數(shù)據(jù)調(diào)用Rte_Write發(fā)送RTE會(huì)自動(dòng)加上E2E Header。注意NvM的Block ID和E2E的Data ID不要混淆。NvM Block ID是NvM模塊的內(nèi)部標(biāo)識(shí)E2E Data ID是通信標(biāo)識(shí)兩者沒(méi)有直接關(guān)系。6.2 E2E與AUTOSAR網(wǎng)絡(luò)管理的交互AUTOSAR網(wǎng)絡(luò)管理NM負(fù)責(zé)控制ECU的睡眠和喚醒。E2E保護(hù)和NM的交互點(diǎn)在于當(dāng)NM讓ECU進(jìn)入睡眠時(shí)E2E的Counter狀態(tài)需要保存嗎答案是不需要。E2E的Counter是通信相關(guān)的ECU睡眠后通信中斷喚醒后Counter重新從1開(kāi)始。接收方在檢測(cè)到通信恢復(fù)后會(huì)進(jìn)入同步階段不校驗(yàn)Counter。所以E2E的Counter狀態(tài)不需要保存到NvM。但有一個(gè)例外如果ECU支持“部分網(wǎng)絡(luò)”Partial Networking某些Signal Group在睡眠期間仍然保持通信這些Signal Group的E2E Counter需要保持連續(xù)性。這種情況下Counter狀態(tài)需要保存在RAM里不是NvM喚醒后繼續(xù)遞增。6.3 E2E在28服務(wù)通信控制下的行為AUTOSAR的28服務(wù)Communication Control用于禁用或啟用通信。當(dāng)28服務(wù)禁用某個(gè)PDU的發(fā)送時(shí)E2E的Counter應(yīng)該停止遞增還是繼續(xù)遞增AUTOSAR規(guī)范的建議是28服務(wù)禁用通信時(shí)E2E的Counter停止遞增。因?yàn)橥ㄐ疟唤煤蠼邮辗绞詹坏綆珻ounter遞增沒(méi)有意義。當(dāng)28服務(wù)重新啟用通信時(shí)Counter從停止時(shí)的值繼續(xù)遞增接收方通過(guò)同步機(jī)制重新同步。實(shí)現(xiàn)方式在28服務(wù)的回調(diào)函數(shù)里調(diào)用E2E Library的E2E_P05ProtectState重置函數(shù)把Counter狀態(tài)重置為初始值?;蛘咴?8服務(wù)禁用期間不調(diào)用E2E_P05Protect函數(shù)Counter自然不遞增。這個(gè)細(xì)節(jié)在配置DaVinci時(shí)容易被忽略。如果28服務(wù)禁用通信后Counter還在遞增接收方重新啟用通信時(shí)會(huì)發(fā)現(xiàn)Counter跳變觸發(fā)通信故障。排查這個(gè)問(wèn)題需要抓包看28服務(wù)禁用前后的Counter變化。7. 測(cè)試與驗(yàn)證如何確認(rèn)E2E保護(hù)真的生效了7.1 故障注入測(cè)試E2E保護(hù)的價(jià)值在于它能檢測(cè)故障所以測(cè)試的核心是故障注入。常見(jiàn)的故障注入場(chǎng)景場(chǎng)景一篡改數(shù)據(jù)字節(jié)。用CANoe發(fā)送一幀數(shù)據(jù)被修改的報(bào)文接收方應(yīng)該檢測(cè)到CRC錯(cuò)誤丟棄該幀并上報(bào)通信故障。場(chǎng)景二重復(fù)發(fā)送同一幀。用CANoe連續(xù)發(fā)送兩幀完全相同的報(bào)文Counter相同接收方應(yīng)該檢測(cè)到Counter重復(fù)丟棄第二幀。場(chǎng)景三跳過(guò)Counter。用CANoe發(fā)送Counter跳變的報(bào)文比如從1跳到5接收方應(yīng)該檢測(cè)到Counter跳變超過(guò)MaxDeltaCounter上報(bào)通信故障。場(chǎng)景四延遲發(fā)送。用CANoe延遲發(fā)送報(bào)文接收方應(yīng)該檢測(cè)到通信超時(shí)如果配置了超時(shí)監(jiān)控上報(bào)通信故障。場(chǎng)景五錯(cuò)誤Data ID。用CANoe發(fā)送Data ID不匹配的報(bào)文接收方應(yīng)該檢測(cè)到Data ID錯(cuò)誤丟棄該幀。每個(gè)場(chǎng)景都需要驗(yàn)證接收方是否正確檢測(cè)到故障、是否丟棄了故障幀、是否上報(bào)了故障碼、故障恢復(fù)后通信是否自動(dòng)恢復(fù)。7.2 用CANoe的E2E插件做自動(dòng)化測(cè)試CANoe的E2E插件支持自動(dòng)化測(cè)試。你可以寫一個(gè)測(cè)試用例自動(dòng)發(fā)送各種故障幀然后檢查接收方的故障碼。測(cè)試用例可以用CAPL或XML編寫集成到CANoe的Test Module里。一個(gè)典型的測(cè)試用例結(jié)構(gòu)testcase E2E_CRC_Failure() { // 發(fā)送一幀CRC錯(cuò)誤的報(bào)文 message 0x123 msg; msg.byte(0) 1; // Counter msg.byte(1) 0xFF; // 錯(cuò)誤的CRC msg.byte(2) 0x12; msg.byte(3) 0x34; // ... 填充數(shù)據(jù) output(msg); // 等待接收方上報(bào)故障 testWaitForSignalUpdate(E2E_CRC_Failure_Flag, 1, 1000); // 驗(yàn)證故障碼 testVerifySignal(E2E_CRC_Failure_Flag, 1); }這種自動(dòng)化測(cè)試可以在每次代碼變更后快速回歸確保E2E保護(hù)沒(méi)有被破壞。7.3 實(shí)測(cè)中的性能影響E2E保護(hù)會(huì)增加CPU負(fù)載因?yàn)槊繋瞻l(fā)都要計(jì)算CRC。CRC-16的計(jì)算量不大對(duì)于10ms周期的報(bào)文CPU負(fù)載增加通常在1%以內(nèi)。但如果ECU上有很多E2E保護(hù)的Signal Group累積負(fù)載可能達(dá)到5%-10%。實(shí)測(cè)數(shù)據(jù)在一個(gè)有20個(gè)E2E保護(hù)Signal Group的ECU上CPU負(fù)載從45%增加到52%增加了7個(gè)百分點(diǎn)。這個(gè)增量在可接受范圍內(nèi)但如果ECU的CPU負(fù)載本來(lái)就接近80%就需要考慮優(yōu)化。優(yōu)化方法一是用硬件CRC加速器如果MCU支持二是減少E2E保護(hù)的Signal Group數(shù)量只保護(hù)安全相關(guān)的信號(hào)三是增大通信周期減少每秒的CRC計(jì)算次數(shù)。我個(gè)人在實(shí)際項(xiàng)目中的體會(huì)是E2E保護(hù)的開(kāi)銷主要不在CRC計(jì)算而在RTE的調(diào)用開(kāi)銷。每次Rte_Write都要經(jīng)過(guò)E2E Transformer這個(gè)函數(shù)調(diào)用鏈比直接寫COM要長(zhǎng)。如果對(duì)性能極度敏感可以考慮在SWC里直接調(diào)用E2E Library繞過(guò)E2E Transformer但這樣會(huì)失去AUTOSAR的標(biāo)準(zhǔn)化優(yōu)勢(shì)需要權(quán)衡。最后再分享一個(gè)小技巧在DaVinci Configurator里配置E2E時(shí)可以先把所有參數(shù)導(dǎo)出成.arxml文件用文本編輯器批量修改再導(dǎo)入回去。對(duì)于有幾十個(gè)Signal Group需要配置E2E的項(xiàng)目這比在GUI里一個(gè)個(gè)點(diǎn)效率高得多。導(dǎo)出時(shí)注意選擇“Export E2E Configuration”只導(dǎo)出E2E相關(guān)的部分避免覆蓋其他配置。