Keep classic ESP32 release profiles within their measured RAM budgets

This commit is contained in:
mikecarper committed 2026-09-05 10:27:07 -07:00
1 parent 55f59e13c0
commit 9155ea58c9
6 files changed
+130 -11

No files matched your search

+59 -6
View File
@@ -2641,6 +2641,24 @@ requires_dram_limited_neighbors() {
# ESP32 MQTT observers exhaust internal DRAM, while the 256 KiB STM32WL
# targets exhaust their fixed application region because initialized table
# storage is part of the image.
# These measured classic ESP32 LoRa OTA images fall below the required
# 8 KiB static reserve at 254 neighbors. Use their board-declared 50-entry
# tables when the OTA manager is included.
case "${1,,}" in
generic_e22_sx1262_repeater_lora_ota_no_external_sensors|\
generic_e22_sx1268_repeater_lora_ota_no_external_sensors|\
heltec_v2_repeater_lora_ota_no_external_sensors|\
meshadventurer_sx1262_repeater_lora_ota_no_external_sensors|\
meshadventurer_sx1268_repeater_lora_ota_no_external_sensors|\
tbeam_sx1262_repeater_lora_ota_no_external_sensors|\
tbeam_sx1276_repeater_lora_ota_no_external_sensors)
return 0 ;;
generic_e22_sx1262_repeater|generic_e22_sx1268_repeater|\
heltec_v2_repeater|meshadventurer_sx1262_repeater|\
meshadventurer_sx1268_repeater|tbeam_sx1262_repeater|\
tbeam_sx1276_repeater)
if [ "$ESP32_FULL_BUILD" = "1" ]; then return 0; fi ;;
esac
#
# Classic ESP32 bridge targets only need the lower limit when the expanded
# FULL profile also enables packet logging. Keep their ordinary and
@@ -2662,6 +2680,8 @@ requires_dram_limited_neighbors() {
esac
fi
case "${1,,}" in
lilygo_tlora_v2_1_1_6_repeater_observer_mqtt_)
return 0 ;;
tbeam_sx1262_repeater_observer_mqtt|tbeam_sx1262_room_server_observer_mqtt|tbeam_sx1276_repeater_observer_mqtt|tbeam_sx1276_room_server_observer_mqtt|rak_3x72_repeater|tiny_relay_repeater|wio-e5-mini_repeater|wio-e5-repeater_bridge_rs232|wio-e5_repeater) return 0 ;;
*) return 1 ;;
esac
@@ -2993,6 +3013,7 @@ declare_build_capability_contract() {
apply_esp32_lora_ota_size_profile() {
local env_name=$1
local max_neighbours=$ESP32_FULL_MAX_NEIGHBOURS
if [ "$BUILD_PROFILE_FOR_TARGET" != "standard" ] \
|| ! requires_esp32_portable_app_slot "$env_name"; then
@@ -3018,12 +3039,18 @@ apply_esp32_lora_ota_size_profile() {
|| requires_esp32_field_browser_ota "$env_name"; then
# The no-external-sensors image is also the self-updatable field image. Keep
# manual browser OTA available on every ESP32 family through the compact
# uploader, the complete role CLI, and the full one-byte neighbor-index
# range. MeshCore and this source-built dependency set do not use C++
# uploader, the complete role CLI, and the target's safe neighbor capacity.
# MeshCore and this source-built dependency set do not use C++
# exceptions, so omit their otherwise forced runtime tables instead of
# dropping WiFi OTA, LoRa OTA, USB seeding, or CLI commands.
append_platformio_build_unflags "-DDISABLE_WIFI_OTA=1 -DMAX_NEIGHBOURS=50 -DMAX_NEIGHBOURS=8 -fexceptions"
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -UDISABLE_WIFI_OTA -DLIGHTWEIGHT_WIFI_OTA=1 -DMAX_NEIGHBOURS=${ESP32_FULL_MAX_NEIGHBOURS} -fno-exceptions"
append_platformio_build_unflags "-DDISABLE_WIFI_OTA=1 -DMAX_NEIGHBOURS=8 -fexceptions"
if requires_dram_limited_neighbors "$env_name"; then
max_neighbours=$DRAM_LIMITED_MAX_NEIGHBOURS
append_platformio_build_unflags "-DMAX_NEIGHBOURS=254"
else
append_platformio_build_unflags "-DMAX_NEIGHBOURS=50"
fi
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -UDISABLE_WIFI_OTA -DLIGHTWEIGHT_WIFI_OTA=1 -DMAX_NEIGHBOURS=${max_neighbours} -fno-exceptions"
record_build_capability "web.lightweight_browser_ota"
else
append_platformio_build_unflags "-DLIGHTWEIGHT_WIFI_OTA=1"
@@ -3090,6 +3117,32 @@ apply_esp32_full_size_profile() {
fi
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DMAX_NEIGHBOURS=${max_neighbours}"
case "${env_name,,}" in
tbeam_sx1262_repeater_observer_mqtt|tbeam_sx1276_repeater_observer_mqtt)
# MQTT/TLS plus OTA left only 3.3 KiB of static-region headroom with
# 63 rules. Retain the complete rule engine with a 31-entry table.
append_platformio_build_unflags "-DFLOOD_PACKET_FILTER_SLOTS=63"
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DFLOOD_PACKET_FILTER_SLOTS=31"
record_build_reduction \
"mesh.flood_rules limited to 31 by measured internal DRAM; complete rule engine retained"
;;
generic_e22_sx1262_repeater_bridge_espnow|\
generic_e22_sx1268_repeater_bridge_espnow|\
heltec_v2_repeater_bridge_espnow|\
lilygo_tlora_v2_1_1_6_repeater_bridge_espnow|\
meshadventurer_sx1262_repeater_bridge_espnow|\
meshadventurer_sx1268_repeater_bridge_espnow|\
tbeam_sx1262_repeater_bridge_espnow|\
tbeam_sx1276_repeater_bridge_espnow)
if [ "${PACKET_LOGGING_OVERRIDE,,}" = "on" ]; then
append_platformio_build_unflags "-DFLOOD_PACKET_FILTER_SLOTS=63"
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DFLOOD_PACKET_FILTER_SLOTS=47"
record_build_reduction \
"mesh.flood_rules limited to 47 by measured internal DRAM; complete rule engine retained"
fi
;;
esac
# Restore the full ElegantOTA implementation only when the target already
# declares its dependency. Some ESP32-C6 targets intentionally have no
# compatible ElegantOTA library and retain their target WiFi-OTA setting.
@@ -3540,9 +3593,9 @@ apply_companion_radio_full_profile() {
meshadventurer_sx1262_companion_radio_full|\
meshadventurer_sx1268_companion_radio_full)
append_platformio_build_unflags "-DMAX_CONTACTS=160 -DMAX_GROUP_CHANNELS=40 -DOFFLINE_QUEUE_SIZE=128"
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DMAX_CONTACTS=160 -DMAX_GROUP_CHANNELS=30 -DOFFLINE_QUEUE_SIZE=64"
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DMAX_CONTACTS=100 -DMAX_GROUP_CHANNELS=30 -DOFFLINE_QUEUE_SIZE=16"
record_build_reduction \
"companion.capacity limited to 160 contacts, 30 channels, and 64 queued frames by measured internal DRAM"
"companion.capacity limited to 100 contacts, 30 channels, and 16 queued frames by measured internal DRAM"
;;
*)
if requires_esp32_companion_full_ota_fallback "$pio_env_name"; then
+2 -2
View File
@@ -15,13 +15,13 @@ A reboot clears it.
| RP2040 | 256 |
| STM32 | 16 |
| Known constrained classic ESP32 target override | 128 |
| Meshadventurer Full Companion | 64 |
| Meshadventurer Full Companion | 16 |
| Constrained Full ESP32 fallback | 16 |
An explicit target `OFFLINE_QUEUE_SIZE` overrides the platform default. The
Heltec V2 and TLora V2 Full Companion profiles, for example, use 16 frames so
their combined WiFi, BLE, and LoRa mOTA image retains enough internal DRAM.
Meshadventurer SX1262 and SX1268 Full Companion use 64 frames together with 160
Meshadventurer SX1262 and SX1268 Full Companion use 16 frames together with 100
contacts and 30 group channels; their ordinary transport-specific images keep
128 frames and 40 channels.
+3 -3
View File
@@ -314,9 +314,9 @@ partition layout. Other boards with 8 MB or more retain dual application
partitions.
Heltec V2 and TLora V2 use 100 contacts, 8 group channels, and a 16-frame offline
queue in this combined profile because of internal DRAM limits. Meshadventurer
SX1262 and SX1268 retain 160 contacts, use 30 group channels, and use a
64-frame queue. That is the smallest measured reduction which cleared their
classic ESP32 internal-DRAM link limit; their ordinary transport-specific
SX1262 and SX1268 use 100 contacts, 30 group channels, and a 16-frame queue.
These capacities preserve the required 8 KiB static internal-DRAM reserve
alongside MOTA and all Full transports; their ordinary transport-specific
images retain 160 contacts, 40 channels, and 128 queued frames.
Full Companions normally retain 256 pending Companion message frames. ESP32
+5
View File
@@ -161,3 +161,8 @@ and the board's matching BLE-DFU-capable bootloader/SoftDevice. USB remains
the fallback when the installed bootloader does not support that procedure.
Bluetooth DFU updates the Companion; the separate Bluetooth MOTA source
service feeds packages to other mesh nodes.
For OTAFIX installations, use the exact board/storage profile from
[OTAFIX 2.4.5](https://github.com/mikecarper/Adafruit_nRF52_Bootloader_OTAFIX/releases/tag/0.11.0-OTAFIX2.4.5).
Its release notes cover the Bluetooth reconnect fix and upgrades from older
bootloaders, including the special UF2-drive precautions for version 2.4.3.
+11
View File
@@ -31,6 +31,15 @@ application slots and OTA metadata; nRF52 Bluetooth qualification checks the
linked DFU service and its application ZIP. LoRa installation on nRF52 still
requires the exact matching OTAFIX bootloader and storage arrangement.
Classic ESP32 capacity limits are recorded in each artifact's capability
manifest. Generic E22, Heltec V2, Meshadventurer, and T-Beam OTA repeaters,
plus the TLora MQTT repeater, use 50 neighbors where needed to preserve the
required internal RAM reserve.
T-Beam MQTT repeater profiles retain the full rule engine with 31 flood rules;
constrained classic ESP32 ESP-NOW bridges with logging use 47.
Meshadventurer Full uses 100 contacts, 30 group channels, and a 16-frame
offline queue while retaining its MOTA and transport features.
Since 1.17.1.4, this branch also includes USB session and contact-persistence
fixes, automatic nRF52 ExtraFS recovery, improved Indicator setup/display
handling, compressed MOTA transport, and measured ESP32 memory limits.
@@ -62,3 +71,5 @@ the matrix unsuccessful and must be resolved before publication.
`--allow-no-ota` is an explicit development override for cable-only
infrastructure. Those outputs do not belong in this OTA-required release.
Use a separate output directory when changing the radio or settings profile.
Use a fresh release output directory after changing the source revision or
firmware version so packaging cannot mix old and new binaries.
+50
View File
@@ -38,4 +38,54 @@ fi
resolve_command_targets build-firmware rp_companion_radio_usb >/dev/null
[ "${#RESOLVED_BUILD_TARGETS[@]}" = 1 ] || fail "explicit USB Companion was rejected"
# The portable OTA overlay and the final neighbor overlay must agree: an
# earlier build_unflags entry removes even a later definition in PlatformIO.
for target in Generic_E22_sx1262_repeater_lora_ota_no_external_sensors \
Generic_E22_sx1268_repeater_lora_ota_no_external_sensors \
Heltec_v2_repeater_lora_ota_no_external_sensors \
Meshadventurer_sx1262_repeater_lora_ota_no_external_sensors \
Meshadventurer_sx1268_repeater_lora_ota_no_external_sensors \
Tbeam_SX1262_repeater_lora_ota_no_external_sensors \
Tbeam_SX1276_repeater_lora_ota_no_external_sensors; do
PIO_ENV_PLATFORM_BY_NAME[$target]=ESP32_PLATFORM
PLATFORMIO_BUILD_FLAGS=""
PLATFORMIO_BUILD_UNFLAGS=""
BUILD_PROFILE_FOR_TARGET=standard
ESP32_FULL_BUILD=0
apply_esp32_lora_ota_size_profile "$target"
apply_repeater_neighbor_capacity "$target"
[[ "$PLATFORMIO_BUILD_FLAGS" == *"-DMAX_NEIGHBOURS=50"* ]] \
|| fail "$target lost its measured-safe neighbor capacity"
[[ "$PLATFORMIO_BUILD_UNFLAGS" != *"MAX_NEIGHBOURS=50"* ]] \
|| fail "$target removed its selected neighbor capacity"
[[ "$PLATFORMIO_BUILD_FLAGS" == *"-DLIGHTWEIGHT_WIFI_OTA=1"* ]] \
|| fail "$target lost WiFi OTA while fixing its RAM budget"
done
ESP32_FULL_BUILD=1
BUILD_PROFILE_FOR_TARGET=full
PACKET_LOGGING_OVERRIDE=on
for pair in Tbeam_SX1262_repeater_observer_mqtt:31 \
Tbeam_SX1276_repeater_observer_mqtt:31 \
Generic_E22_sx1262_repeater_bridge_espnow:47 \
LilyGo_TLora_V2_1_1_6_repeater_bridge_espnow:47 \
LilyGo_TLora_V2_1_1_6_repeater_observer_mqtt_:default; do
target=${pair%:*}
rules=${pair##*:}
PIO_ENV_PLATFORM_BY_NAME[$target]=ESP32_PLATFORM
PIO_ENV_FULL_BUILD_BY_NAME[$target]=1
PLATFORMIO_BUILD_FLAGS=""
PLATFORMIO_BUILD_UNFLAGS=""
apply_esp32_full_size_profile "$target"
apply_repeater_neighbor_capacity "$target"
[[ "$PLATFORMIO_BUILD_FLAGS" == *"-DMAX_NEIGHBOURS=50"* \
&& "$PLATFORMIO_BUILD_UNFLAGS" != *"MAX_NEIGHBOURS=50"* ]] \
|| fail "$target lost its Full profile neighbor capacity"
if [ "$rules" != default ]; then
[[ "$PLATFORMIO_BUILD_FLAGS" == *"-DFLOOD_PACKET_FILTER_SLOTS=$rules"* \
&& "$PLATFORMIO_BUILD_UNFLAGS" != *"FLOOD_PACKET_FILTER_SLOTS=$rules"* ]] \
|| fail "$target lost its Full profile rule capacity"
fi
done
echo "test_release_ota_policy: OK"