Skip to content

[RF] Move RTL_433 / SX127x envs to the shipped ESP32 platform - #2360

Merged
1technophile merged 1 commit into
developmentfrom
fix/rtl433-radiolib-core3
Aug 23, 2026
Merged

[RF] Move RTL_433 / SX127x envs to the shipped ESP32 platform#2360
1technophile merged 1 commit into
developmentfrom
fix/rtl433-radiolib-core3

Conversation

@1technophile

Copy link
Copy Markdown
Owner

Description:

Eight environments were still pinned to espressif32@6.1.0 (arduino-esp32 2.0.7 / IDF 4.4) while the rest of the tree had moved to the shared ${com.esp32_platform} definition. Align them so they build against the platform that actually ships, rather than silently keeping an old toolchain alive:

esp32doitv1-aithinker-r01-sx1278
esp32dev-rtl_433, esp32dev-rtl_433-fsk
heltec-rtl_433, heltec-rtl_433-fsk
lilygo-rtl_433, lilygo-rtl_433-fsk
esp32dev-multi_receiver

The stray "* copy.c" duplicate in rtl_433_ESP that previously blocked these envs on a modern toolchain is gone as of rtl_433_ESP v0.6.0, which development already pulls in, so no build workaround is needed.

The move alone is not sufficient: the newer core leaves ~35 KB less heap on BT-less ESP32 builds, which pushes the memory-constrained RTL_433 boards into a boot loop at the first TLS handshake. That is fixed here too, in main.cpp.

On ESP32-classic builds without ZgatewayBT, arduino-esp32 3.x leaves most of the Bluetooth controller's reserved DRAM (CONFIG_BTDM_RESERVE_DRAM = 0xdb5c, 56156 B) stranded. arduino-esp32 2.x released the whole BTDM region unconditionally in initArduino():

if (!btInUse()) esp_bt_controller_mem_release(ESP_BT_MODE_BTDM);

3.x releases CLASSIC and BLE separately, and the CLASSIC pass silently short-circuits. cores/esp32/esp32-hal-bt.c has:

#if defined(CONFIG_BT_CLASSIC_ENABLED)
static bool _classicMemReleased = false;
#else
static bool _classicMemReleased = true;  // "No Classic BT on this chip"
#endif

With a BLE-only controller build CONFIG_BT_CLASSIC_ENABLED is unset, so _classicMemReleased starts true and btMemRelease(BT_MODE_CLASSIC_BT) returns "already released" without reaching IDF. Only the ~5 KB BLE slice is freed. The guard is wrong for this part: ESP32 does have Classic BT hardware (CONFIG_SOC_BT_CLASSIC_SUPPORTED) and the DRAM is reserved regardless of the controller's configured mode; the correct guard would be CONFIG_SOC_BT_CLASSIC_SUPPORTED. Reported upstream separately.

Release the whole BTDM region explicitly. esp_bt_mem_release() is used rather than esp_bt_controller_mem_release() because it is a superset that also frees the linker _bt_data / bt_controller* sections. The guard is compile-time and authoritative: OMG knows via ZgatewayBT whether it uses BT, whereas the core infers it from link-time flags that NimBLE-Arduino does not set. Safe no-op if the memory was already released or once the core is fixed. Note this makes btStart() permanently unavailable in these builds, which is already the case for a !ZgatewayBT build.

Measured on a Heltec WiFi LoRa32 V2 running heltec-rtl_433 (WiFi + MQTT + TLS + rtl_433 + SSD1306, no BT), pioarduino 55.03.39 / esp32-arduino-libs 0.1.8:

BT DRAM reclaimed: 209928 -> 245048 (+35120 B)
Update check, free heap: 49868 -> 89484

Without it, the boot-time HTTPS update check fails its TLS handshake ("Dynamic Impl: alloc(4437 bytes) failed", then X509 -9984) because the largest free block is too small, and the MinimumMemory watchdog then reboots the board in a loop. With it: no allocation failure, handshake succeeds, freemem ~85 KB / minmem 53432 against the 40000 threshold, 0 reboots over a 3 min soak with live RTL_433 decodes.

The memory fix affects every ESP32-classic env without ZgatewayBT, not just the ones moved here. The RTL_433 envs fail loudly because they carry the MinimumMemory watchdog; others (esp32dev-ir, esp32dev-pilight, ttgo-lora32-v21, heltec-wifi-lora-32, ...) simply run ~35 KB short. Builds with ZgatewayBT are unaffected.

Hardware validation, two boards:

heltec-rtl_433 (OOK 433.92 MHz, Heltec WiFi LoRa32 V2)
boots, joins WiFi/MQTT, RadioLib/SX127x RSSI calibration completes,
HA discovery publishes, decodes live ambient sensors
(Ambientweather-F007TH, Prologue-TH, WEC-2103).

heltec-rtl_433-fsk (FSK 915 MHz, second Heltec)
same boot path, decodes a live Fineoffset-WH51 soil sensor.

The other six envs have no matching board on hand and are compile-only.

