mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-23 16:52:22 +00:00
Fix capacity matrix build regressions
This commit is contained in:
1 parent
e4db57dbef
commit
5f7d03373c
11 files changed
+75
-13
No files matched your search
@@ -37,7 +37,10 @@ The [small-screen message layout](v4_pixel5_font_trial.md) retains complete
|
||||
160-byte messages. Its expanded preview records add 2,816 bytes to the
|
||||
startup allowance and increase the contiguous history allocation budget.
|
||||
The V4 can allocate that history in PSRAM; the guard conservatively reserves
|
||||
internal capacity so that PSRAM availability cannot hide a RAM shortage.
|
||||
internal capacity so that PSRAM availability cannot hide a RAM shortage. A
|
||||
target may replace the generic UI allowance only with
|
||||
`MESH_COMPANION_SCREEN_STARTUP_BYTES`; a source-side assertion then covers its
|
||||
actual startup screens plus ESP32 allocator overhead.
|
||||
|
||||
These are engineering allowances for supported configurations, not measured
|
||||
free heap after boot or a guarantee against every future allocation failure.
|
||||
|
||||
@@ -1757,6 +1757,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(MESH_COMPANION_SCREEN_STARTUP_BYTES)
|
||||
// The target may replace the generic UI allowance with a tighter measured
|
||||
// bound. Keep the check next to the actual allocations so a future screen
|
||||
// growth cannot silently invalidate its runtime-RAM budget. ESP32's checked
|
||||
// heap allocator can consume up to 16 bytes per allocation.
|
||||
static_assert(sizeof(SplashScreen) + sizeof(HomeScreen)
|
||||
+ sizeof(MsgPreviewScreen) + 3 * 16
|
||||
<= MESH_COMPANION_SCREEN_STARTUP_BYTES,
|
||||
"Increase MESH_COMPANION_SCREEN_STARTUP_BYTES and its RAM budget");
|
||||
#endif
|
||||
|
||||
void UITask::begin(DisplayDriver* display, SensorManager* sensors, CompanionNodePrefs* node_prefs) {
|
||||
_display = display;
|
||||
_sensors = sensors;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#if MESH_ENABLE_ROOM_FLOOD_RULE_ENGINE
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <helpers/FloodFilterPolicy.h>
|
||||
@@ -394,8 +395,13 @@ static bool verifyWrittenFile(FILESYSTEM* fs, const char* path,
|
||||
|
||||
} // namespace
|
||||
|
||||
FloodRuleEngine::FloodRuleEngine() : _fs(NULL), _regions(NULL) {
|
||||
memset(_entries, 0, sizeof(_entries));
|
||||
FloodRuleEngine::FloodRuleEngine()
|
||||
: _fs(NULL), _regions(NULL),
|
||||
_entries(new (std::nothrow) Entry[RULE_SLOTS]) {
|
||||
// MyMesh is constructed before setup(), while the internal heap is
|
||||
// unfragmented. The runtime RAM gate budgets this exact allocation.
|
||||
if (_entries == NULL) abort();
|
||||
memset(_entries, 0, sizeof(Entry) * RULE_SLOTS);
|
||||
}
|
||||
|
||||
void FloodRuleEngine::begin(FILESYSTEM* fs, RegionMap* regions) {
|
||||
@@ -405,7 +411,7 @@ void FloodRuleEngine::begin(FILESYSTEM* fs, RegionMap* regions) {
|
||||
}
|
||||
|
||||
void FloodRuleEngine::seedDefaults() {
|
||||
memset(_entries, 0, sizeof(_entries));
|
||||
memset(_entries, 0, sizeof(Entry) * RULE_SLOTS);
|
||||
Entry& entry = _entries[0];
|
||||
entry.active = true;
|
||||
entry.payload_type = PAYLOAD_TYPE_OTA;
|
||||
@@ -423,7 +429,7 @@ void FloodRuleEngine::load() {
|
||||
|
||||
enum class FileState : uint8_t { Missing, Valid, Invalid, Unreadable };
|
||||
auto loadFile = [this](const char* path) -> FileState {
|
||||
memset(_entries, 0, sizeof(_entries));
|
||||
memset(_entries, 0, sizeof(Entry) * RULE_SLOTS);
|
||||
if (!_fs->exists(path)) return FileState::Missing;
|
||||
File file = openRead(_fs, path);
|
||||
if (!file) return FileState::Unreadable;
|
||||
@@ -655,7 +661,7 @@ void FloodRuleEngine::load() {
|
||||
&& file.available() == 0;
|
||||
}
|
||||
file.close();
|
||||
if (!success) memset(_entries, 0, sizeof(_entries));
|
||||
if (!success) memset(_entries, 0, sizeof(Entry) * RULE_SLOTS);
|
||||
return success ? FileState::Valid : FileState::Invalid;
|
||||
};
|
||||
|
||||
@@ -1746,7 +1752,7 @@ void FloodRuleEngine::remove(const char* args, char* reply) {
|
||||
if (asciiEqual(selector, "all")) {
|
||||
Entry previous[RULE_SLOTS];
|
||||
memcpy(previous, _entries, sizeof(previous));
|
||||
memset(_entries, 0, sizeof(_entries));
|
||||
memset(_entries, 0, sizeof(Entry) * RULE_SLOTS);
|
||||
if (!save()) {
|
||||
memcpy(_entries, previous, sizeof(_entries));
|
||||
copyString(reply, "Err - unable to save flood filter", 160);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Mesh.h>
|
||||
#include <new>
|
||||
|
||||
#include <helpers/IdentityStore.h>
|
||||
#include <helpers/RegionMap.h>
|
||||
@@ -71,9 +72,16 @@ private:
|
||||
bool rate_window_active;
|
||||
};
|
||||
|
||||
// This table is 6,200 bytes. Keep it in the constructor-time heap rather
|
||||
// than inside the global MyMesh object: classic ESP32 has a small static
|
||||
// DRAM window but substantially more internal heap at this point in boot.
|
||||
// Allocation is deliberately all-or-nothing. A node must never fall back
|
||||
// to silently running without its configured flood rules.
|
||||
static_assert(sizeof(Entry) == 200,
|
||||
"Update the flood-rule runtime RAM budget in check_firmware_ram.py");
|
||||
FILESYSTEM* _fs;
|
||||
RegionMap* _regions;
|
||||
Entry _entries[RULE_SLOTS];
|
||||
Entry* _entries;
|
||||
|
||||
void seedDefaults();
|
||||
void load();
|
||||
|
||||
@@ -98,11 +98,22 @@ def requirements(platform, defines, target):
|
||||
engine = integer(defines, "MESH_ENABLE_FLOOD_RULE_ENGINE", int(platform != "STM32_PLATFORM"))
|
||||
slots = integer(defines, "FLOOD_PACKET_FILTER_SLOTS", 63 if engine else 16)
|
||||
parts["flood_filter_table"] = slots * (200 if engine else 40) + 16
|
||||
if "room_server" in target.lower() and integer(
|
||||
defines, "MESH_ENABLE_ROOM_FLOOD_RULE_ENGINE", 0):
|
||||
# FloodRuleEngine keeps all 31 persisted rules in one startup heap
|
||||
# allocation. Its C++ assertion pins Entry to the budgeted 200 bytes.
|
||||
parts["room_flood_rule_table"] = 31 * 200 + 16
|
||||
if "ENABLE_OTA" in defines and "OTA_HEAP_CONTEXT" in defines:
|
||||
parts["ota_context"] = 16384 + 16
|
||||
if display and display != "NullDisplayDriver":
|
||||
parts["display_pixels_and_driver"] = display_heap
|
||||
parts["screen_objects_and_history"] = 8192 if companion else 2048
|
||||
screen_budget = integer(defines, "MESH_COMPANION_SCREEN_STARTUP_BYTES", 0)
|
||||
if companion and screen_budget:
|
||||
# A target using this override has a source-side static assertion
|
||||
# that covers its concrete startup screens and allocator overhead.
|
||||
parts["screen_objects_and_history"] = screen_budget
|
||||
else:
|
||||
parts["screen_objects_and_history"] = 8192 if companion else 2048
|
||||
if companion:
|
||||
# ui-new retains 32 previews in one heap allocation. The baseline
|
||||
# covers 78 bytes per message; budget larger buffers explicitly,
|
||||
@@ -113,7 +124,7 @@ def requirements(platform, defines, target):
|
||||
small_font = integer(defines, "UI_SMALL_MESSAGE_FONT", int(small_display))
|
||||
default_preview = 161 if small_font else 78
|
||||
extra = max(0, integer(defines, "UI_MSG_PREVIEW_SIZE", default_preview) - 78)
|
||||
if extra:
|
||||
if extra and not screen_budget:
|
||||
parts["expanded_message_previews"] = 32 * ((extra + 7) // 8) * 8
|
||||
parts["allocation_and_transient_margin"] = 16384 if platform == "ESP32_PLATFORM" else 4096
|
||||
required = sum(parts.values())
|
||||
@@ -124,7 +135,8 @@ def requirements(platform, defines, target):
|
||||
largest = max(display_heap, parts["radio_packet_pool"], 8192 if platform == "ESP32_PLATFORM" else 0)
|
||||
if "expanded_message_previews" in parts:
|
||||
largest = max(largest, 8192 + parts["expanded_message_previews"])
|
||||
for name in ("client_table", "flood_filter_table", "ota_context"):
|
||||
for name in ("client_table", "flood_filter_table", "room_flood_rule_table",
|
||||
"ota_context", "screen_objects_and_history"):
|
||||
largest = max(largest, parts.get(name, 0))
|
||||
return {"required_heap_bytes": required, "required_contiguous_bytes": largest,
|
||||
"components": parts, "display": display, "full_companion": full}
|
||||
|
||||
@@ -151,7 +151,7 @@ void SerialBLEInterface::enable() {
|
||||
if (_isEnabled) return;
|
||||
_isEnabled = true;
|
||||
clearBuffers();
|
||||
BLE.startAdvertising(true);
|
||||
BLE.startAdvertising();
|
||||
}
|
||||
|
||||
void SerialBLEInterface::disconnect() {
|
||||
|
||||
@@ -421,6 +421,9 @@ extends = env:heltec_tracker_v2_companion_radio_wifi_femon
|
||||
board_build.flash_mode = ${esp32_s3_full.board_build.flash_mode}
|
||||
build_flags =
|
||||
${env:heltec_tracker_v2_companion_radio_wifi_femon.build_flags}
|
||||
; Bound by the ui-new source assertion: Splash + Home + full 32-message
|
||||
; preview history and ESP32 allocator overhead, without reducing UI state.
|
||||
-D MESH_COMPANION_SCREEN_STARTUP_BYTES=9808
|
||||
-D MESHCORE_REQUIRES_COMPANION_RADIO_FULL=1
|
||||
|
||||
[env:heltec_tracker_v2_companion_radio_wifi_femoff]
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
[LilyGo_TBeam_SX1262]
|
||||
extends = esp32_base
|
||||
board = ttgo-t-beam
|
||||
; MeshCore and its source-built dependencies do not throw C++ exceptions.
|
||||
; Avoid linking the unused exception runtime and use the supported compact
|
||||
; ROM formatter so the feature-complete dual-OTA observer remains deployable.
|
||||
build_unflags =
|
||||
-fexceptions
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-fno-exceptions
|
||||
-D PORTABLE_ESP32_ROM_NANO_FORMAT=1
|
||||
-I variants/lilygo_tbeam_SX1262
|
||||
-D TBEAM_SX1262
|
||||
-D P_LORA_DIO_0=26
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
[LilyGo_TBeam_SX1276]
|
||||
extends = esp32_base
|
||||
board = ttgo-t-beam
|
||||
; MeshCore and its source-built dependencies do not throw C++ exceptions.
|
||||
; Avoid linking the unused exception runtime and use the supported compact
|
||||
; ROM formatter so the feature-complete dual-OTA observer remains deployable.
|
||||
build_unflags =
|
||||
-fexceptions
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-fno-exceptions
|
||||
-D PORTABLE_ESP32_ROM_NANO_FORMAT=1
|
||||
-I variants/lilygo_tbeam_SX1276
|
||||
-D TBEAM_SX1276
|
||||
-D P_LORA_DIO_0=26
|
||||
|
||||
@@ -122,7 +122,9 @@ build_src_filter = ${rpi_picow.build_src_filter}
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
lib_deps = ${rpi_picow.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
lib_ignore = BLE
|
||||
lib_ignore =
|
||||
${rp2040_base.lib_ignore}
|
||||
BLE
|
||||
|
||||
[env:PicoW_terminal_chat]
|
||||
extends = rpi_picow
|
||||
|
||||
@@ -49,6 +49,9 @@ build_flags =
|
||||
; G2 roles remain below each legacy 0x140000 (1.25 MiB) application slot.
|
||||
-D LIGHTWEIGHT_WIFI_OTA=1
|
||||
-D WEBCONFIG_DISABLED=1
|
||||
; The ESP32-S3 ROM formatter preserves the normal libc ABI while keeping
|
||||
; the complete portable LoRa-OTA repeater inside its legacy app slot.
|
||||
-D PORTABLE_ESP32_ROM_NANO_FORMAT=1
|
||||
build_src_filter = ${esp32_base.build_src_filter}
|
||||
+<../variants/station_g2>
|
||||
+<helpers/sensors>
|
||||
|
||||
Reference in new issue
Block a user