ESP32 OTA default examples don't work in PlatformIO

Hey there,
I’m trying to implement OTA functionality within my project but can’t seem to find code that I can compile.
I’ve asked a friend of mine how he did it and he said he used the OTA examples from the ESP-IDF repository found here: esp-idf/examples/system/ota at master · espressif/esp-idf · GitHub
When I try to use that code however PlatformIO can’t seem to find a lot of definitions or other functions.
I’ve tried manually putting the right files into the project folder and including them but it doesn’t seem to work.
Can anyone tell me how I’m supposed to run the example code with PlatformIO?

And the project is written with Arduino or ESP-IDF as framework?

You are linking to the master branch version of that example, which won’t work since PlatformIO uses ESP-IDF version 4.2 (releases) in its latest version. You would need to base it off of https://github.com/espressif/esp-idf/tree/release/v4.2/examples/system/ota.

Further see general info about OTA at the official documentation.

1 Like

I’m using ESP-IDF as framework.
I’ve looked at the version 4.2 branch you linked to see if using that code would work.
The problem I’m running into now is that PlatformIO can’t include the “protocol_examples_common.h” file.
Would you happen to know how to fix this issue?

You need to have all dependencies in the project. You’re missing esp-idf/examples/common_components at release/v4.2 · espressif/esp-idf · GitHub – copy that folder in a new folder called components, as per docs and example.

1 Like

That fixed the include error for that file but now I’m getting errors about defines in the sdkconfig.ci
I tried putting that file along with sdkconfig.defaults into the include folder and including them both in my main.cpp but platformIO says some values from those files aren’t “declared in this scope”
Any idea what could fix this?
Edit: I’m talking about things like CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL
When I look in the sdkconfig.ci file i get the following error message:
‘CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL’ does not name a type; did you mean ‘CONFIG_EXAMPLE_WIFI_PASSWORD’?

sdkconfig.ci is for CI (continuous integration), you’ll want the sdkconfig.defaults file. Assuming you’re talking about the simple_ota_example example, the EXAMPLE_FIRMWARE_UPGRADE_URL macro comes from the KConfig file

So if you follow the docs for the menuconfig that macro should should be there. I can also test this myself…

1 Like

I’m not having any problems with the examples. What I’ve done :

  • Cloned esp-idf in v4.2 version (not release/v4.2 — this gets updated in esp-idf! very confusing!), specifically for this folder
  • created a blank ESP-IDF project
  • removed default src/CMakeLists.txt and src/main.c files
  • created a new folder components in which protocol_examples_common was copied
  • copied over the sdkconfig.defaults in the root directory
  • coped the CMakeLists.txt, Kconfig.projbuild and simple_ota_example.c from the example in the src/ folder
  • copied the server_certs folder from the example in the root of the project
  • opened a CLI and ran pio run -t menuconfig

And there I see all the configuration options for the example.

grafik

So I went and configured it for my WiFi network and IP address.

Further, per documentation, I configure my platformio.ini for the required baud rate, monitor filters (for color) and embedded text file:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = espidf
monitor_speed = 115200
monitor_filters = direct
board_build.embed_txtfiles =
  server_certs/ca_cert.pem

And when I hit compile I get

Linking .pio\build\esp32dev\firmware.elf
Retrieving maximum program size .pio\build\esp32dev\firmware.elf
Checking size .pio\build\esp32dev\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   9.9% (used 32516 bytes from 327680 bytes)
Flash: [========  ]  77.7% (used 814548 bytes from 1048576 bytes)
Building .pio\build\esp32dev\firmware.bin
esptool.py v3.0
===================== [SUCCESS] Took 45.02 seconds =====================

So an “upload and monitor” gives

I (769) example_connect: Connecting to You shall not pass...
W (769) phy_init: failed to load RF calibration data (0xffffffff), falling back to full calibration
I (929) phy: phy_version: 4500, 0cd6843, Sep 17 2020, 15:37:07, 0, 2
I (949) wifi:mode : sta (24:0a:c4:04:26:38)
I (949) example_connect: Waiting for IP(s)
I (2279) wifi:new:<11,0>, old:<1,0>, ap:<255,255>, sta:<11,0>, prof:13
I (3049) wifi:state: init -> auth (b0)
I (3059) wifi:state: auth -> assoc (0)
I (3069) wifi:state: assoc -> run (10)
I (3079) wifi:connected with You shall not pass, aid = 2, channel 11, BW20, bssid = e8:de:27:bb:c7:a6
I (3079) wifi:security: WPA2-PSK, phy: bgn, rssi: -45
I (3079) wifi:pm start, type: 1

I (3079) wifi:AP's beacon interval = 102400 us, DTIM period = 2
I (4649) example_connect: Got IPv6 event: Interface "example_connect: sta" address: fe80:0000:0000:0000:260a:c4ff:fe04:2638, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (7149) esp_netif_handlers: example_connect: sta ip: 192.168.1.162, mask: 255.255.255.0, gw: 192.168.1.1
I (7149) example_connect: Got IPv4 event: Interface "example_connect: sta" address: 192.168.1.162
I (7159) example_connect: Connected to example_connect: sta
I (7159) example_connect: - IPv4 address: 192.168.1.162
I (7169) example_connect: - IPv6 address: fe80:0000:0000:0000:260a:c4ff:fe04:2638, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (7179) wifi:Set ps type: 0

