Skip to content

[feature] Free a little memory used by bluetooth if wifi is enabled or bluetooth is disabled#10398

Merged
thebentern merged 9 commits into
meshtastic:developfrom
h3lix1:esp32-runtime-bt-memory-release
Jun 25, 2026
Merged

[feature] Free a little memory used by bluetooth if wifi is enabled or bluetooth is disabled#10398
thebentern merged 9 commits into
meshtastic:developfrom
h3lix1:esp32-runtime-bt-memory-release

Conversation

@h3lix1

@h3lix1 h3lix1 commented May 6, 2026

Copy link
Copy Markdown
Contributor

ESP32 SRAM Memory Savings by Releasing Bluetooth Memory.

Scope

Testing focused on Heltec V3 / ESP32-S3 targets without PSRAM. The goal for this branch is runtime SRAM savings with the same firmware image: if Bluetooth will not be active for this boot, release the ESP-IDF Bluetooth memory pool.

Clanker warning

This was developed with the help of Codex 5.5, but reviewed and tested by a fallible human.

Runtime change in this branch

After NodeDB loads config, but before NimBLE is initialized, ESP32 firmware now calls esp_bt_mem_release(ESP_BT_MODE_BTDM) when either:

  • config.bluetooth.enabled == false
  • config.network.wifi_enabled == true

The WiFi case is included because ESP32 Bluetooth is not started when WiFi is enabled for the boot. Releasing ESP_BT_MODE_BTDM is intentionally irreversible until reboot, which matches the existing runtime behavior where re-enabling Bluetooth already requires a reboot.

ESP_BT_MODE_BTDM is the ESP-IDF "all Bluetooth" release mode. Meshtastic uses BLE, but this mode returns the whole Bluetooth controller/host memory pool that ESP-IDF allows to be released for the rest of the boot.

The release path logs the measured heap delta. The first line below is from the Bluetooth-disabled test; the WiFi-enabled path uses
the same release call and is expected to have the same size profile.

Released BTDM memory because Bluetooth is disabled: heap +1652, free +1580
Released BTDM memory because WiFi is enabled: heap +1652, free +1580

The exact log reason depends on the config state. The WiFi-enabled path uses the same release API and timing, so it is expected to recover the same amount of memory as the Bluetooth-disabled path.

Runtime measurements

Measurements were taken from Heltec V3 boot logs during this investigation.

Test Firmware shape Result
Normal boot, Bluetooth enabled Stock Heltec V3 build Bluetooth remains available; no BTDM memory released
Bluetooth disabled at runtime Same firmware image heap +1652, free +1580 bytes after esp_bt_mem_release(ESP_BT_MODE_BTDM)
Forced earlier release during ESP32 setup Same firmware image, config ignored for test heap +1652, free +1580 bytes

Moving the release earlier than config load did not increase savings. The useful point is after config is loaded and before NimBLE setup.

Compile-time comparison

A separate no-Bluetooth firmware saves much more memory, but it is a different firmware image and cannot re-enable Bluetooth without rebuilding/flashing. That experiment disabled Bluetooth and the BLE-dependent paxcounter code:

  • MESHTASTIC_EXCLUDE_BLUETOOTH=1
  • HAS_BLUETOOTH=0
  • remove src/nimble/
  • ignore NimBLE-Arduino
  • MESHTASTIC_EXCLUDE_PAXCOUNTER=1
  • ignore libpax
  • remove NimBLE/libpax build flags such as CONFIG_BT_NIMBLE_ENABLED and LIBPAX_BLE
Build Static RAM Flash Delta vs normal
Normal Heltec V3 132492 bytes 2102181 bytes baseline
No Bluetooth + no paxcounter 116680 bytes 1907169 bytes -15812 RAM, -195012 flash

Boot-log heap impact was larger than the static RAM report:

