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 <unsigned N>
+    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 <unsigned N>
+    static task create_static(TaskFunction_t pvTaskCode,
+        const char* const pcName,
+        void* pvParameters,
+        UBaseType_t uxPriority,
+        storage<N>* 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<N>::stack_depth, "ESP-IDF indicates stack depth is bytes");
+#endif
+
+        return task(xTaskCreateStatic(pvTaskCode,
+            pcName,
+            storage<N>::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