I (7179) simple_ota_example: Starting OTA example
E (25439) esp-tls: Failed to connnect to host (errno 113)
E (25439) esp-tls: Failed to open new connection

So the example starts up, connects to my WiFi and then complains about not being able to connect to my server, which is correct sine I haven’t set up a server to host the expected https://192.168.1.180:8070/hello-world.bin file where it would fetch the new firmware from.

I could further dig into this and setup the webserver (or use the suppplied example_test.py script, since the SSL certs and keys are already hardcoded into there) to demonstrate the firmware fully working but this is now out of PlatformIO terroritory. PlatformIO has built the firmware just fine and it’s running.

2 Likes

Hm because I couldn’t help my curiosity I ended up running the example completely.

I modified the example_test.py file to have no dependency on some ESP-IDF internal libs but simply start the needed HTTPS server with the needed key and certificate.

After that was up and getting the output

I (4719) esp-tls-mbedtls: Failed to verify peer certificate!
I (4719) esp-tls-mbedtls: verification info:   ! The certificate Common Name (CN) does not match with the expected CN

I had to turn on the “Ignore common name verification” in the menuconfig (“Example configuration”) option. Then I got

I (5499) esp_https_ota: Starting OTA...
E (5499) esp_https_ota: Passive OTA partition not found
E (5499) simple_ota_example: Firmware upgrade failed

which means I had my partition table setup wrongly. The default per documentation is partitions_singleapp.csv after all and that can’t do OTA.

So I added

board_build.partitions = partitions_two_ota.csv

to the platformio.ini and ran menuconfig again to also set it in “Partition Table” configuration and re-uploaded the program. And low-and-behold on the Python script said…

>python example_test_no_deps.py
Starting HTTPS server at https://192.168.1.180:8070 serving folder C:\Users\Max\temp\esp-idf\examples\system\ota\simple_ota_example\http_server_root
192.168.1.162 - - [28/Apr/2021 15:47:54] "GET /hello-world.bin HTTP/1.1" 200 -

And the firmware output said

I (5046) simple_ota_example: Starting OTA example
I (7156) esp_https_ota: Starting OTA...
I (7156) esp_https_ota: Writing to partition subtype 16 at offset 0x110000
I (17526) esp_https_ota: Connection closed
I (17526) esp_image: segment 0: paddr=0x00110020 vaddr=0x3f400020 size=0x1f8e4 (129252) map
I (17576) esp_image: segment 1: paddr=0x0012f90c vaddr=0x3ffb0000 size=0x0070c (  1804) 
I (17576) esp_image: segment 2: paddr=0x00130020 vaddr=0x400d0020 size=0x8e604 (583172) map
I (17806) esp_image: segment 3: paddr=0x001be62c vaddr=0x3ffb070c size=0x03168 ( 12648) 
I (17806) esp_image: segment 4: paddr=0x001c179c vaddr=0x40080000 size=0x00404 (  1028) 
I (17816) esp_image: segment 5: paddr=0x001c1ba8 vaddr=0x40080404 size=0x15284 ( 86660) 
I (17856) esp_image: segment 0: paddr=0x00110020 vaddr=0x3f400020 size=0x1f8e4 (129252) map
I (17906) esp_image: segment 1: paddr=0x0012f90c vaddr=0x3ffb0000 size=0x0070c (  1804) 
I (17906) esp_image: segment 2: paddr=0x00130020 vaddr=0x400d0020 size=0x8e604 (583172) map
I (18116) esp_image: segment 3: paddr=0x001be62c vaddr=0x3ffb070c size=0x03168 ( 12648) 
I (18126) esp_image: segment 4: paddr=0x001c179c vaddr=0x40080000 size=0x00404 (  1028) 
I (18126) esp_image: segment 5: paddr=0x001c1ba8 vaddr=0x40080404 size=0x15284 ( 86660) 
I (18186) wifi:state: run -> init (0)
I (18186) wifi:pm stop, total sleep time: 1219859 us / 14696251 us

I (18186) wifi:new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
W (18196) wifi:hmac tx: stop, discard
I (18236) wifi:flush txq
I (18236) wifi:stop sw txq
I (18236) wifi:lmac stop hw txq
I (18236) wifi:Deinit lldesc rx mblock:10
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

So it succesfully did the OTA and rebooted, and the hello-world.bin (aka again the OTA example) was running.

I’ll put this in a repository shortly.

1 Like

See GitHub - maxgerhardt/pio-espidf-simple-ota-example: PlatformIO compilable version of https://github.com/espressif/esp-idf/tree/v4.2/examples/system/ota/simple_ota_example.

1 Like

Hey man,
Sorry for the late response but I just wanted to say thanks for the incredible help.
It helped us along greatly and I’m pretty sure we wouldn’t have gotten it without your help.
I appreciate you taking time out of your day to help some random internet stranger.
So anyway,
Thanks

1 Like