diff --git a/examples/nucleo_f429zi/freertos_plus_tcp/main.cpp b/examples/nucleo_f429zi/freertos_static/main.cpp similarity index 70% rename from examples/nucleo_f429zi/freertos_plus_tcp/main.cpp rename to examples/nucleo_f429zi/freertos_static/main.cpp index 140167e102..6b1354b4a9 100644 --- a/examples/nucleo_f429zi/freertos_plus_tcp/main.cpp +++ b/examples/nucleo_f429zi/freertos_static/main.cpp @@ -12,16 +12,15 @@ // ---------------------------------------------------------------------------- #include -#include +#include +#include +#include using namespace modm::platform; /** * This example uses four threads to check if task switching works correctly. * - * It also check if the FreeRTOS TCP stack can be compiled. - * No TCP functionality in this example (yet). - * * What to expect? * --------------- * - All our LEDs blinking at different rates, about 3 to 4 Hz @@ -38,27 +37,43 @@ using namespace modm::platform; */ // ---------------------------------------------------------------------------- +SemaphoreHandle_t semaphore = nullptr; +StaticSemaphore_t semaphoreBuffer; + template -class P: modm::rtos::Thread +class P { char c; uint8_t i = 0; volatile float a = 10.f; + TaskHandle_t task; + StaticTask_t taskBuffer; + StackType_t stack[1024/4]; public: - P(char c): Thread(2,1<<10), c(c) {} + P(char c): c(c) + { + xTaskCreateStatic( + [](void* obj) { reinterpret_cast(obj)->run(); }, + "anon", + (1024 / 4), + this, + 2, + stack, + &taskBuffer); + } void run() { Gpio::setOutput(); while (true) { - sleep(SleepTime * MILLISECONDS); + vTaskDelay(SleepTime * (configTICK_RATE_HZ / 1000.0)); Gpio::toggle(); { - static modm::rtos::Mutex lm; - modm::rtos::MutexGuard m(lm); + xSemaphoreTake(semaphore, portMAX_DELAY); MODM_LOG_INFO << char(i + c); + xSemaphoreGive(semaphore); } i = (i+1)%10; a *= 3.141f; @@ -70,12 +85,14 @@ P< Board::LedRed, 260 > p1('0'); P< Board::LedGreen, 260 + 10 > p2('a'); P< Board::LedBlue, 260 + 20 > p3('A'); - // ---------------------------------------------------------------------------- int main() { Board::initialize(); - modm::rtos::Scheduler::schedule(); + + semaphore = xSemaphoreCreateMutexStatic(&semaphoreBuffer); + vTaskStartScheduler(); + return 0; } diff --git a/examples/nucleo_f429zi/freertos_plus_tcp/project.xml b/examples/nucleo_f429zi/freertos_static/project.xml similarity index 65% rename from examples/nucleo_f429zi/freertos_plus_tcp/project.xml rename to examples/nucleo_f429zi/freertos_static/project.xml index 395d1497f3..1d82f7d8a5 100644 --- a/examples/nucleo_f429zi/freertos_plus_tcp/project.xml +++ b/examples/nucleo_f429zi/freertos_static/project.xml @@ -1,11 +1,10 @@ modm:nucleo-f429zi - + - modm:processing:rtos - modm:freertos:tcp + modm:freertos modm:build:scons diff --git a/ext/aws/FreeRTOSConfig.h.in b/ext/aws/FreeRTOSConfig.h.in index 63bb7f0cea..85053cf4cd 100644 --- a/ext/aws/FreeRTOSConfig.h.in +++ b/ext/aws/FreeRTOSConfig.h.in @@ -48,8 +48,8 @@ your application. */ #define configCPU_CLOCK_HZ ( SystemCoreClock ) #define configTICK_RATE_HZ ( {{ frequency }} ) /* Memory allocation related definitions. */ -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION {{ 0 if with_heap else 1 }} +#define configSUPPORT_DYNAMIC_ALLOCATION {{ 1 if with_heap else 0 }} // used by modm:platform:clock for modm::Clock::increment(): vApplicationTickHook() #define configUSE_TICK_HOOK 1 diff --git a/ext/aws/freertos.md b/ext/aws/freertos.md index 2d83a7ee6c..56d3c6c340 100644 --- a/ext/aws/freertos.md +++ b/ext/aws/freertos.md @@ -25,7 +25,8 @@ these settings: - `configASSERT(x)` implemented with `modm_assert(x, "freertos")`. - `configCPU_CLOCK_HZ` implemented with CMSIS `SystemCoreClock`. - `configTICK_RATE_HZ` set to `modm:freertos:frequency` or 1kHz on Cortex-M0. -- `configSUPPORT_DYNAMIC_ALLOCATION = 1` as implemented by `modm:platform:heap`. +- `configSUPPORT_DYNAMIC_ALLOCATION = 1` only if used with `modm:platform:heap`. +- `configSUPPORT_STATIC_ALLOCATION = 1` only if used without `modm:platform:heap`. - `configUSE_TICK_HOOK = 1` used by `modm:platform:clock` to provide `modm::Clock`. In addition we define these overwritable default settings: diff --git a/ext/aws/modm_port.cpp.in b/ext/aws/modm_port.cpp.in index f35f8fa8cc..a7991925d3 100644 --- a/ext/aws/modm_port.cpp.in +++ b/ext/aws/modm_port.cpp.in @@ -20,6 +20,7 @@ void vApplicationStackOverflowHook(TaskHandle_t /*pxTask*/, char *pcTaskName) modm_assert(false, "freertos.stack", "FreeRTOS detected a stack overflow!", pcTaskName); } +%% if with_heap // ---------------------------------------------------------------------------- // Make the Newlib heap thread-safe with FreeRTOS @@ -64,6 +65,33 @@ void vPortFree(void *pv) traceFREE(pv, 0); } } +%% else +#if configUSE_TIMERS == 1 +static StaticTask_t timers_task_storage; +static StackType_t timers_task_stack_storage[configTIMER_TASK_STACK_DEPTH]; +extern "C" +void vApplicationGetTimerTaskMemory(StaticTask_t** ppxTimerTaskTCBBuffer, + StackType_t** ppxTimerTaskStackBuffer, + uint32_t* pulTimerTaskStackSize) +{ + *ppxTimerTaskTCBBuffer = &timers_task_storage; + *ppxTimerTaskStackBuffer = timers_task_stack_storage; + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} +#endif + +static StaticTask_t idle_task_storage; +static StackType_t idle_task_stack_storage[configMINIMAL_STACK_SIZE]; +extern "C" +void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer, + StackType_t** ppxIdleTaskStackBuffer, + uint32_t* pulIdleTaskStackSize) +{ + *ppxIdleTaskTCBBuffer = &idle_task_storage; + *ppxIdleTaskStackBuffer = idle_task_stack_storage; + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} +%% endif %% if with_debug #include diff --git a/ext/aws/module.lb b/ext/aws/module.lb index 5da6b250c2..40ce51bce1 100644 --- a/ext/aws/module.lb +++ b/ext/aws/module.lb @@ -82,8 +82,7 @@ def prepare(module, options): module.depends( ":architecture:assert", ":cmsis:device", - ":platform:clock", - ":platform:heap") + ":platform:clock") module.add_submodule(FreeRTOS_TCP()) @@ -95,7 +94,8 @@ def build(env): env.substitutions = { "core": core, "frequency": env.get("frequency", 1000), - "with_debug": env.has_module(":debug") + "with_debug": env.has_module(":debug"), + "with_heap": env.has_module(":platform:heap"), } path = core.replace("cortex-m", "ARM_CM").replace("+", "").replace("fd", "f").upper() path = path.replace("CM7F", "CM7/r0p1") # use subfolder for M7 diff --git a/src/modm/processing/rtos/module.lb b/src/modm/processing/rtos/module.lb index b9ddda329a..55396ea398 100644 --- a/src/modm/processing/rtos/module.lb +++ b/src/modm/processing/rtos/module.lb @@ -25,7 +25,7 @@ def prepare(module, options): return False if options[":target"].identifier["platform"] not in ["hosted"]: - module.depends(":freertos") + module.depends(":freertos",":platform:heap") return True