Checklist:

  • The pull request is done against the latest development branch
  • Only one feature/fix was added per PR and the code change compiles without warnings
  • I accept the DCO.

Eight environments were still pinned to espressif32@6.1.0 (arduino-esp32
2.0.7 / IDF 4.4) while the rest of the tree had moved to the shared
${com.esp32_platform} definition. Align them so they build against the
platform that actually ships, rather than silently keeping an old
toolchain alive:

  esp32doitv1-aithinker-r01-sx1278
  esp32dev-rtl_433, esp32dev-rtl_433-fsk
  heltec-rtl_433, heltec-rtl_433-fsk
  lilygo-rtl_433, lilygo-rtl_433-fsk
  esp32dev-multi_receiver

The stray "* copy.c" duplicate in rtl_433_ESP that previously blocked
these envs on a modern toolchain is gone as of rtl_433_ESP v0.6.0, which
development already pulls in, so no build workaround is needed.

The move alone is not sufficient: the newer core leaves ~35 KB less heap
on BT-less ESP32 builds, which pushes the memory-constrained RTL_433
boards into a boot loop at the first TLS handshake. That is fixed here
too, in main.cpp.

On ESP32-classic builds without ZgatewayBT, arduino-esp32 3.x leaves most
of the Bluetooth controller's reserved DRAM (CONFIG_BTDM_RESERVE_DRAM =
0xdb5c, 56156 B) stranded. arduino-esp32 2.x released the whole BTDM
region unconditionally in initArduino():

    if (!btInUse()) esp_bt_controller_mem_release(ESP_BT_MODE_BTDM);

3.x releases CLASSIC and BLE separately, and the CLASSIC pass silently
short-circuits. cores/esp32/esp32-hal-bt.c has:

    #if defined(CONFIG_BT_CLASSIC_ENABLED)
    static bool _classicMemReleased = false;
    #else
    static bool _classicMemReleased = true;  // "No Classic BT on this chip"
    #endif

With a BLE-only controller build CONFIG_BT_CLASSIC_ENABLED is unset, so
_classicMemReleased starts true and btMemRelease(BT_MODE_CLASSIC_BT)
returns "already released" without reaching IDF. Only the ~5 KB BLE slice
is freed. The guard is wrong for this part: ESP32 does have Classic BT
hardware (CONFIG_SOC_BT_CLASSIC_SUPPORTED) and the DRAM is reserved
regardless of the controller's configured mode; the correct guard would be
CONFIG_SOC_BT_CLASSIC_SUPPORTED. Reported upstream separately.

Release the whole BTDM region explicitly. esp_bt_mem_release() is used
rather than esp_bt_controller_mem_release() because it is a superset that
also frees the linker _bt_data / _bt_controller_* sections. The guard is
compile-time and authoritative: OMG knows via ZgatewayBT whether it uses
BT, whereas the core infers it from link-time flags that NimBLE-Arduino
does not set. Safe no-op if the memory was already released or once the
core is fixed. Note this makes btStart() permanently unavailable in these
builds, which is already the case for a !ZgatewayBT build.

Measured on a Heltec WiFi LoRa32 V2 running heltec-rtl_433 (WiFi + MQTT +
TLS + rtl_433 + SSD1306, no BT), pioarduino 55.03.39 / esp32-arduino-libs
0.1.8:

  BT DRAM reclaimed: 209928 -> 245048        (+35120 B)
  Update check, free heap: 49868 -> 89484

Without it, the boot-time HTTPS update check fails its TLS handshake
("Dynamic Impl: alloc(4437 bytes) failed", then X509 -9984) because the
largest free block is too small, and the MinimumMemory watchdog then
reboots the board in a loop. With it: no allocation failure, handshake
succeeds, freemem ~85 KB / minmem 53432 against the 40000 threshold,
0 reboots over a 3 min soak with live RTL_433 decodes.

The memory fix affects every ESP32-classic env without ZgatewayBT, not
just the ones moved here. The RTL_433 envs fail loudly because they carry
the MinimumMemory watchdog; others (esp32dev-ir, esp32dev-pilight,
ttgo-lora32-v21, heltec-wifi-lora-32, ...) simply run ~35 KB short.
Builds with ZgatewayBT are unaffected.

Hardware validation, two boards:

  heltec-rtl_433 (OOK 433.92 MHz, Heltec WiFi LoRa32 V2)
    boots, joins WiFi/MQTT, RadioLib/SX127x RSSI calibration completes,
    HA discovery publishes, decodes live ambient sensors
    (Ambientweather-F007TH, Prologue-TH, WEC-2103).

  heltec-rtl_433-fsk (FSK 915 MHz, second Heltec)
    same boot path, decodes a live Fineoffset-WH51 soil sensor.

The other six envs have no matching board on hand and are compile-only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@1technophile
1technophile merged commit b6b23bd into development Aug 23, 2026
194 of 196 checks passed
@1technophile
1technophile deleted the fix/rtl433-radiolib-core3 branch August 23, 2026 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant