樂鑫官網樂鑫信息科技ESP32-C3wifi模組固件OTA升級原理功能,前面介紹了分區表的個條目起始地址為 0x9000,為什么不是 0x0 這個地址呢? 又為什么是 0x9000 呢? Flash 被分為了 8個區域,0x00 地址存放了 Bootloader (啟動加載程儲的具體內容。序),0x8000 存放了分區表,后面6個就很熟悉了,從0x9000 開始便是分區表所劃分的區域?,F在我們可以回答第一個問題了,因為 0x0 地址存放了 Botloader 程序(并非所有芯片 Flash 的 0x0 地址都存放著 Bootloader。樂鑫官網樂鑫信息科技ESP32-C3wifi模組系列芯片的 Bootloader 存放在 0x1000 地址處),它用于加載并引導應用分區。在樂鑫科技的芯片程序設計中,Bootloader 被稱為二級導程序,其主要作用為增加 Flash 分區的靈活性,并且方便實現 Flash 加密、安全引導和OT升級 等功能。二級引導程序默認從 Flash 的 0x8000 偏移地址處加載分區表,分區表的大小頭0x1000,二級引導程序會從分區表中尋找出廠應用分區和 OTA 升級數據分區,并通過查詢OTA 升級數據分區來確定引導哪個分區,現在第 2 個問題也找到了答案。
樂鑫官網樂鑫信息科技ESP32-C3wifi模組從上電到運行 app_main()函數的過程可以分為如下 3 個步驟:
(1)由一級引導程序進行引導。一級引導程序被固化在了 ESP32-C3 內部的 ROM 中,芯片復位后,CPU 會立即開始運行,判斷啟動模式并執行相關操作,從 Flash 的 0x0 偏移地址處將二級引導程序加載到 RAM 中。
(2) 由二級引導程序進行引導。二級引導程序將首先從 Flash 中加載分區表,然后查詢 OTA升級數據分區,并選擇某個應用分區的固件進行加載。當處理完所有數據后,二級引導程序將校驗固件的完整性,并從二進制固件文件的頭部尋找入口地址,跳轉到該地址處運行。應用分區的固件擁有一些狀態,這些狀態會影響固件的啟動。這些狀態保存在 OTA 升級數據分區,在樂鑫官網樂鑫信息科技ESP32-C3wifi模組ESP-IDF 中由一組枚舉變量 (esp_ota_img_states_t) 定義。
1)新固件:由ESP_OTA_IMG_NEW定義,標記固件是否為第一次被 Bootloader 加載。在引導加載程序中,此狀態更改為 ESP_OTA_IMG_PENDING_VERIEY。
2) 待校驗的固件:由ESP_OTA_IMG_PENDING_VERIEY定義,標記固件是否被啟用。如果第二次啟動時仍然為此狀態,則它將被更改為 ESP_OTA_IMG_ABORTED。
3)有效固件:由 ESP_OTA_IMG_VALID定義,標記固件能夠正常運行。一旦被標識為該狀態,此固件能夠無限制啟動。
4)無效固件: 由 ESP_OTA_IMG_INVALID 定義,標記固件無法正常運行。一旦被標識為該狀態,此固件將無法再次被啟動。
5)異常固件:由 ESP_TAIME_ABORTED 定義,標記件存在異常。一旦被標為該狀態,此固件將無法再次被啟動。
6)不明確的固件:由ESP_OTA_IMS_UMDSFINED 定義,若標記固件狀態為不明確,則該因固件能夠無限制啟動。
(3)應用程序啟動階段。二級引導程序跳轉后便是應用固件的啟動階段,該階段包含了從應圍程序開始執行到 app_main()函數創建運行前的所有過程。樂鑫官網樂鑫信息科技ESP32-C3wifi模組可分為三個部分:
1)硬件和基本端口的初始化。
2)軟件服務和 FreeRTOS 系統的初始化。
3)運行主任務并調用 app_main()函數。
OTA 升級原理概述
物聯網設備進行 OTA 升級的第一步是獲取新固件。獲取新固件的方式有很多,使用 Wi-Fi 獲取是其中較為簡單、方便的一種方式。物聯網設備可以通過 Wi-Fi 連接到路由器,進而連接到OTA 升級服務器,通過一些應用層協議 (如 HTTP、FTP) 下載固件。樂鑫官網樂鑫信息科技ESP32-C3wifi模組將介紹一種通過HTTPS 下載固件的方式,這里我們以 advanced_https_ota (esp-idf/examples/system/ota/advanced_https_ota)為示例,該示例使用 esp_https_ota 組件完成OTA 升級,該組件使用的下載協議為 HTTPS。
(1)固件獲取。上述代碼使用 HTTPS 協議完成了固件的下載,ESP-IDF 對 HTTPS 操作進行了封裝。僅需配置 esp_http_client_config_t 結構體即可,在該結構體中可以傳遞證書并啟用 TLS 協議來保護傳輸的數據安全。在完成 HTTPS 連接參數配置后,樂鑫官網樂鑫信息科技ESP32-C3wifi模組需要將填寫的配置傳遞給 esp_https_ota_config_t 結構體,該結構體提供了一個回調函數,方便設置 HTTPS 請求頭部信息(Request Header)。頭部信息一般用于向服務器端聲明HTTPSBody 的長度、數據格式等。在完成配置后就可以調用 esp_https_ota_begin()函數進行連接了,該函數將根據HTTPS 返回的狀態碼(HTTPS Status Code)判斷結果。當完成HTTPS連接后,后續就可以循環調用 esp_https_ota_perform ()函數請求固件。
(2) 固件寫入。Esp_https_ota_perform()函數將不斷向服務器端發送請求信息,并將每一次服務器端返回的數據寫入設備的 Flash 中,寫入過程是在該函數內部通過調用esp_ota_write()函數實現的。
(3)固件校驗??紤]到接收設備的資源有限、網絡環境不一定理想等情況,有時往往需要多次發送 HTTPS 請求才能完整地下載固件,樂鑫官網樂鑫信息科技ESP32-C3wifi模組ESP-IDF 提供了 esp_https_ota_iscomplete_data_ received ()函數,該函數可通過計算固件的大小來判斷是否完整接收了固件。一旦完整接收了固件,就調用 esp_https_ota_finish()函數結束 HTTPS 連接釋放所占用的資源。僅僅通過對比固件大小是否一致來判斷固件是否有效是不完善的,我們還需要校驗固件的 SHA-256 值來確保下載的固件與原固件是完全一致的,調用函數esp_https_ota_finish()可自動完成校驗工作。
(4) 固件切換。Esp_https_ota_finish()函數不僅會釋放 HTTPS 資源和校驗固件,還會在校驗成功后自動改寫 OTA 升級數據分區,并同時將本次下載固件的狀態更新為不明確固件 (ESP_OTA_IMG_UNDEFINED)。在一切準備工作結束后,調用 esp_restart ()函數再此啟動的固件就是新固件。此處的不明確固件是指在 Bootloader 未開啟回滾時,固件可以無限制啟動。
固件版本管理
將不同功能的固件標記為不同版本是方便后期維護的一個重要手段。樂鑫官網樂鑫信息科技ESP32-C3wifi模組ESP-IDF 提供了一些標記字段,可用于標記版本信息,這些字段與回滾/防回滾功能搭配使用可滿足大部分版本管控的需求。
11.2.1 固件標記
可供進行編輯的字段有 4 個,分別為 secure version (安全版本號)、project_version (工程版本號)、project_name (工程名稱)與App version (應用版本);不可編輯的字段有2個,分別是 idf_ver (ESP-IDF 版本)與 Compile time and date (編譯時間與日期)。
(1) secure_version。安全版本號,用于設定芯片的安全版本,安全版本號存儲在 eFuse中,多能標記 16 個版本。啟用方式如下:
(Top) - Bootloader config
...
...
[*] Enable app rollback support
[*]Enable app anti-rollback support
(0)eFuse secure version of app (NEW)
(16)Size of the eFuse secure version field (NEW)
...
...
(2) project_version。工程版本號,用于設定工程的版本。啟用方式如下:
(Top) - Application manager
...
...
[*] Get the project version from Kconfig
(1)Project version
...
...
(3) project_name。工程名稱,在工程目錄下的 CMakeLists.txt 文件中進行設置,以advanced_ https_ota 工程為例,啟用方式如下:
1. ...
2. ...
3.include ($ENV(IDF_PATH)/tools/emake/project.cmake)
4.project (advanced_https_ota)
5. ...
6. ...
project(X)為標記的工程名稱。
(4) compile time and date (編譯時間和日期)與 idf_ver (ESP-IDF 版本)將在編譯時自動賦值,從 Log 中可看到下述如下內容:
...
...
(304)Cpu_start: Coplile time: Mar 14 2022 18:44:
(316)Cpu_start: ESP-IDF: v4.
安全版本號與工程版本號都可以用于標記固件版本信息,但它們的側重點與實現方式不同。安全版本號寫入樂鑫官網樂鑫信息科技ESP32-C3wifi模組芯片的 eFuse 中,一旦寫入便不可被更改,該芯片之后只允許寫入更高版本號的固件,這種特性可以安全有效地管控重要的更新。重要的更新一般與安全相關,所以稱為安全版本號。工程版本號跟隨固件存放在 Flash 中,可以在每次編譯時隨意更改,設備更新時不主動檢查該信息,使用方式完全由開發者決定。在實際的開發應用中,因為安全版本號有使用次數限制,一般將提升安全版本號定義為包含了重要功能更新、修復了安全漏洞,將提升工程版本號作為業務層面功能更新使用。
回滾與防回滾功能
應用程序回滾的主要目的是確保設備在更新后一旦發生異常能夠及時回退到上一個版本,不影響設備的正常使用。在啟用回滾功能時,當校驗固件完成后此固件將被標記為新固件(ESP_OTA_IMG_NEW),樂鑫官網樂鑫信息科技ESP32-C3wifi模組在重啟時 Bootloader 將選擇該固件并將其重新標記為待校驗(ESP_OTA_IMG_PENDING_VERIEY),在運行 app_main()函數時可能出現以下兩種情況:
1)應用程序運行正常。開發者自測確定功能一切正常,由開發者調用 esp_ota_mark_app_valid_cancel_rollback() 函數將正在運行的固件狀態標記為有效固件 (ESP_OTA_IMG_VALID),該固件隨后便可無限制啟動。
2)應用程序出現嚴重錯誤。因為異常導致自動二次重啟,這種情況 Bootloader 會直接將該固件標記為異常固件 (ESP_OTA_IMG_ABORTED) 并回滾到上一版本。開發者自測確定功能存在異常,由開發者調用 esp_ota_mark_app_invalid_rollback_and_reboot()函數將正在運行的版本標記為無效固件 (ESP_OTA_IMG_INVALID) 并自動重啟回滾到上一版本,該固件隨后便無法再啟動。
全版本號的另一個作用是防止固件回滾到更低的安全版本號。在 Bootloader 選擇可啟動的應用程序時,會額外檢查安全版本號,只有固件的安全版本號等于或高于芯片 eFuse 中存儲的安全版本號,此固件才會被選擇,樂鑫官網樂鑫信息科技ESP32-C3wifi模組新的安全版本號將在固件狀態被標記為有效固件(ESP_OTA_IMG_VALID) 后被更新。
回滾與防回滾功能都可以通過 menuconfig 啟動,啟用方式如下:
(Top) - Bootloader config
...
...
[*] Enable app rollback support
[*]Enable app anti-rollback support
(0)eFuse secure version of app (NEW)
(16)Size of the eFuse secure version field (NEW)
...
...