官方有通過WIFI的更新樣例召嘶,如果要自主實現(xiàn)BLE的升級,只能自己上了。在網(wǎng)上瞎找還不如好好看看官方文檔夸溶。
Over The Air Updates (OTA)
OTA Process Overview
The OTA update mechanism allows a device to update itself based on data received while the normal firmware is running (for example, over WiFi or Bluetooth.)
——可以通過BLE升級。
OTA requires configuring the Partition Table of the device with at least two “OTA app slot” partitions (ie ota_0 and ota_1)and an “OTA Data Partition”.
——需要先配置分區(qū)表的兩個運(yùn)行分區(qū)和一個OTA數(shù)據(jù)分區(qū)
The OTA operation functions write a new app firmware image to whichever OTA app slot is not currently being used for booting. Once the image is verified, the OTA Data partition is updated to specify that this image should be used for the next boot.
——ota_0 ota_1輪換被使用凶硅,OTA Data partition標(biāo)識那個分區(qū)正在使用
OTA Data Partition
An OTA data partition (type data
, subtype ota
) must be included in the Partition Table of any project which uses the OTA functions.
——OTA必須配置OTA data partition
For factory boot settings, the OTA data partition should contain no data (all bytes erased to 0xFF). In this case the esp-idf software bootloader will boot the factory app if it is present in the the partition table. If no factory app is included in the partition table, the first available OTA slot (usually ota_0
) is booted.
——如果有出廠APP缝裁,OTA data partition應(yīng)被格式化為0xFF。如果無出廠默認(rèn)APP足绅,將會啟動可用OTA分區(qū)
After the first OTA update, the OTA data partition is updated to specify which OTA app slot partition should be booted next.
——一旦某個OTA分區(qū)被更新捷绑,OTA data將會指過去
The OTA data partition is two flash sectors (0x2000 bytes) in size, to prevent problems if there is a power failure while it is being written. Sectors are independently erased and written with matching data, and if they disagree a counter field is used to determine which sector was written more recently.
——OTA數(shù)據(jù)分區(qū) 將會使用兩個獨(dú)立的扇區(qū)來存取,防止扇區(qū)寫入時突發(fā)性寫入失敗氢妈。萬一出現(xiàn)兩個扇區(qū)不一致粹污,計數(shù)器可以確定哪個是寫入失敗的。
App rollback
The main purpose of the application rollback is to keep the device working after the update. This feature allows you to roll back to the previous working application in case a new application has critical errors. When the rollback process is enabled and an OTA update provides a new version of the app, one of three things can happen:
——擁有回滾機(jī)制允懂,防止更新失敗厕怜。回滾啟動后有以下三種情況:
- The application works fine,
esp_ota_mark_app_valid_cancel_rollback()
marks the running application with the stateESP_OTA_IMG_VALID
. There are no restrictions on booting this application.
——應(yīng)用正常蕾总,esp_ota_mark_app_valid_cancel_rollback將其標(biāo)記為ESP_OTA_IMG_VALID粥航,此狀態(tài)啟用無限制。 - The application has critical errors and further work is not possible, a rollback to the previous application is required,
esp_ota_mark_app_invalid_rollback_and_reboot()
marks the running application with the stateESP_OTA_IMG_INVALID
and reset. This application will not be selected by the bootloader for boot and will boot the previously working application.
——應(yīng)用存在嚴(yán)重錯誤無法工作生百,啟動回滾至前一個版本递雀。esp_ota_mark_app_invalid_rollback_and_reboot將其標(biāo)記為ESP_OTA_IMG_INVALID,此應(yīng)用無法被引導(dǎo)啟動蚀浆。 - If the CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option is set, and a reset occurs without calling either function then the application is rolled back.
——通過配置CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE直接回滾程序缀程,無需調(diào)用接口
Note: The state is not written to the binary image of the application it is written to the otadata
partition. The partition contains a ota_seq
counter which is a pointer to the slot (ota_0, ota_1, …) from which the application will be selected for boot.
——回滾狀態(tài)存儲于數(shù)據(jù)存儲分區(qū),ota_seq來指向ota_0, ota_1市俊,用以標(biāo)記啟動哪個分區(qū)杨凑。
App OTA State
States control the process of selecting a boot app:
States | Restriction of selecting a boot app in bootloader |
---|---|
ESP_OTA_IMG_VALID | None restriction. Will be selected. |
ESP_OTA_IMG_UNDEFINED | None restriction. Will be selected. |
ESP_OTA_IMG_INVALID | Will not be selected. |
ESP_OTA_IMG_ABORTED | Will not be selected. |
ESP_OTA_IMG_NEW | If CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option is set it will be selected only once. In bootloader the state immediately changes to ESP_OTA_IMG_PENDING_VERIFY . |
ESP_OTA_IMG_PENDING_VERIFY | If CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option is set it will not be selected and the state will change to ESP_OTA_IMG_ABORTED . |
If CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option is not enabled (by default), then the use of the following functions esp_ota_mark_app_valid_cancel_rollback()
and esp_ota_mark_app_invalid_rollback_and_reboot()
are optional, and ESP_OTA_IMG_NEW
and ESP_OTA_IMG_PENDING_VERIFY
states are not used.
——配置回滾不開啟時,直接用 OTA 有效 和OTA無效 直接標(biāo)記APP狀態(tài)摆昧。
An option in Kconfig CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE allows you to track the first boot of a new application. In this case, the application must confirm its operability by calling esp_ota_mark_app_valid_cancel_rollback()
function, otherwise the application will be rolled back upon reboot. It allows you to control the operability of the application during the boot phase. Thus, a new application has only one attempt to boot successfully.
——配置回滾開啟時撩满,會跟蹤第一次啟動。如果程序可以正常啟動,必須調(diào)用OTA有效將state標(biāo)記為可用伺帘,路徑為:ESP_OTA_IMG_NEW--》ESP_OTA_IMG_PENDING_VERIFY--》ESP_OTA_IMG_VALID(這里需要調(diào)函數(shù))昭躺;否則會將啟動APP按照:ESP_OTA_IMG_NEW--》ESP_OTA_IMG_PENDING_VERIFY--》ESP_OTA_IMG_ABORTED(函數(shù)調(diào)用失敗)標(biāo)記為不可用伪嫁。新應(yīng)用程序在配置回滾開啟時會嘗試引導(dǎo)一次领炫,如果成功請標(biāo)記為可用,如果不可用张咳,將被自動忽略此版本帝洪。
Rollback Process
The description of the rollback process when CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option is enabled:
- The new application successfully downloaded and
esp_ota_set_boot_partition()
function makes this partition bootable and sets the stateESP_OTA_IMG_NEW
. This state means that the application is new and should be monitored for its first boot. - Reboot
esp_restart()
. - The bootloader checks for the
ESP_OTA_IMG_PENDING_VERIFY
state if it is set, then it will be written toESP_OTA_IMG_ABORTED
. - The bootloader selects a new application to boot so that the state is not set as
ESP_OTA_IMG_INVALID
orESP_OTA_IMG_ABORTED
. - The bootloader checks the selected application for
ESP_OTA_IMG_NEW
state if it is set, then it will be written toESP_OTA_IMG_PENDING_VERIFY
. This state means that the application requires confirmation of its operability, if this does not happen and a reboot occurs, this state will be overwritten toESP_OTA_IMG_ABORTED
(see above) and this application will no longer be able to start, i.e. there will be a rollback to the previous work application. - A new application has started and should make a self-test.
- If the self-test has completed successfully, then you must call the function
esp_ota_mark_app_valid_cancel_rollback()
because the application is awaiting confirmation of operability (ESP_OTA_IMG_PENDING_VERIFY
state). - If the self-test fails then call
esp_ota_mark_app_invalid_rollback_and_reboot()
function to roll back to the previous working application, while the invalid application is setESP_OTA_IMG_INVALID
state. - If the application has not been confirmed, the state remains
ESP_OTA_IMG_PENDING_VERIFY
, and the next boot it will be changed toESP_OTA_IMG_ABORTED
. That will prevent re-boot of this application. There will be a rollback to the previous working application.
——以上流程很清晰。配置回滾開啟晶伦,首次啟動后碟狞,如果正常則調(diào)用函數(shù)標(biāo)記為有效,否則標(biāo)記為無效婚陪,或者自動重啟后標(biāo)記為忽略狀態(tài)族沃。
Unexpected Reset
If a power loss or an unexpected crash occurs at the time of the first boot of a new application, it will roll back the application.
——新應(yīng)用啟動中發(fā)生意外,會迫使回滾發(fā)生泌参。
Recommendation: Perform the self-test procedure as quickly as possible, to prevent rollback due to power loss.
Only OTA
partitions can be rolled back. Factory partition is not rolled back.
——只有OTA分區(qū)可以回滾脆淹,出廠分區(qū)不支持回滾。
Booting invalid/aborted apps
Booting an application which was previously set to ESP_OTA_IMG_INVALID
or ESP_OTA_IMG_ABORTED
is possible:
——重啟ESP_OTA_IMG_INVALID和ESP_OTA_IMG_ABORTED失效APP
- Get the last invalid application partition
esp_ota_get_last_invalid_partition()
.
——esp_ota_get_last_invalid_partition獲得失效APP - Pass the received partition to
esp_ota_set_boot_partition()
, this will update theotadata
.
——將失效APP標(biāo)記為ESP_OTA_IMG_UNDEFINED 或者ESP_OTA_IMG_NEW - Restart
esp_restart()
. The bootloader will boot the specified application.
——重啟執(zhí)行
To determine if self-tests should be run during startup of an application, call theesp_ota_get_state_partition()
function. If result isESP_OTA_IMG_PENDING_VERIFY
then self-testing and subsequent confirmation of operability is required.
——esp_ota_get_state_partition==ESP_OTA_IMG_PENDING_VERIFY 為自檢沽一。
Where the states are set
A brief description of where the states are set:
——匯總狀態(tài)變更說明
-
ESP_OTA_IMG_VALID
state is set byesp_ota_mark_app_valid_cancel_rollback()
function. -
ESP_OTA_IMG_UNDEFINED
state is set byesp_ota_set_boot_partition()
function if CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option is not enabled. -
ESP_OTA_IMG_NEW
state is set byesp_ota_set_boot_partition()
function if CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option is enabled. -
ESP_OTA_IMG_INVALID
state is set byesp_ota_mark_app_invalid_rollback_and_reboot()
function. -
ESP_OTA_IMG_ABORTED
state is set if there was no confirmation of the application operability and occurs reboots (if CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option is enabled). -
ESP_OTA_IMG_PENDING_VERIFY
state is set in a bootloader if CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE option is enabled and selected app hasESP_OTA_IMG_NEW
state.
Anti-rollback
Anti-rollback prevents rollback to application with security version lower than one programmed in eFuse of chip.
——低版本時防回滾盖溺,開啟CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
This function works if set CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK option. In the bootloader, when selecting a bootable application, an additional security version check is added which is on the chip and in the application image. The version in the bootable firmware must be greater than or equal to the version in the chip.
CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK and CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE options are used together. In this case, rollback is possible only on the security version which is equal or higher than the version in the chip.
A typical anti-rollback scheme is
- New firmware released with the elimination of vulnerabilities with the previous version of security.
- After the developer makes sure that this firmware is working. He can increase the security version and release a new firmware.
- Download new application.
- To make it bootable, run the function
esp_ota_set_boot_partition()
. If the security version of the new application is smaller than the version in the chip, the new application will be erased. Update to new firmware is not possible.
——這里增加一層防回滾檢測 - Reboot.
- In the bootloader, an application with a security version greater than or equal to the version in the chip will be selected. If otadata is in the initial state, and one firmware was loaded via a serial channel, whose secure version is higher than the chip, then the secure version of efuse will be immediately updated in the bootloader.
- New application booted. Then the application should perform diagnostics of the operation and if it is completed successfully, you should call
esp_ota_mark_app_valid_cancel_rollback()
function to mark the running application with theESP_OTA_IMG_VALID
state and update the secure version on chip. Note that if was calledesp_ota_mark_app_invalid_rollback_and_reboot()
function a rollback may not happend due to the device may not have any bootable apps then it will returnESP_ERR_OTA_ROLLBACK_FAILED
error and stay in theESP_OTA_IMG_PENDING_VERIFY
state.
——如果無其它可用APP,esp_ota_mark_app_invalid_rollback_and_reboot存在回滾失敗的可能铣缠,ESP_OTA_IMG_PENDING_VERIFY保持不變烘嘱。 - The next update of app is possible if a running app is in the
ESP_OTA_IMG_VALID
state.
Recommendation:
If you want to avoid the download/erase overhead in case of the app from the server has security version lower then running app you have to get new_app_info.secure_version from the first package of an image and compare it with the secure version of efuse. Use esp_efuse_check_secure_version(new_app_info.secure_version) function if it is true then continue downloading otherwise abort.
——esp_efuse_check_secure_version可以直接在更新前檢查版本,以避免下載后再刪除蝗蛙。
bool image_header_was_checked = false;
while (1) {
int data_read = esp_http_client_read(client, ota_write_data, BUFFSIZE);
...
if (data_read > 0) {
if (image_header_was_checked == false) {
esp_app_desc_t new_app_info;
if (data_read > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t)) {
// check current version with downloading
if (esp_efuse_check_secure_version(new_app_info.secure_version) == false) {
ESP_LOGE(TAG, "This a new app can not be downloaded due to a secure version is lower than stored in efuse.");
http_cleanup(client);
task_fatal_error();
}
image_header_was_checked = true;
esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
}
}
esp_ota_write( update_handle, (const void *)ota_write_data, data_read);
}
}
Restrictions:
- The number of bits in the
secure_version
field is limited to 32 bits. This means that only 32 times you can do an anti-rollback. You can reduce the length of this efuse field use CONFIG_BOOTLOADER_APP_SEC_VER_SIZE_EFUSE_FIELD option.
——最大可回滾次數(shù)蝇庭,esp32是32次,esp32S2是16次 - Anti-rollback only works if the encoding scheme for efuse is set to
NONE
. - The partition table should not have a factory partition, only two of the app.
——不能沒有出廠APP捡硅。
security_version
:
- In application image it is stored in
esp_app_desc
structure. The number is set CONFIG_BOOTLOADER_APP_SECURE_VERSION. - In ESP32 it is stored in efuse
EFUSE_BLK3_RDATA4_REG
. (when a eFuse bit is programmed to 1, it can never be reverted to 0). The number of bits set in this register is thesecurity_version
from app.
See also
-
Partition Table documentation
——分區(qū)表介紹 -
Lower-Level SPI Flash/Partition API
——Flash操作接口 -
ESP HTTPS OTA
——HTTPS升級接口
————
以上已介紹完整個OTA流程
API Reference
Header File
返回當(dāng)前運(yùn)行APP的詳情esp_app_desc結(jié)構(gòu)體哮内,包含APP版本號
- Return
Pointer to esp_app_desc structure.
填充SHA256格式ELF文件數(shù)據(jù)至dst中,十六進(jìn)制壮韭,以0x00結(jié)尾北发,如果空間不足,將盡肯能充滿喷屋,最后補(bǔ)0x00琳拨。
Return
Number of bytes written to dst (including null terminator)Parameters
dst: Destination buffer
size: Size of the buffer
開始向指定分區(qū)寫入OTA更新。
指定的分區(qū)將被擦除到指定的圖像大小屯曹。
如果圖像大小未知从绘,請傳遞OTA_size_UNKNOWN寄疏,這將導(dǎo)致整個分區(qū)被擦除。
如果成功僵井,該函數(shù)將分配在使用返回的句柄調(diào)用esp_ota_end()之前一直使用的內(nèi)存。
注意:如果啟用了回滾選項驳棱,并且正在運(yùn)行的應(yīng)用程序具有ESP_OTA_IMG_PENDING_VERIFY狀態(tài)批什,則將導(dǎo)致ESP_ERR_OTA_rollback_INVALID_state錯誤。在運(yùn)行下載新應(yīng)用程序之前社搅,請確認(rèn)正在運(yùn)行的應(yīng)用程序驻债,對其使用esp_ota_mark_app_valid_cancel_rollback()函數(shù)(應(yīng)在首次下載新應(yīng)用程序時盡早完成)。
Return
ESP_OK: OTA operation commenced successfully.
ESP_ERR_INVALID_ARG: partition or out_handle arguments were NULL, or partition doesn’t point to an OTA app partition.
ESP_ERR_NO_MEM: Cannot allocate memory for OTA operation.
ESP_ERR_OTA_PARTITION_CONFLICT: Partition holds the currently running firmware, cannot update in place.
ESP_ERR_NOT_FOUND: Partition argument not found in partition table.
ESP_ERR_OTA_SELECT_INFO_INVALID: The OTA data partition contains invalid data.
ESP_ERR_INVALID_SIZE: Partition doesn’t fit in configured flash size.
ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
ESP_ERR_OTA_ROLLBACK_INVALID_STATE: If the running app has not confirmed state. Before performing an update, the application must be valid.Parameters
partition: Pointer to info for partition which will receive the OTA update. Required.
image_size: Size of new OTA app image. Partition will be erased in order to receive this size of image. If 0 or OTA_SIZE_UNKNOWN, the entire partition is erased.
out_handle: On success, returns a handle which should be used for subsequent esp_ota_write() and esp_ota_end() calls.
——將ota寫入指定分區(qū)形葬。重點(diǎn):可多次寫入合呐,比如藍(lán)牙接收時可以直接調(diào)用。
——完成OTA并驗證
——將啟動分區(qū)配置到OTAdata
——獲取OTAdata配置的當(dāng)前啟動分區(qū)笙以。一般是esp_ota_set_boot_partition配置的分區(qū)淌实,與esp_ota_get_running_partition相同。如果出現(xiàn)不同猖腕,可能是回退導(dǎo)致拆祈。
如果數(shù)據(jù)無效,則按照 出廠APP ota_0 或測試分區(qū)倘感。
注意返回:分區(qū)并不一定都是有效分區(qū)放坏。
——獲取正在運(yùn)行的分區(qū)信息
——獲取下一個寫入分區(qū)
——這里和上面的接口對比:
esp_err_t esp_ota_get_partition_description (const esp_partition_t *partition, esp_app_desc_t *app_desc) |
任何APP |
---|---|
const esp_app_desc_t *esp_ota_get_app_description (void) |
當(dāng)前APP |
——mark valid 并取消自動回滾檬姥。
——失敗重啟
——查找最后一次無效分區(qū)
——查找分區(qū)狀態(tài)
——格式化分區(qū)并重新初始化otadata甚淡。以便重新使用此分區(qū)。
——防止有效分區(qū)被回滾進(jìn)行檢查