Skip to content

MCU — ESP32 (ESP-IDF)

The OTA-Pulse device SDK is a C library with no dynamic allocation and no thread of its own — your application owns the main loop and calls into it. The ESP-IDF port covers Wi-Fi/HTTPS, BLE and UART transports, and works with either ESP-IDF’s native OTA or MCUboot.

Validated targets

PartTransports supported
ESP32-S3Wi-Fi/HTTPS, BLE (SMP), UART
ESP32-C6Wi-Fi/HTTPS, BLE (SMP), UART
ESP32-WROOMWi-Fi/HTTPS, BLE (SMP), UART

Full update cycles have been run on all three parts. BLE L2CAP CoC is implemented but its hardware bench validation is not yet complete, so treat it as unproven until we say otherwise.

Other ESP32 variants (S2, C3) are accepted by the server and covered by the same port, but we have not run full update cycles on them ourselves.

Prerequisites

  • ESP-IDF v5.3 or newer with a working idf.py toolchain (we build and test against v5.3.2)
  • A partition table with two OTA app slots
  • An OTA-Pulse organization with the MCU add-on enabled
  • A device provisioning (claim) key from the console

Integration

  1. Add the SDK to your project.

    Drop the SDK into your project’s components/ directory and add it to your component requirements. It builds with your existing idf.py build.

  2. Provide the platform callbacks.

    The ESP-IDF port supplies storage (NVS), flash, SHA-256 and HTTP for you. You wire up your own network-ready signal and, optionally, a health check the SDK calls before confirming an update.

  3. Initialise and provision.

    On first boot the device exchanges its claim key for a per-device API key over HTTPS and registers itself with the server. The API key is stored in NVS and reused on every later boot.

  4. Call the SDK from your main loop.

    The SDK is non-blocking: each call does a bounded slice of work and returns. It polls the server for an available update, downloads it in ranged chunks, hashes as it writes, and resumes rather than restarting if the link drops.

  5. Confirm the update.

    After the new image boots, your application calls the SDK’s confirm function once it is satisfied the device is healthy. If it never confirms, the bootloader reverts to the previous image on the next reset.

Signing

ESP32 images use an OTA-Pulse envelope whose detached signature is optional by default: an upload without one is accepted, integrity-checked but not authenticated, and logged as a warning. When a detached signature is present the server verifies it against the envelope’s inner hash before accepting the firmware version.

Set the server’s strict ESP32 signature setting to have unsigned uploads refused outright — do that before you go to production, once your build produces detached signatures.

What ESP32 devices do not get

Remote SSH and coredump collection are embedded-Linux features and do not apply here. See platform support for the full matrix.