Configure and build
Both platforms use the same Kconfig system. You edit options interactively with menuconfig, freeze the ones you care about in sdkconfig.defaults, and let the generated sdkconfig stay out of version control.
This page covers the mechanics. For what the individual options do, see Configuration options below and the per-feature guides.
ESP-IDF
Set the target, then configure
cd examples/light
idf.py set-target esp32c3 # once per project, or when changing chip
idf.py menuconfig
The SDK's options live under Component config; the app_* example helpers add their own top-level menus:
| Menu | Component | Covers |
|---|---|---|
| RMNG Configuration | esp_rmaker_neo | Build options, state reporting, timeseries, scheduling, MQTT, local control, remote control, claiming, timing |
| RMNG Common Component Configuration | esp_rmaker_neo_common | MQTT port, work queue, factory partition label and namespace |
| RMNG OTA Configuration | esp_rmaker_neo_ota | OTA transport, retries, signature verification, resume, rollback |
| ESP RainMaker App Network Configuration (top level) | app_network (example helper) | Network protocol (Wi-Fi/Thread), proof-of-possession type |
| ESP RainMaker App Button Configuration (top level) | app_button (example helper) | Button GPIO, press timings |
| ESP RainMaker App Reset Configuration (top level) | app_reset (example helper) | Long-hold network / factory reset thresholds |
sdkconfig and defaults
sdkconfigis generated in the project root. It holds your fully resolved configuration and is normally gitignored.sdkconfig.defaultsis committed. IDF merges it in wheneversdkconfigis created or is missing a key.sdkconfig.defaults.<target>is merged on top for that chip only. The in-tree examples shipsdkconfig.defaults.esp32c2and.esp32h2where a chip needs different settings, plussdkconfig.defaults.psram_quadfor PSRAM builds.
A minimal example sdkconfig.defaults looks like this:
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y
# Increase FreeRTOS timer task stack depth.
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3072
# Default to BLE provisioning.
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE=y
CONFIG_APP_NETWORK_PROV_COMPACT_QR=y
# Optimize build for size for all targets.
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
idf.py save-defconfig writes a minimal sdkconfig.defaults containing only your deviations from the IDF defaults. That is how the in-tree files are generated — use it instead of hand-maintaining a full config dump.
Build, flash, monitor
idf.py build
idf.py -p <serial-port> flash
idf.py -p <serial-port> monitor
Or all three at once:
idf.py -p <serial-port> build flash monitor
Artifacts land in build/: the ELF, <project_name>.bin (the OTA image — see OTA), the partition table, and flash_args (used when building merged production images).
POSIX
menuconfig
Configuration is driven from the build directory. Configure once, then invoke the menuconfig target:
cmake -B build -G Ninja # or -G "Unix Makefiles"
cmake --build build --target menuconfig
With Makefiles you can also go through Make directly:
make -C build menuconfig
SDKCONFIG_DEFAULTS
Point the SDK subtree at your defaults before adding it, so they apply to the esp_rmaker_neo Kconfig tree:
list(PREPEND SDKCONFIG_DEFAULTS ${CMAKE_CURRENT_LIST_DIR}/sdkconfig.defaults)
add_subdirectory(${RMNG_ROOT}/components/esp_rmaker_neo components/esp_rmaker_neo)
You can also export SDKCONFIG_DEFAULTS as an environment variable before invoking CMake.
Build and run
cmake --build build
cd build && ./light
Run from inside build/ so nvs_persistent/ and partitions/ resolve. See Set up POSIX for the build-tree layout.
Configuration options
The full set is discoverable in menuconfig — every option has help text. These are the ones that most often need changing.
Build options
| Option | Default | Notes |
|---|---|---|
CONFIG_RMNG_CONSOLE_ENABLED | y | Builds the serial console. See Serial console. |
CONFIG_RMNG_CONSOLE_PARAM_CMDS_ENABLED | y | Adds set-param / update-param / get-param. |
CONFIG_RMNG_HOST_CTRL | n | Remote control over serial, for automated testing. Cannot coexist with a console on UART0. |
CONFIG_RMNG_HEAP_MONITORING | n | Heap monitoring hooks. |
CONFIG_RMNG_BRIDGE_ENABLED | n | Bridge APIs and sources. See Bridge nodes. |
CONFIG_RMNG_CUSTOM_MQTT_CLIENT_PROVIDER | n | Supply your own MQTT client instead of the bundled coreMQTT one. |
Identity and credentials
| Option | Default | Notes |
|---|---|---|
CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME | "fctry" | Must match the partition name in partitions.csv and the label you pass to the factory tools. |
CONFIG_ESP_RMAKER_FACTORY_NAMESPACE | "rmaker_creds" | NVS namespace holding the credentials. |
MQTT and reporting
| Option | Default | Notes |
|---|---|---|
CONFIG_ESP_RMAKER_MQTT_PORT_443 | selected | Port 443 is preferred — firewalls rarely block it. Switch to _8883 only if your network requires it. |
CONFIG_ESP_RMAKER_MQTT_USE_BASIC_INGEST | y | Publishes eligible messages via AWS IoT basic ingest — cheaper, and no subscriber receives them. |
CONFIG_ESP_RMAKER_MQTT_USE_PERSISTENT_SESSION | n | QoS1 messages missed during a disconnect are delivered on reconnect (broker caches up to 1 hour). Enable only if late delivery is acceptable. |
CONFIG_ESP_RMAKER_MQTT_ENABLE_BUDGETING | y, n with OTA or bridge | Rate-limits node publishes. Budget 100, max 1024, revives 1 every 5 s by default. Messages are dropped when the budget is exhausted. |
CONFIG_RMAKER_STATE_REPORT_DELAY_MS | 500 | How long esp_rmaker_param_update() waits to coalesce further updates into one report. |
Timeseries and scheduling
| Option | Default | Notes |
|---|---|---|
CONFIG_RMAKER_TIMESERIES_PUBLISH_INITIAL_DELAY_MS | 100 | Minimum gap between timeseries publishes. |
CONFIG_RMAKER_TIMESERIES_PUBLISH_MAX_DELAY_MS | 300000 | Ceiling for the exponential backoff after a failed publish. |
CONFIG_RMAKER_TIMESERIES_DATA_QUEUE_LENGTH | 100 | Queued data points (~24 bytes each). Full queue drops new data. |
CONFIG_RMAKER_SCHEDULING_MAX_SCHEDULES | 10 | Range 1–50. Raising it grows the reported params JSON. |
Work queue
| Option | Default | Notes |
|---|---|---|
CONFIG_RMAKER_WORK_QUEUE_TASK_QUEUE_SIZE | 64 (256 with bridge) | Adding work fails when full. With a bridge, set at least 2× the child count. |
CONFIG_RMAKER_WORK_QUEUE_TASK_STACK_SIZE | 4096 (8192 with PSRAM) | PSRAM in the malloc heap deepens the allocation call chain. |
For OTA options see OTA firmware updates; for local control see Local control.
Remote control (both platforms)
With CONFIG_RMNG_HOST_CTRL=y the node exposes a binary control protocol over its serial interface, driven from a Python host controller (components/esp_rmaker_neo/src/host_ctrl/host_ctrl_python/). This is how the SDK's integration tests puppet a node — create devices, write parameters, and assert on reported state without touching the cloud.
Enabling it implies CONFIG_RMNG_HEAP_MONITORING and the virtual scheduler, and it is incompatible with a console on the default UART (both would multiplex UART0). Use USB Serial/JTAG or a second UART for the console if you need both.
Related
- Firmware specifications → Node Configuration — the payload the node reports for its configuration
- Firmware specifications → Initialization — component init order and failure points
- Pre-production checklist