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 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...