文章總列表

ELM327 OBD-II 心得 (9),驗屍報告3,CANBUS起碼要有兩個裝置!

給開發板做個家

亂成一團的設備也是Bug來源,我請收納專家(老婆)幫忙改善。收納真的是專業!
  • 開發板的針腳插入泡棉當底座,底座再用熱熔膠貼在盒子裡
    • 專家:網購的紙箱都是用熱熔膠固定,唯一答案
  • 杜邦線用束帶固定在盒子邊緣
    • 專家:這種紙不能用膠帶黏,束帶才是正解,還可以反覆調整
  • 在盒子挖洞固定OBD-II頭(熱熔膠固定),以及走USB線
    • MCU開發板,供電和燒錄用
    • OBD-II供電,5V轉12V給設備用
    • 樹莓派供電
      • 這篇文章最後的結論:樹莓派妙用無窮!







玩MCU還是要沾醬油(Data Sheet)

換STM32優點是環境單純,而且STM給了CAN驅動程式,沾醬油(Reference Manual)服用更美味,這份文件有1954頁。我想起十年前刻S3C2410 bootloader的往事,整份datasheet大概600頁我也幾乎讀遍,把peripheral driver全部寫一輪

開卷有益,我對CAN Bus又有一些新的了解,也修掉幾個Bug。底下文字我純粹留個紀錄,客官看看就好
  • STM32 boot code預設沒開CAN重傳,這個功能必須打開
    • 封包從HUD轉發到汽車時,很有可能被忙碌的CAN BUS撞掉,需要重傳
    • 如果沒開重傳,STM32發送失敗就會丟掉封包,於是HUD以為車子不理他
    • STM的register命名很爛:NART,No Auto ReTransmission
      • 我自己寫軟體很注意正向表列,0關閉,1打開,符合人類直覺才好debug
      • 名字要正向表列才對,改成ENART(Enable Auto ReTransmission)
  • STM32的CAN-TX很強,Mailbox能承受3個message排隊
    • 直接發送封包即可,如果queue滿了軟體印條紀錄就好
      • 拔掉畫蛇添的semaphore可以拔掉(沒寫他造成程式鎖死)
  • STM32的CAN-RX也很強,有兩套FIFO,每套FIFO都能存3個message
    • 基本上不大需要擔心buffer overflow
  • STM32的CAN1/CAN2共享資源,需要透過CAN1幫CAN2設定Filter的起點和參數
    • 他硬體就是這樣做,不知道就會卡很久

靈光一閃

其實關鍵的問題就是:汽車和我的書桌究竟哪裡不一樣,為什麼書桌上OK,汽車會死。HUD設計時,應該預期連上活的網路,上面有很多裝置在溝通,眾聲喧嘩;書桌上的網路很安靜。中間人攻擊發動時,我會有兩個CAN網路

  • CAN1
    • CAR or Pi-CAR
    • RPi-MITM
  • CAN2
    • HUD
    • RPi-MITM
設備接上汽車,封包會從CAN1不斷轉發到CAN2。如果HUD還沒上電,等於CAN2只剩RPi-MITM。他自顧自的發送封包,但是沒人理他。這時CAN控制器內部的
TEC (Transmit Error Count)會不斷累加,數到255就自己消音進入bus-off狀態,不再打Ack。我設定RPi等10ms會解開Bus-Off。這代表HUD加入時,如果RPi正在耍自閉(Bus-OFF),HUD也會沒反應

假如HUD加入網路瞬間,RPi-MITM把堆在TX-Queue的東西一股腦送出(我又把Queue弄得很深1024,清光需要0.2秒),變成HUD的查詢要等很久才發出,最後就time-out死掉。也許我可以把TX-Queue弄淺一點作實驗,不過還是會周期的進入Bus-off狀態,這樣解不漂亮

所以正確的解法是滿足HUD設計的場景:隨時都有兩個以上的CAN裝置
  • CAN1
    • CAR or Pi-CAR
    • STM32-CAN1 (package forwarding)
    • RPi-CAN0 (dummy client/ sniffer)
  • CAN2
    • HUD or VIDA-DICE
    • STM32-CAN2 (package forwarding)
    • SRPi-CAN1 (dummy client/ sniffer)
同時放上RPi和STM32,利用STM32轉發,HUD上電就是活的網路,理論上就能正常運作。RPi好用就在這裡:他可以滿足CAN網路的需要(起碼兩個元件),也可以當監聽設備,還可以輕鬆保存大量資料(高速CPU,很大的記憶體,GB等級的儲存空間)。我本來還在煩惱怎麼從STM32取數據出來(在考慮要不要搞USB或Ethernet),暫時可以省掉這個工夫




其實中間人的延遲比想像得再多一點

中間人串起的兩個網路,如果是無條件轉發,兩個封包的負載完全一樣:從HUD發資料到CAR會多吃一發arbitration delay
  • HUD封包在CAN2發送時,先承受一次Arbitration delay
  • 在CAN1發送到汽車時,還要再承受一次Arbitration delay
如果是查詢速度的封包,優先順序特別低(7DF/ 7E8),這個延遲在忙碌的bus會特別久。第一篇驗屍報告沒想到這點,不過上一篇我發現HUD其實對延遲沒那麼敏感,這題我就跳過了。如果真的很在乎,可以在CAN2只讓7DF/7E8通過


STM32的開發環境

最後我想聊一下開發環境,底下是我用的工具和挑選的理由
  • STM32 CUBEMX
    • STM提供的boot code generator,可以不用自己手刻,配置環境很方便
    • 想玩USB也有資源
  • Atollic True Studio
    • 純粹當GCC編譯工具,不用折騰toolchain,同時避免用Keil ARM這類版權物
    • 他的編輯器我用不慣,Code complete無法用
    • Debugger透過gdb連線的體驗不大好,無法attach上裝置;不過他的OS awareness有FreeRTOS,可以看semaphore,Queue的狀態,改天可以試試看
  • Sublime text 3
    • 近年來我愛用的編輯器,Windows/Linux跨平台
  • Convert ST-Link on-board into a J-Link
  • Segger OZone Debugger
    • 專業,免費,而且還是跨平台(Windows/ MacOS/ Linux)的debugger
    • 大部分的IDE都有Debugger,但是未必用得順手
      • Keil ARM的debugger很好用,不過要錢,未必用得心安理得
      • Attolic True Studio這類gdb-based debugger有時候真的難用
    • SEGGER OZone有專人維護,而且好用,值得投資時間精通
  • Amazon FreeRTOS
    • 感謝Amazon買下FreeRTOS,以前要賣錢的文件現在可以以直接下載
      • 這個年代,拉攏開發者就對了
    • MCU寫一個while(1)搭配中斷是一種玩法,這個適合寫小程式
    • MCU搭配Real Time Kernel是另一種風情,可以架構大型程式。如果要挑一個投資時間,有富爸爸Amazon撐腰的FreeRTOS絕對是上上之選,裡面已經有現成的TCP/IP stack(注意,這個以前要賣錢的),日後想玩IoT也可以

留言

這個網誌中的熱門文章

STM32 UART + DMA,使用HAL實作TX/RX,以及不定長度接收

幼犬書桌椅選擇心得 升降桌 兒童桌椅

CANON G3000 廢墨瓶改裝