文章總列表

ESP32的韌體更新

緣起

用ESP32做好的玩具,部署到遠方得提供韌體更新服務。這篇幫通用資料紀錄器新增最簡單的韌體更新

  • 用電腦把update.bin(新韌體)放入SD卡
  • 裝置上電,偵測SD卡有update.bin開始更新,每刷4KB閃爍LED,韌體看得到
  • 更新完把update.bin更名成update.bin.done

ESP32 SDK 預設採用單一factory分區,沒有韌體更新機制。這篇介紹怎麼加入雙 OTA 韌體更新,寫給未來的我讀(三兩下就忘了)


更改SDK Config

  • vscode設定SDK的頁面,根據板子WIKI,這片開發版有4MB Flash,調整設定

  • 調整分割表設定
    • 選擇全客製化表格(我們自己掌控一切)


    • 在專案root folder加入partitions.csv,ota_0 & ota_1是放APP的,尺寸是1.625MB。這裡可以設計Flash的布局


    • 儲存SDK設定
      • 不直接把sdkconfig存到版本控制,因為SDK進版,可能設定和順序都改了;到時候diff分不出是SDK改動,還是我們的設定改動
      • 樂鑫建議的步驟:修改完開啟ESP-IDF Terminal
        • 執行idf.py save-defconfig,他會比對差異,把更動寫在sdkconfig.defaults。這個檔案再寫入版本控制


      • 從sdkconfig.defaults重建sdkconfig
        • idf.py reconfigure


觀察軟體版本,執行的partition

在web介面多印一些資訊,之後能觀測韌體更新是否成功

  • 印出當前的韌體資訊,包括git資訊,最後一次submit的hash,日期,時間;編譯的日期和時間,以及當前是跑哪個partition(把這些放標準printf()也可以)


  • Source code如下



  • CMakeLists.txt新增"app_update"才吃得到對應header


韌體更新實作

在開機初始化的地方,安插底下的邏輯

  • 需要在SD卡初始化之後才能執行
  • 具體實作
    • 檢查/sdcard/update.bin是否存在,不在就離開
    • 跟OTA系統拿到 next partition,以及宣告開始更新






    • 配置記憶體,讀檔,新韌體寫入Flash,以及每寫一塊讓LED閃爍


    • 告訴OTA系統更新結束,計算checksum,以及下次開機切換成新的partition


    • 重新開機



執行結果

首先故意讓網頁的TITLE額外多顯示一點字



重新編譯軟體,build/esp32_can_logger.bin複製貼上到SD卡,並且更名成update.bin。SD卡放回裝置上電,看到LED閃爍,之後顯示的資訊如下圖:TITLE已經改過,編譯的時間確實變化,然後partitions從ota_0變成ota_1




結語

多年前我有手刻過bootloader,翻閱datasheet和technical manual,從英文猜出機器的設計,在一團迷霧裡匍匐前進,這種開發體驗實在不大健康,效率也低

這次弄ESP32韌體更新設計,用AI輔助設計,幾乎沒翻原廠範例和文件,都是直接問AI。事後來看,就算直接照著他的步驟和code,大概也能簡單的把機制動起來。先讓東西動起來,再從會動的東西學習(以物為師),大概是最有效率的方案

這篇是我加入韌體更新的小抄,背後的原理我也有挖掘寫在ESP32開機載入過程,可以搭著看


留言

這個網誌中的熱門文章

ELM327 OBD-II 心得 (2),ELM327底層介面

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

玩CAN bus的傢伙們 (1) CandleLight-based USB-CAN