diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index cd3b2e86e6..1ec86be526 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -3,6 +3,11 @@ #include "MyMesh.h" +#if defined(NRF52_PLATFORM) +#include +static void meshAppLoop(); // forward decl: setup() passes it to startMeshWorker() +#endif + #ifdef DISPLAY_CLASS #include "UITask.h" static UITask ui_task(display); @@ -105,9 +110,16 @@ void setup() { #endif board.onBootComplete(); + +#if defined(NRF52_PLATFORM) + if (!startMeshWorker(meshAppLoop)) { + MESH_DEBUG_PRINTLN("Failed to start mesh worker task!"); + halt(); + } +#endif } -void loop() { +static void meshAppLoop() { board.loop(); int len = strlen(command); @@ -172,3 +184,11 @@ void loop() { #endif } } + +void loop() { +#if defined(NRF52_PLATFORM) + vTaskDelay(pdMS_TO_TICKS(1000)); // app loop runs on the dedicated mesh worker task +#else + meshAppLoop(); +#endif +} diff --git a/examples/simple_room_server/main.cpp b/examples/simple_room_server/main.cpp index c413ff6102..fe41f38078 100644 --- a/examples/simple_room_server/main.cpp +++ b/examples/simple_room_server/main.cpp @@ -3,6 +3,11 @@ #include "MyMesh.h" +#if defined(NRF52_PLATFORM) +#include +static void meshAppLoop(); // forward decl: setup() passes it to startMeshWorker() +#endif + #ifdef DISPLAY_CLASS #include "UITask.h" static UITask ui_task(display); @@ -82,9 +87,16 @@ void setup() { #endif board.onBootComplete(); + +#if defined(NRF52_PLATFORM) + if (!startMeshWorker(meshAppLoop)) { + MESH_DEBUG_PRINTLN("Failed to start mesh worker task!"); + halt(); + } +#endif } -void loop() { +static void meshAppLoop() { board.loop(); int len = strlen(command); @@ -118,3 +130,11 @@ void loop() { #endif rtc_clock.tick(); } + +void loop() { +#if defined(NRF52_PLATFORM) + vTaskDelay(pdMS_TO_TICKS(1000)); // app loop runs on the dedicated mesh worker task +#else + meshAppLoop(); +#endif +} diff --git a/src/helpers/MeshWorkerTask.cpp b/src/helpers/MeshWorkerTask.cpp new file mode 100644 index 0000000000..db67acd204 --- /dev/null +++ b/src/helpers/MeshWorkerTask.cpp @@ -0,0 +1,38 @@ +#include "MeshWorkerTask.h" + +#if defined(NRF52_PLATFORM) +#include +#include // MESH_DEBUG_PRINTLN +#include +#include + +static TaskHandle_t _meshTaskHandle = nullptr; +static void (*_meshLoopBody)() = nullptr; + +static void mesh_worker_task(void*) { + for (;;) { + if (_meshLoopBody) _meshLoopBody(); + vTaskDelay(1); // yield at least one tick (tick-rate independent) + } +} + +bool startMeshWorker(void (*loopBody)()) { + if (loopBody == nullptr) { + MESH_DEBUG_PRINTLN("startMeshWorker: null loopBody"); + return false; + } + if (_meshTaskHandle != nullptr) { + MESH_DEBUG_PRINTLN("startMeshWorker: already started"); + return false; + } + _meshLoopBody = loopBody; + // 2048 words = 8KB stack (measured peak ~4.7KB + headroom). + // TASK_PRIO_LOW (1) matches the framework's own loop_task priority. + if (xTaskCreate(mesh_worker_task, "mesh", 2048, NULL, TASK_PRIO_LOW, &_meshTaskHandle) != pdPASS) { + MESH_DEBUG_PRINTLN("startMeshWorker: xTaskCreate failed (out of FreeRTOS heap?)"); + _meshTaskHandle = nullptr; + return false; + } + return true; +} +#endif diff --git a/src/helpers/MeshWorkerTask.h b/src/helpers/MeshWorkerTask.h new file mode 100644 index 0000000000..aa4583b73f --- /dev/null +++ b/src/helpers/MeshWorkerTask.h @@ -0,0 +1,13 @@ +#pragma once + +#if defined(NRF52_PLATFORM) +// Run an application loop body on a dedicated FreeRTOS task with an 8KB stack, +// instead of the Adafruit_nRF52_Arduino framework's Arduino loop_task (whose 4KB +// stack -- LOOP_STACK_SZ = 256*4, an unconditional #define that build flags can't +// override -- is too small for LittleFS file opens done from loop(), e.g. +// ClientACL::saveSessionKeys, which overflow it and corrupt adjacent heap). +// +// Definitions live in MeshWorkerTask.cpp so there is a single shared instance. +// Returns true if the task was created, false on FreeRTOS heap exhaustion. +bool startMeshWorker(void (*loopBody)()); +#endif