Boot point Normal No Bluetooth + no paxcounter Delta
Early total heap 252720 283440 +30720
Early free heap 205796 239980 +34184
PowerFSM free heap 132888 167068 +34180
After NimBLE setup, normal build only 72928 n/a No-BT build was about +94140 free bytes compared with normal after NimBLE init

Other module reductions explored

These are not part of this branch, but were useful for sizing possible SRAM reductions:

  • WiFi/webserver/MQTT can be compile-time disabled with MESHTASTIC_EXCLUDE_WIFI, MESHTASTIC_EXCLUDE_WEBSERVER, and MESHTASTIC_EXCLUDE_MQTT, but removing those paths requires additional OTA/admin dependency cleanup. For this branch, WiFi enabled at runtime now triggers BTDM release because WiFi already prevents Bluetooth from starting.
  • I2C-driven features can be reduced by disabling I2C plus dependent screen, accelerometer, environmental sensor, air quality, power telemetry, and input broker code. A local build-only check of that shape reported 118228 static RAM bytes and 1711349 flash bytes, but that was a broad feature cut and is not committed here.

Interpretation

Runtime esp_bt_mem_release(ESP_BT_MODE_BTDM) saves about 1.5 KiB of free heap in the same firmware image. That is small, but it is available whenever Bluetooth will not be active for the boot, including the WiFi-enabled case.

Compile-time Bluetooth removal is the larger SRAM win: roughly 15.8 KiB static RAM, roughly 34 KiB boot free heap, and roughly 92 KiB free heap compared with a normal build after NimBLE initialization. The cost is a separate no-Bluetooth firmware image.

🤝 Attestations

  • I have tested that my proposed changes behave as described.
  • I have tested that my proposed changes do not cause any obvious regressions on the following devices:
    • Heltec (Lora32) V3
    • LilyGo T-Deck
    • LilyGo T-Beam
    • RAK WisBlock 4631
    • Seeed Studio T-1000E tracker card
    • Other (please specify below)
      Heltec V4

Release ESP-IDF BTDM memory after config load when Bluetooth is disabled or WiFi is enabled, recovering heap on ESP32 targets where BLE won’t be used for this boot.
@github-actions github-actions Bot added needs-review Needs human review enhancement New feature or request labels May 6, 2026
@thebentern thebentern requested a review from Copilot May 6, 2026 11:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an ESP32-only runtime SRAM optimization by releasing ESP-IDF Bluetooth (BTDM) memory early in boot when Bluetooth will not be used, aiming to improve heap availability on constrained targets (notably ESP32-S3 without PSRAM).

Changes:

  • Add esp32ReleaseBluetoothMemoryIfUnused() and call esp_bt_mem_release(ESP_BT_MODE_BTDM) before NimBLE initialization when Bluetooth is disabled and/or WiFi is enabled.
  • Prevent attempts to re-enable Bluetooth in the same boot after Bluetooth memory has been released (warn + require reboot).
  • Invoke the release path both after config load (boot) and after runtime Bluetooth deinit via admin flows.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/platform/esp32/main-esp32.cpp Adds BT memory release logic + re-enable guard and logging.
src/main.cpp Calls BT memory release right after NodeDB loads config, before NimBLE setup.
src/modules/AdminModule.cpp Releases BT memory after ESP32 Bluetooth deinit in disableBluetooth().
src/main.h Updates ESP32 NimBLE include guard and adds esp32ReleaseBluetoothMemoryIfUnused() declaration.

Comment thread src/platform/esp32/main-esp32.cpp Outdated
Comment thread src/platform/esp32/main-esp32.cpp
@h3lix1

h3lix1 commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

These bytes are hard fought for these days.

@fifieldt fifieldt added triaged Reviewed by the team, has enough information and ready to work on now. and removed needs-review Needs human review labels May 29, 2026
@thebentern thebentern merged commit 98fa4a6 into meshtastic:develop Jun 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request triaged Reviewed by the team, has enough information and ready to work on now.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants