From 44900079e91ea16ab4f0286d3326fe16aa57ac34 Mon Sep 17 00:00:00 2001 From: Malachi Burke Date: Mon, 9 Dec 2024 09:29:14 -0800 Subject: [PATCH] feat: finalizing xTaskCreateStatic wrapper https://github.com/malachi-iot/estdlib/issues/68 --- CHANGELOG.md | 1 + src/estd/port/freertos/wrapper/task.h | 41 ++++++++++++++++++++++----- test/unity/freertos.cpp | 24 ++++++++++++++-- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2314c983..2f870416 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ## Quality Updates & Bug Fixes +* https://github.com/malachi-iot/estdlib/issues/68 `freertos::wrapper::task::create_static` now truly calls `xTaskCreateStatic` * https://github.com/malachi-iot/estdlib/issues/66 `tuple.visit()` now works with references too # v0.8.1 - 31OCT24 diff --git a/src/estd/port/freertos/wrapper/task.h b/src/estd/port/freertos/wrapper/task.h index 48659f4c..a02c04bf 100644 --- a/src/estd/port/freertos/wrapper/task.h +++ b/src/estd/port/freertos/wrapper/task.h @@ -70,11 +70,6 @@ class task return pcTaskGetName(t); } - void delay(const TickType_t xTicksToDelay) const - { - vTaskDelay(xTicksToDelay); - } - void resume() const { vTaskResume(t); @@ -135,7 +130,15 @@ class task #endif #if configSUPPORT_STATIC_ALLOCATION - using static_type = StaticTask_t; + // N represents byte count, not word count + template + struct storage + { + static constexpr unsigned stack_depth = N / sizeof(StackType_t); + + StaticTask_t task; + StackType_t stack[stack_depth]; + }; static task create_static(TaskFunction_t pvTaskCode, const char* const pcName, @@ -143,7 +146,7 @@ class task void* pvParameters, UBaseType_t uxPriority, StackType_t* const puxStackBuffer, - static_type* const pxTaskBuffer) + StaticTask_t* const pxTaskBuffer) { return task(xTaskCreateStatic(pvTaskCode, pcName, uxStackDepth, @@ -151,6 +154,30 @@ class task puxStackBuffer, pxTaskBuffer)); } + + template + static task create_static(TaskFunction_t pvTaskCode, + const char* const pcName, + void* pvParameters, + UBaseType_t uxPriority, + storage* s) + { + // "The size of the task stack specified as the NUMBER OF BYTES. Note that this differs from vanilla FreeRTOS" + // https://docs.espressif.com/projects/esp-idf/en/v5.3.2/esp32/api-reference/system/freertos_idf.html + // We believe them. The penalty for stack size inaccuracy is so high we do an assert + // anyway. +#if ESP_PLATFORM + static_assert(N == storage::stack_depth, "ESP-IDF indicates stack depth is bytes"); +#endif + + return task(xTaskCreateStatic(pvTaskCode, + pcName, + storage::stack_depth, + pvParameters, uxPriority, + s->stack, + &s->task)); + } + #endif operator TaskHandle_t () const diff --git a/test/unity/freertos.cpp b/test/unity/freertos.cpp index 6bc5952f..4715f5e1 100644 --- a/test/unity/freertos.cpp +++ b/test/unity/freertos.cpp @@ -8,22 +8,40 @@ using namespace estd::freertos::wrapper; +volatile bool test_task_completed = false; + static void test_task1(void* p) { + test_task_completed = true; + + // It seems the task may need minimum one context switch otherwise + // FreeRTOS reports an improper task return + vTaskDelay(10); + vTaskDelete(nullptr); } static void test_static_task_wrapper() { // DEBT: Do a malloc for these in SPIRAM for ESP32 - static task::static_type storage; - static unsigned char stack[2048]; + static StaticTask_t storage; + static portSTACK_TYPE stack[2048]; task t = task::create_static(test_task1, "unity:freertos1", - sizeof stack / 4, nullptr, 3, stack, &storage); + (sizeof stack) / sizeof(portSTACK_TYPE), nullptr, 3, stack, &storage); t.suspend(); t.resume(); + + while(!test_task_completed) vTaskDelay(10); + + test_task_completed = false; + + static task::storage<2048> storage2; + + t = task::create_static(test_task1, "unity:freertos2", nullptr, 3, &storage2); + + while(!test_task_completed) vTaskDelay(10); } #ifdef ESP_IDF_TESTING