From 7bfb747a4bf48bfe2d38240b5cf4229967be8e39 Mon Sep 17 00:00:00 2001 From: limpkin Date: Tue, 23 Dec 2025 19:41:24 +0100 Subject: [PATCH 1/2] using a unique low level semaphore to prevent simultaneous access to pixel data --- src/main.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 64f3529d..9e710b9b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -114,8 +114,7 @@ ModuleLiveScripts moduleLiveScripts = ModuleLiveScripts(&server, &esp32sveltekit ModuleChannels moduleChannels = ModuleChannels(&server, &esp32sveltekit); ModuleMoonLightInfo moduleMoonLightInfo = ModuleMoonLightInfo(&server, &esp32sveltekit); -volatile xSemaphoreHandle effectSemaphore = xSemaphoreCreateBinary(); -volatile xSemaphoreHandle driverSemaphore = xSemaphoreCreateBinary(); +volatile xSemaphoreHandle lowLevelSemaphore = xSemaphoreCreateBinary(); TaskHandle_t effectTaskHandle = NULL; TaskHandle_t driverTaskHandle = NULL; @@ -128,7 +127,7 @@ void effectTask(void* pvParameters) { for (;;) { esp32sveltekit.lps++; // 🌙 todo: not moonlight specific? - if (xSemaphoreTake(effectSemaphore, pdMS_TO_TICKS(100)) == pdFALSE) { + if (xSemaphoreTake(lowLevelSemaphore, pdMS_TO_TICKS(100)) == pdFALSE) { // EXT_LOGW(ML_TAG, "effectSemaphore wait too long"); //happens if no driver!, but let effects continue (for monitor) at 10 fps } @@ -140,7 +139,7 @@ void effectTask(void* pvParameters) { layerP.loop20ms(); } - xSemaphoreGive(driverSemaphore); + xSemaphoreGive(lowLevelSemaphore); vTaskDelay(1); // yield to other tasks, 1 tick (~1ms) } @@ -152,11 +151,11 @@ void driverTask(void* pvParameters) { // layerP.setup() done in effectTask for (;;) { - xSemaphoreTake(driverSemaphore, pdMS_TO_TICKS(100)); + xSemaphoreTake(lowLevelSemaphore, pdMS_TO_TICKS(100)); layerP.loopDrivers(); - xSemaphoreGive(effectSemaphore); + xSemaphoreGive(lowLevelSemaphore); vTaskDelay(1); // yield to other tasks, 1 tick (~1ms) } @@ -325,8 +324,6 @@ void setup() { false); #endif - xSemaphoreGive(effectSemaphore); // Allow effectTask to run first - // 🌙 xTaskCreateUniversal(effectTask, // task function "AppEffectTask", // name From bca999117c22828ba2a6dee2437bb4965e4bb18a Mon Sep 17 00:00:00 2001 From: limpkin Date: Tue, 23 Dec 2025 20:24:23 +0100 Subject: [PATCH 2/2] actually use semaphores for what they're intended --- src/main.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9e710b9b..8a143488 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -129,18 +129,20 @@ void effectTask(void* pvParameters) { if (xSemaphoreTake(lowLevelSemaphore, pdMS_TO_TICKS(100)) == pdFALSE) { // EXT_LOGW(ML_TAG, "effectSemaphore wait too long"); //happens if no driver!, but let effects continue (for monitor) at 10 fps + //EXT_LOGW(ML_TAG, "effect: semaphore wait too long"); } + else { + layerP.loop(); // run all the effects of all virtual layers (currently only one layer) - layerP.loop(); // run all the effects of all virtual layers (currently only one layer) + static unsigned long last20ms = 0; + if (millis() - last20ms >= 20) { + last20ms = millis(); + layerP.loop20ms(); + } - static unsigned long last20ms = 0; - if (millis() - last20ms >= 20) { - last20ms = millis(); - layerP.loop20ms(); + xSemaphoreGive(lowLevelSemaphore); } - xSemaphoreGive(lowLevelSemaphore); - vTaskDelay(1); // yield to other tasks, 1 tick (~1ms) } } @@ -151,12 +153,14 @@ void driverTask(void* pvParameters) { // layerP.setup() done in effectTask for (;;) { - xSemaphoreTake(lowLevelSemaphore, pdMS_TO_TICKS(100)); - - layerP.loopDrivers(); - - xSemaphoreGive(lowLevelSemaphore); + if (xSemaphoreTake(lowLevelSemaphore, pdMS_TO_TICKS(100)) == pdFALSE) { + //EXT_LOGW(ML_TAG, "driver: semaphore wait too long"); + } + else { + layerP.loopDrivers(); + xSemaphoreGive(lowLevelSemaphore); + } vTaskDelay(1); // yield to other tasks, 1 tick (~1ms) } } @@ -324,6 +328,8 @@ void setup() { false); #endif + xSemaphoreGive(lowLevelSemaphore); + // 🌙 xTaskCreateUniversal(effectTask, // task function "AppEffectTask", // name