ESP32基于IDF框架OTA学习记录
ESP32基于IDF框架OTA学习记录
参考:
- 空中升级 (OTA) - ESP32 - — ESP-IDF 编程指南 v5.1.1 文档 (espressif.com)
目录
- ESP32基于IDF框架OTA学习记录
- 1.分区表
- 2.native_ota_example上手
- 2.1配置分区表
- 2.2配置OTA的bin文件
- 2.3修改esp32的https证书验证方法
- 2.4修改当前固件版本
- 2.5配置WiFi连接参数
- 2.6编译、下载
- 3.native_ota_example代码解读
1.分区表
分区表将esp32的flash作了划分,不同类型的区域作不同功能使用。我们进行OTA时,需要将程序写入flash,需要先配置部分flash区域,标识为OTA使用。
官方的分区表介绍很详细:分区表 - ESP32 - — ESP-IDF 编程指南 v5.1.2 文档 (espressif.com)
2.native_ota_example上手
这个示例是官方的例程,路径:esp-idf-v5.1.2\examples\system\ota\native_ota_example
2.1配置分区表
官方例程貌似已经配置了,没配置的话需要配置2个OTA分区。
配置方法:
idf.py menuconfig
打开配置界面,对Partition Table项进行配置:
(Top) → Partition Table → Partition Table Espressif IoT Development Framework Configuration ( ) Single factory app, no OTA
( ) Single factory app (large), no OTA
(X) Factory app, two OTA definitions
( ) Custom partition table CSV
2.2配置OTA的bin文件
这里使用get-started里面的blink点灯例程,编译出一个blink.bin文件。
服务器使用gitee,建了一个测试仓库,上传blink.bin,下载链接:https://gitee.com/nameisboy/esp32-https-ota/raw/master/blink.bin
idf.py menuconfig
配置固件升级的URL,使用上面的链接:
(Top) → Example Configuration Espressif IoT Development Framework Configuration (https://gitee.com/nameisboy/esp32-https-ota/raw/master/blink.bin) Firmware Upgrade URL
[ ] Skip server certificate CN fieldcheck
[ ] Skip firmware version check
(4) Number of the GPIO input for diagnostic
(5000) OTA Receive Timeout
2.3修改esp32的https证书验证方法
例程使用的是服务器的自签名证书做SSL/TLS验证,gitee服务器的证书不知道怎么搞,这里直接修改使用esp32自带的 ESP x509 Certificate Bundle
进行验证,该功能覆盖了大多数受信任的根证书。
具体修改方法:
找到代码中配置https的结构体,修改初始化参数:
给 crt_bundle_attach
成员赋值 esp_crt_bundle_attach
,关闭 cert_pem
的初始化。
esp_http_client_config_t config = {.url = CONFIG_EXAMPLE_FIRMWARE_UPG_URL,
// .cert_pem = (char *)server_cert_pem_start,.crt_bundle_attach = esp_crt_bundle_attach,.timeout_ms = CONFIG_EXAMPLE_OTA_RECV_TIMEOUT,.keep_alive_enable = true,};
需要包含头文件:
#include "esp_crt_bundle.h"/*使用ESP x509 Certificate Bundle*/
2.4修改当前固件版本
因为OTA代码中做了版本判断,如果版本相同,不会进行OTA。而blink例程编译出来的固件版本默认是1,OTA例程的版本也默认为1,这里直接修改OTA例程的版本,使其不一致即可。
修改方法:
修改工程目录下的version.txt文件中数字,这里直接修改为2。
2.5配置WiFi连接参数
idf.py menuconfig
配置WiFi连接的SSID密码。
2.6编译、下载
确保WiFi可以连接、上网,观察串口输出即可看到OTA升级的过程,成功后ESP32会重启运行新的blink代码。
PS D:\Coding\Embedded\MCU\ESP32\esp-idf\native_ota_example> idf.py -p COM3 flash monitor
Executing action: flash
Running ninja in directory D:\Coding\Embedded\MCU\ESP32\esp-idf\native_ota_example\build
Executing "ninja flash"...
[1/5] cmd.exe /C "cd /D D:\Coding\Embedded\MCU\ESP32\esp-idf\native_ota_example\build\esp-idf\esptool_py && D:\Coding\Embedded\MCU\espressif\Tools\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe D:/Coding/Embedded/MCU/espressif/esp-idf-v5.1.2/components/partition_table/check_sizes.py --offset 0x8000 partition --type app D:/Coding/Embedded/MCU/ESP32/esp-idf/native_ota_example/build/partition_table/partition-table.bin D:/Coding/Embedded/MCU/ESP32/esp-idf/native_ota_example/build/native_ota.bin"
native_ota.bin binary size 0xeda90 bytes. Smallest app partition is 0x100000 bytes. 0x12570 bytes (7%) free.
[2/5] Performing build step for 'bootloader'
[1/1] cmd.exe /C "cd /D D:\Coding\Embedded\MCU\ESP32\esp-idf\native_ota_example\build\bootloader\esp-idf\esptool_py && D:\Coding\Embedded\MCU\espressif\Tools\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe D:/Coding/Embedded/MCU/espressif/esp-idf-v5.1.2/components/partition_table/check_sizes.py --offset 0x8000 bootloader 0x1000 D:/Coding/Embedded/MCU/ESP32/esp-idf/native_ota_example/build/bootloader/bootloader.bin"
Bootloader binary size 0x6810 bytes. 0x7f0 bytes (7%) free.
[2/3] cmd.exe /C "cd /D D:\Coding\Embedded\MCU\espressif\esp-idf-v5.1.2\components\esptool_py && D:\Coding\Embedded\MCU\espressif\Tools\Espressif\tools\cmake\3.24.0\bin\cmake.exe -D IDF_PATH=D:/Coding/Embedded/MCU/espressif/esp-idf-v5.1.2 -D SERIAL_TOOL=D:/Coding/Embedded/MCU/espressif/Tools/Espressif/python_env/idf5.1_py3.11_env/Scripts/python.exe;;D:/Coding/Embedded/MCU/espressif/esp-idf-v5.1.2/components/esptool_py/esptool/esptool.py;--chip;esp32 -D SERIAL_TOOL_ARGS=--before=default_reset;--after=hard_reset;write_flash;@flash_args -D WORKING_DIRECTORY=D:/Coding/Embedded/MCU/ESP32/esp-idf/native_ota_example/build -P D:/Coding/Embedded/MCU/espressif/esp-idf-v5.1.2/components/esptool_py/run_serial_tool.cmake"
esptool.py --chip esp32 -p COM3 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 bootloader/bootloader.bin 0x10000 native_ota.bin 0x8000 partition_table/partition-table.bin 0xd000 ota_data_initial.bin
esptool.py v4.7.dev3
Serial port COM3
Connecting.....
Chip is ESP32-D0WD (revision v1.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: e8:68:e7:23:58:1c
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00001000 to 0x00007fff...
Flash will be erased from 0x00010000 to 0x000fdfff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000d000 to 0x0000efff...
Compressed 26640 bytes to 16691...
Writing at 0x00001000... (50 %)
Writing at 0x0000768d... (100 %)
Wrote 26640 bytes (16691 compressed) at 0x00001000 in 0.9 seconds (effective 239.8 kbit/s)...
Hash of data verified.
Compressed 973456 bytes to 634536...
Writing at 0x00010000... (2 %)
Writing at 0x00018908... (5 %)
Writing at 0x0001d5d4... (7 %)
Writing at 0x000229e0... (10 %)
Writing at 0x0002a261... (12 %)
Writing at 0x00031225... (15 %)
Writing at 0x000365a4... (17 %)
Writing at 0x00041e08... (20 %)
Writing at 0x0004c12a... (23 %)
Writing at 0x00051d7c... (25 %)
Writing at 0x0005759a... (28 %)
Writing at 0x0005d066... (30 %)
Writing at 0x00062b1d... (33 %)
Writing at 0x000683eb... (35 %)
Writing at 0x0006df8d... (38 %)
Writing at 0x00074378... (41 %)
Writing at 0x00079e9f... (43 %)
Writing at 0x0007f70f... (46 %)
Writing at 0x00084a40... (48 %)
Writing at 0x00089e2c... (51 %)
Writing at 0x0008f394... (53 %)
Writing at 0x00094682... (56 %)
Writing at 0x00099cf4... (58 %)
Writing at 0x0009f597... (61 %)
Writing at 0x000a5474... (64 %)
Writing at 0x000aab92... (66 %)
Writing at 0x000b0275... (69 %)
Writing at 0x000b5946... (71 %)
Writing at 0x000bb341... (74 %)
Writing at 0x000c09fd... (76 %)
Writing at 0x000c6385... (79 %)
Writing at 0x000cc699... (82 %)
Writing at 0x000d21d5... (84 %)
Writing at 0x000d7980... (87 %)
Writing at 0x000e0612... (89 %)
Writing at 0x000e8d55... (92 %)
Writing at 0x000ee9dd... (94 %)
Writing at 0x000f4378... (97 %)
Writing at 0x000f9a04... (100 %)
Wrote 973456 bytes (634536 compressed) at 0x00010000 in 15.3 seconds (effective 510.4 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 138...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (138 compressed) at 0x00008000 in 0.1 seconds (effective 274.2 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 31...
Writing at 0x0000d000... (100 %)
Wrote 8192 bytes (31 compressed) at 0x0000d000 in 0.2 seconds (effective 395.2 kbit/s)...
Hash of data verified.Leaving...
Hard resetting via RTS pin...
Executing action: monitor
Running idf_monitor in directory D:\Coding\Embedded\MCU\ESP32\esp-idf\native_ota_example
Executing "D:\Coding\Embedded\MCU\espressif\Tools\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe D:\Coding\Embedded\MCU\espressif\esp-idf-v5.1.2\tools/idf_monitor.py -p COM3 -b 115200 --toolchain-prefix xtensa-esp32-elf- --target esp32 --revision 0 D:\Coding\Embedded\MCU\ESP32\esp-idf\native_ota_example\build\native_ota.elf --force-color -m 'D:\Coding\Embedded\MCU\espressif\Tools\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe' 'D:\Coding\Embedded\MCU\espressif\esp-idf-v5.1.2\tools\idf.py' '-p' 'COM3'"...
--- WARNING: GDB cannot open serial ports accessed as COMx
--- Using \\.\COM3 instead...
--- esp-idf-monitor 1.3.3 on \\.\COM3 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
I (531) cpu_start: Pro cpu ����ets Jun 8 2016 00:22:57rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7084
ho 0 tail 12 room 4
load:0x40078000,len:15584
load:0x40080400,len:4
0x40080400: _init at ??:?load:0x40080404,len:3876
entry 0x4008064c
I (31) boot: ESP-IDF v5.1.2-dirty 2nd stage bootloader
I (31) boot: compile time Nov 26 2023 22:37:12
I (31) boot: Multicore bootloader
I (36) boot: chip revision: v1.0
I (40) boot.esp32: SPI Speed : 40MHz
I (44) boot.esp32: SPI Mode : DIO
I (49) boot.esp32: SPI Flash Size : 4MB
I (53) boot: Enabling RNG early entropy source...
I (59) boot: Partition Table:
I (62) boot: ## Label Usage Type ST Offset Length
I (70) boot: 0 nvs WiFi data 01 02 00009000 00004000
I (77) boot: 1 otadata OTA data 01 00 0000d000 00002000
I (84) boot: 2 phy_init RF data 01 01 0000f000 00001000
I (92) boot: 3 factory factory app 00 00 00010000 00100000
I (99) boot: 4 ota_0 OTA app 00 10 00110000 00100000
I (107) boot: 5 ota_1 OTA app 00 11 00210000 00100000
I (114) boot: End of partition table
I (119) boot: Defaulting to factory image
I (123) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=36160h (221536) map
I (212) esp_image: segment 1: paddr=00046188 vaddr=3ffb0000 size=03b44h ( 15172) load
I (218) esp_image: segment 2: paddr=00049cd4 vaddr=40080000 size=06344h ( 25412) load
I (229) esp_image: segment 3: paddr=00050020 vaddr=400d0020 size=9e144h (647492) map
I (463) esp_image: segment 4: paddr=000ee16c vaddr=40086344 size=0f8f8h ( 63736) load
I (501) boot: Loaded app from partition at offset 0x10000
I (501) boot: Disabling RNG early entropy source...
I (512) cpu_start: Multicore app
I (513) cpu_start: Pro cpu up.
I (513) cpu_start: Starting app cpu, entry point is 0x40081390
0x40081390: call_start_cpu1 at D:/Coding/Embedded/MCU/espressif/esp-idf-v5.1.2/components/esp_system/port/cpu_start.c:157I (0) cpu_start: App cpu up.
I (531) cpu_start: Pro cpu start user code
I (531) cpu_start: cpu freq: 160000000 Hz
I (531) cpu_start: Application information:
I (535) cpu_start: Project name: native_ota
I (541) cpu_start: App version: 2
I (545) cpu_start: Compile time: Nov 26 2023 22:36:55
I (551) cpu_start: ELF file SHA256: 7166a216a7cfb5c9...
I (557) cpu_start: ESP-IDF: v5.1.2-dirty
I (562) cpu_start: Min chip rev: v0.0
I (567) cpu_start: Max chip rev: v3.99
I (572) cpu_start: Chip rev: v1.0
I (577) heap_init: Initializing. RAM available for dynamic allocation:
I (584) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (590) heap_init: At 3FFB8780 len 00027880 (158 KiB): DRAM
I (596) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (603) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (609) heap_init: At 40095C3C len 0000A3C4 (40 KiB): IRAM
I (617) spi_flash: detected chip: generic
I (620) spi_flash: flash io: dio
I (625) app_start: Starting scheduler on CPU0
I (629) app_start: Starting scheduler on CPU1
I (629) main_task: Started on CPU0
I (639) main_task: Calling app_main()
I (639) native_ota_example: OTA example app_main start
I (649) native_ota_example: SHA-256 for the partition table: : d1c0e9d02fa9d26cd2e1984e7b5dd20157204f501ddc83ce82229e5f3175ee8b
I (669) native_ota_example: SHA-256 for bootloader: : 8c6551e255cf261e7f61ca415b440a25e380d9bfcec7f4bbd67ed4ae526dfb7d
I (909) native_ota_example: SHA-256 for current firmware: : f568ba42cbef29927eb44e5239d5cc01e6aacceb4431ea57a086f116c834617c
I (929) example_connect: Start example_connect.
I (949) wifi:wifi driver task: 3ffc0440, prio:23, stack:6656, core=0
I (959) wifi:wifi firmware version: 91b9630
I (959) wifi:wifi certification version: v7.0
I (959) wifi:config NVS flash: enabled
I (959) wifi:config nano formating: disabled
I (959) wifi:Init data frame dynamic rx buffer num: 32
I (969) wifi:Init static rx mgmt buffer num: 5
I (969) wifi:Init management short buffer num: 32
I (979) wifi:Init dynamic tx buffer num: 32
I (979) wifi:Init static rx buffer size: 1600
I (979) wifi:Init static rx buffer num: 10
I (989) wifi:Init dynamic rx buffer num: 32
I (989) wifi_init: rx ba win: 6
I (999) wifi_init: tcpip mbox: 32
I (999) wifi_init: udp mbox: 6
I (999) wifi_init: tcp mbox: 6
I (1009) wifi_init: tcp tx win: 5744
I (1009) wifi_init: tcp rx win: 5744
I (1019) wifi_init: tcp mss: 1440
I (1019) wifi_init: WiFi IRAM OP enabled
I (1019) wifi_init: WiFi RX IRAM OP enabled
I (1029) phy_init: phy_version 4780,16b31a7,Sep 22 2023,20:42:16
I (1109) wifi:mode : sta (e8:68:e7:23:58:1c)
I (1109) wifi:enable tsf
I (1109) example_connect: Connecting to ap...
I (1119) example_connect: Waiting for IP(s)
I (3529) example_connect: Wi-Fi disconnected, trying to reconnect...
I (5939) wifi:new:<11,0>, old:<1,0>, ap:<255,255>, sta:<11,0>, prof:1
I (6189) wifi:state: init -> auth (b0)
I (6219) wifi:state: auth -> assoc (0)
I (6229) wifi:state: assoc -> run (10)
I (6239) wifi:connected with ap, aid = 13, channel 11, BW20, bssid = ce:5e:f8:f0:ec:a7
I (6239) wifi:security: WPA2-PSK, phy: bgn, rssi: -15
I (6239) wifi:pm start, type: 1I (6479) wifi:AP's beacon interval = 102400 us, DTIM period = 1
I (6899) wifi:<ba-add>idx:0 (ifx:0, ce:5e:f8:f0:ec:a7), tid:0, ssn:4, winSize:64
I (7749) esp_netif_handlers: example_netif_sta ip: 192.168.137.31, mask: 255.255.255.0, gw: 192.168.137.1
I (7749) example_connect: Got IPv4 event: Interface "example_netif_sta" address: 192.168.137.31
I (7929) example_connect: Got IPv6 event: Interface "example_netif_sta" address: fe80:0000:0000:0000:ea68:e7ff:fe23:581c, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (7929) example_common: Connected to example_netif_sta
I (7939) example_common: - IPv4 address: 192.168.137.31,
I (7939) example_common: - IPv6 address: fe80:0000:0000:0000:ea68:e7ff:fe23:581c, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (7959) wifi:Set ps type: 0, coexist: 0I (7959) native_ota_example: Starting OTA example task
I (7969) native_ota_example: Running partition type 0 subtype 0 (offset 0x00010000)
I (7979) main_task: Returned from app_main()
I (9739) esp-x509-crt-bundle: Certificate validated
I (11819) native_ota_example: Writing to partition subtype 16 at offset 0x110000
I (11819) native_ota_example: New firmware version: 1
I (11819) native_ota_example: Running firmware version: 2
I (11829) native_ota_example: esp_ota_begin succeeded
I (27089) native_ota_example: Connection closed
I (27089) native_ota_example: Total Write binary data length: 182368
I (27089) esp_image: segment 0: paddr=00110020 vaddr=3f400020 size=09be8h ( 39912) map
I (27119) esp_image: segment 1: paddr=00119c10 vaddr=3ffb0000 size=02158h ( 8536)
I (27119) esp_image: segment 2: paddr=0011bd70 vaddr=40080000 size=042a8h ( 17064)
I (27129) esp_image: segment 3: paddr=00120020 vaddr=400d0020 size=14abch ( 84668) map
I (27159) esp_image: segment 4: paddr=00134ae4 vaddr=400842a8 size=07d54h ( 32084)
I (27169) esp_image: segment 0: paddr=00110020 vaddr=3f400020 size=09be8h ( 39912) map
I (27179) esp_image: segment 1: paddr=00119c10 vaddr=3ffb0000 size=02158h ( 8536)
I (27189) esp_image: segment 2: paddr=0011bd70 vaddr=40080000 size=042a8h ( 17064)
I (27199) esp_image: segment 3: paddr=00120020 vaddr=400d0020 size=14abch ( 84668) map
I (27229) esp_image: segment 4: paddr=00134ae4 vaddr=400842a8 size=07d54h ( 32084)
I (27319) native_ota_example: Prepare to restart system!
I (27319) wifi:state: run -> init (0)
I (27319) wifi:pm stop, total sleep time: 322820 us / 21073032 usI (27319) wifi:<ba-del>idx:0, tid:0
I (27319) wifi:new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
E (27329) wifi:NAN WiFi stop
I (27339) wifi:flush txq
I (27339) wifi:stop sw txq
I (27339) wifi:lmac stop hw txq
I (27339) wifi:Deinit lldesc rx mblock:10
ets Jun 8 2016 00:22:57rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7084
ho 0 tail 12 room 4
load:0x40078000,len:15584
load:0x40080400,len:4
0x40080400: _init at ??:?load:0x40080404,len:3876
entry 0x4008064c
I (31) boot: ESP-IDF v5.1.2-dirty 2nd stage bootloader
I (31) boot: compile time Nov 26 2023 22:37:12
I (31) boot: Multicore bootloader
I (36) boot: chip revision: v1.0
I (40) boot.esp32: SPI Speed : 40MHz
I (44) boot.esp32: SPI Mode : DIO
I (49) boot.esp32: SPI Flash Size : 4MB
I (53) boot: Enabling RNG early entropy source...
I (59) boot: Partition Table:
I (62) boot: ## Label Usage Type ST Offset Length
I (70) boot: 0 nvs WiFi data 01 02 00009000 00004000
I (77) boot: 1 otadata OTA data 01 00 0000d000 00002000
I (84) boot: 2 phy_init RF data 01 01 0000f000 00001000
I (92) boot: 3 factory factory app 00 00 00010000 00100000
I (99) boot: 4 ota_0 OTA app 00 10 00110000 00100000
I (107) boot: 5 ota_1 OTA app 00 11 00210000 00100000
I (114) boot: End of partition table
I (119) esp_image: segment 0: paddr=00110020 vaddr=3f400020 size=09be8h ( 39912) map
I (142) esp_image: segment 1: paddr=00119c10 vaddr=3ffb0000 size=02158h ( 8536) load
I (145) esp_image: segment 2: paddr=0011bd70 vaddr=40080000 size=042a8h ( 17064) load
I (155) esp_image: segment 3: paddr=00120020 vaddr=400d0020 size=14abch ( 84668) map
I (187) esp_image: segment 4: paddr=00134ae4 vaddr=400842a8 size=07d54h ( 32084) load
I (206) boot: Loaded app from partition at offset 0x110000
I (206) boot: Disabling RNG early entropy source...
I (218) cpu_start: Multicore app
I (218) cpu_start: Pro cpu up.
I (218) cpu_start: Starting app cpu, entry point is 0x400810f0
I (206) cpu_start: App cpu up.
I (236) cpu_start: Pro cpu start user code
I (236) cpu_start: cpu freq: 160000000 Hz
I (236) cpu_start: Application information:
I (241) cpu_start: Project name: blink
I (246) cpu_start: App version: 1
I (250) cpu_start: Compile time: Nov 26 2023 10:10:34
I (256) cpu_start: ELF file SHA256: 44615b9489a1ce4c...
Warning: checksum mismatch between flashed and built applications. Checksum of built application is 7166a216a7cfb5c9e6af6148f9cd73bc2b16493a53a63bbe900ce54c1cc5afce
I (262) cpu_start: ESP-IDF: v5.1.2-dirty
I (268) cpu_start: Min chip rev: v0.0
I (272) cpu_start: Max chip rev: v3.99
I (277) cpu_start: Chip rev: v1.0
I (282) heap_init: Initializing. RAM available for dynamic allocation:
I (289) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (295) heap_init: At 3FFB29D0 len 0002D630 (181 KiB): DRAM
I (302) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (308) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (314) heap_init: At 4008C000 len 00014000 (80 KiB): IRAM
I (322) spi_flash: detected chip: generic
I (325) spi_flash: flash io: dio
I (330) app_start: Starting scheduler on CPU0
I (334) app_start: Starting scheduler on CPU1
I (334) main_task: Started on CPU0
I (344) main_task: Calling app_main()
I (344) example: Example configured to blink GPIO LED!
I (344) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (354) example: Turning the LED OFF!
I (864) example: Turning the LED ON!
I (1364) example: Turning the LED OFF!
I (1864) example: Turning the LED ON!
I (2364) example: Turning the LED OFF!
I (2864) example: Turning the LED ON!
I (3364) example: Turning the LED OFF!
I (3864) example: Turning the LED ON!
I (4364) example: Turning the LED OFF!
I (4864) example: Turning the LED ON!
I (5364) example: Turning the LED OFF!
I (5864) example: Turning the LED ON!
I (6364) example: Turning the LED OFF!
I (6864) example: Turning the LED ON!
I (7364) example: Turning the LED OFF!
I (7864) example: Turning the LED ON!
I (8364) example: Turning the LED OFF!
I (8864) example: Turning the LED ON!
I (9364) example: Turning the LED OFF!
I (9864) example: Turning the LED ON!
I (10364) example: Turning the LED OFF!
I (10864) example: Turning the LED ON!
I (11364) example: Turning the LED OFF!
I (11864) example: Turning the LED ON!
I (12364) example: Turning the LED OFF!
I (12864) example: Turning the LED ON!
I (13364) example: Turning the LED OFF!
I (13864) example: Turning the LED ON!
3.native_ota_example代码解读
主要逻辑在 ota_example_task
任务中。基本逻辑其实就是使用ESP_HTTP_CLIENT相关接口,从https服务器上下载需要OTA的bin文件,将下载数据写入到相应的flash中。
static void ota_example_task(void *pvParameter)
{esp_err_t err;/* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */esp_ota_handle_t update_handle = 0 ;const esp_partition_t *update_partition = NULL;ESP_LOGI(TAG, "Starting OTA example task");const esp_partition_t *configured = esp_ota_get_boot_partition();const esp_partition_t *running = esp_ota_get_running_partition();if (configured != running) {ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08"PRIx32", but running from offset 0x%08"PRIx32,configured->address, running->address);ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)");}ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08"PRIx32")",running->type, running->subtype, running->address);esp_http_client_config_t config = {.url = CONFIG_EXAMPLE_FIRMWARE_UPG_URL,
// .cert_pem = (char *)server_cert_pem_start,.crt_bundle_attach = esp_crt_bundle_attach,.timeout_ms = CONFIG_EXAMPLE_OTA_RECV_TIMEOUT,.keep_alive_enable = true,};#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDINchar url_buf[OTA_URL_SIZE];if (strcmp(config.url, "FROM_STDIN") == 0) {example_configure_stdin_stdout();fgets(url_buf, OTA_URL_SIZE, stdin);int len = strlen(url_buf);url_buf[len - 1] = '\0';config.url = url_buf;} else {ESP_LOGE(TAG, "Configuration mismatch: wrong firmware upgrade image url");abort();}
#endif#ifdef CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECKconfig.skip_cert_common_name_check = true;
#endifesp_http_client_handle_t client = esp_http_client_init(&config);if (client == NULL) {ESP_LOGE(TAG, "Failed to initialise HTTP connection");task_fatal_error();}err = esp_http_client_open(client, 0);if (err != ESP_OK) {ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));esp_http_client_cleanup(client);task_fatal_error();}esp_http_client_fetch_headers(client);update_partition = esp_ota_get_next_update_partition(NULL);assert(update_partition != NULL);ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%"PRIx32,update_partition->subtype, update_partition->address);int binary_file_length = 0;/*deal with all receive packet*/bool image_header_was_checked = false;while (1) {int data_read = esp_http_client_read(client, ota_write_data, BUFFSIZE);if (data_read < 0) {ESP_LOGE(TAG, "Error: SSL data read error");http_cleanup(client);task_fatal_error();} else 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 downloadingmemcpy(&new_app_info, &ota_write_data[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t));ESP_LOGI(TAG, "New firmware version: %s", new_app_info.version);esp_app_desc_t running_app_info;if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) {ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version);}const esp_partition_t* last_invalid_app = esp_ota_get_last_invalid_partition();esp_app_desc_t invalid_app_info;if (esp_ota_get_partition_description(last_invalid_app, &invalid_app_info) == ESP_OK) {ESP_LOGI(TAG, "Last invalid firmware version: %s", invalid_app_info.version);}// check current version with last invalid partitionif (last_invalid_app != NULL) {if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 0) {ESP_LOGW(TAG, "New version is the same as invalid version.");ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.", invalid_app_info.version);ESP_LOGW(TAG, "The firmware has been rolled back to the previous version.");http_cleanup(client);infinite_loop();}}
#ifndef CONFIG_EXAMPLE_SKIP_VERSION_CHECKif (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) {ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update.");http_cleanup(client);infinite_loop();}
#endifimage_header_was_checked = true;err = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &update_handle);if (err != ESP_OK) {ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));http_cleanup(client);esp_ota_abort(update_handle);task_fatal_error();}ESP_LOGI(TAG, "esp_ota_begin succeeded");} else {ESP_LOGE(TAG, "received package is not fit len");http_cleanup(client);esp_ota_abort(update_handle);task_fatal_error();}}err = esp_ota_write( update_handle, (const void *)ota_write_data, data_read);if (err != ESP_OK) {http_cleanup(client);esp_ota_abort(update_handle);task_fatal_error();}binary_file_length += data_read;ESP_LOGD(TAG, "Written image length %d", binary_file_length);} else if (data_read == 0) {/** As esp_http_client_read never returns negative error code, we rely on* `errno` to check for underlying transport connectivity closure if any*/if (errno == ECONNRESET || errno == ENOTCONN) {ESP_LOGE(TAG, "Connection closed, errno = %d", errno);break;}if (esp_http_client_is_complete_data_received(client) == true) {ESP_LOGI(TAG, "Connection closed");break;}}}ESP_LOGI(TAG, "Total Write binary data length: %d", binary_file_length);if (esp_http_client_is_complete_data_received(client) != true) {ESP_LOGE(TAG, "Error in receiving complete file");http_cleanup(client);esp_ota_abort(update_handle);task_fatal_error();}err = esp_ota_end(update_handle);if (err != ESP_OK) {if (err == ESP_ERR_OTA_VALIDATE_FAILED) {ESP_LOGE(TAG, "Image validation failed, image is corrupted");} else {ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err));}http_cleanup(client);task_fatal_error();}err = esp_ota_set_boot_partition(update_partition);if (err != ESP_OK) {ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));http_cleanup(client);task_fatal_error();}ESP_LOGI(TAG, "Prepare to restart system!");esp_restart();return ;
}
通过 调用esp_ota_begin
OTA写入分区操作,使用 esp_ota_write
写入数据到分区,调用 esp_ota_end
写入完成。
接着调用 esp_ota_set_boot_partition
设置启动分区为刚刚写入的分区,最后通过 esp_restart
重启即可运行刚刚的分区。
相关文章:
ESP32基于IDF框架OTA学习记录
ESP32基于IDF框架OTA学习记录 参考: 空中升级 (OTA) - ESP32 - — ESP-IDF 编程指南 v5.1.1 文档 (espressif.com) 目录 ESP32基于IDF框架OTA学习记录1.分区表2.native_ota_example上手2.1配置分区表2.2配置OTA的bin文件2.3修改esp32的https证书验证方法2.4修改当…...

分布式技术(一)分布式的架构的演进
💌 所属专栏:【微服务】😀 作 者:长安不及十里💻 工作:目前从事电力行业开发🌈 目标:全栈开发🚀 个人简介:一个正在努力学技术的Java工程师,专注基…...

webpack 打包优化
在vue.config.js中配置 下载 uglifyjs-webpack-plugin 包 const { defineConfig } require("vue/cli-service"); var path require("path");module.exports defineConfig({transpileDependencies: true,filenameHashing: false, // 去除Vue打包后.cs…...

electron windows robotjs 安装教程
Robotjs 安装 前言第一步 : 安装python第二步 : 安装Visual Studio 2022第三步 : 安装robotjs 前言 robotjs可以控制鼠标键盘,获取屏幕内容,配合electron可做很多自动化操作。windows下配置环境有很多坑,很多文章都太旧了。试了很多次发现了…...

IDEA解决Git冲突详解
目录 前言: 何为冲突 冲突演示 IDEA冲突解决 小结: 前言: 相信大家多多少少都有了解和使用过Git,作为Java程序员idea可谓是无敌的存在了,那么如何使用idea解决Git冲突呢?不瞒大家前段时间在公司把同事…...

Vue3使用kkFileView预览文件pdf
kkFileView - 在线文件预览kkFileView官网 - kkFileView使用Spring Boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,Excel,pdf,txt,zip,rar,图片等等https://kkfileview.keking.cn/zh-cn/docs/usage.html业务场景…...

建造者模式-C语言实现
UML类图: 代码实现: #include <stdio.h> #include <stdlib.h>// 产品类 typedef struct {char* part1;char* part2;char* part3; } Product;// 抽象建造者类 typedef struct {void (*buildPart1)(void*, const char*);void (*buildPart2)(v…...

Jmeter+influxdb+grafana监控平台在windows环境的搭建
原理:Jmeter采集的数据存储在infuxdb数据库中,grafana将数据库中的数据在界面上进行展示 一、grafana下载安装 Download Grafana | Grafana Labs 直接选择zip包下载,下载后解压即可,我之前下载过比较老的版本,这里就…...

关注这两点 或能避开一些现货黄金交易的陷阱
在现货黄金投资中,交易机会是处处都有,但是亏损的情况也可能出现。投资者要在陷阱处处的市场中获得稳定盈利,就需要懂得如何规避现货黄金投资的陷阱。下面我们就来介绍两个很常用的避开陷阱的方法。 看交易的活跃度。交易越活跃,市…...

Python 文件读写
Python 文件读写笔记整理 参数说明 open(path, flag[, encoding][,errors]) path:要打开文件的路径 flag:打开方式 encoding:编码方式 errors:错误处理 Flag打开方式表 模式 描述 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 rb 以二进制格…...

线性分组码的奇偶校验矩阵均匀性分析
回顾信道编解码知识,我们知道信道编码要求编码具有检纠错能力,作为FEC(forward error correction)前向纠错编码的一类,线性分组码表示校验位与信息位的关系能够线性表示。 在这篇文章中,并不是要讨论信道编…...

leetcode算法之链表
目录 1.两数相加2.两两交换链表中的节点3.重排链表4.合并K个升序链表5.K个一组翻转链表 1.两数相加 两数相加 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(…...
2023.11.27 滴滴P0级故障或为k8s升级造成
滴滴11.27 P0级故障|打车|宕机|网约车|出租车|滴滴出行|系统故障_网易订阅 (163.com) 如何看待滴滴11月27日故障,对日常生产生活有哪些影响? - 知乎 (zhihu.com) 最新消息滴滴P0故障原因,是由于k8s集群升级导致的,后面又进行版本…...

Ubuntu16.04.4系统本地提权实验
目录 1.介绍: 2.实验: 3.总结: 1.介绍: 1.1:eBPF简介:eBPF(extendedBerkeleyPacketFilter)是内核源自于BPF的一套包过滤机制,BPF可以理解成用户与内核之间的一条通道,有非常强大的…...
Vue中使用正则表达式进行文本匹配和处理的方法
1. 正则表达式基础 正则表达式是一种用来匹配字符串的模式。它由普通字符(例如字符 a 到 z)和特殊字符(称为"元字符")组成。以下是一些基本的正则表达式示例: 匹配邮箱的正则表达式: /^[\w-](\…...
php许愿墙代码包括前端和后端部分
以下是一个简单的PHP许愿墙代码示例,包括前端和后端部分: 前端HTML代码(index.html): <!DOCTYPE html> <html> <head><title>许愿墙</title> </head> <body><h1>许…...
PHP 刷新缓存区的问题!
PHP流式输出,在Nginx下可以正常刷新缓存区 , 但是在Apache下会等待循环全部执行完,才会刷新!有怎么解决? header(X-Accel-Buffering: no); // Nginx情况下必须加这一行header(Content-type: text/event-stream);header…...

Android Studio Giraffe-2022.3.1-Patch-3安装注意事项
准备工作: android studio下载地址:https://developer.android.google.cn/studio/releases?hlzh-cn gradle下载地址:https://services.gradle.org/distributions/ 比较稳定的网络环境(比较android studio相关的依赖需要从谷歌那边…...

【古月居《ros入门21讲》学习笔记】14_参数的使用与编程方法
目录 说明: 1. 参数模型(全局字典) 2. 实现过程(C) 创建功能包 参数命令行的使用 YAML参数文件 rosparam命令 使用示例 编程方法(C) 配置代码编译规则 编译并运行 编译 运行 3. 实…...
Webpack 懒加载
文章目录 前言懒加载示例后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:webpack 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

归并排序:分治思想的高效排序
目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...

云原生时代的系统设计:架构转型的战略支点
📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、云原生的崛起:技术趋势与现实需求的交汇 随着企业业务的互联网化、全球化、智能化持续加深,传统的 I…...