diff --git a/README.md b/README.md index f718271ea..bfccf84cf 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,9 @@ These examples require you to set the `FREERTOS_KERNEL_PATH` to point to the Fre App|Description ---|--- -[hello_freertos](freertos/hello_freertos) | Examples that demonstrate how run FreeRTOS and tasks on 1 or 2 cores. +[hello_freertos_one_core](freertos/hello_freertos) | Demonstrates how run FreeRTOS and tasks on one core +[hello_freertos_two_cores](freertos/hello_freertos) | Demonstrates how run FreeRTOS and tasks on two cores. +[hello_freertos_static_allocation](freertos/hello_freertos) | Demonstrates how run FreeRTOS on two cores with static RAM allocation. ### GPIO diff --git a/freertos/FreeRTOSConfig_examples_common.h b/freertos/FreeRTOSConfig_examples_common.h index 88d4ac94f..af0ec3686 100755 --- a/freertos/FreeRTOSConfig_examples_common.h +++ b/freertos/FreeRTOSConfig_examples_common.h @@ -70,8 +70,12 @@ #define configMESSAGE_BUFFER_LENGTH_TYPE size_t /* Memory allocation related definitions. */ +#ifndef configSUPPORT_STATIC_ALLOCATION #define configSUPPORT_STATIC_ALLOCATION 0 +#endif +#ifndef configSUPPORT_DYNAMIC_ALLOCATION #define configSUPPORT_DYNAMIC_ALLOCATION 1 +#endif #define configTOTAL_HEAP_SIZE (128*1024) #define configAPPLICATION_ALLOCATED_HEAP 0 diff --git a/freertos/hello_freertos/CMakeLists.txt b/freertos/hello_freertos/CMakeLists.txt index 1da0ce773..a96d34a25 100644 --- a/freertos/hello_freertos/CMakeLists.txt +++ b/freertos/hello_freertos/CMakeLists.txt @@ -1,42 +1,74 @@ -set(TARGET_NAME hello_freertos1) -add_executable(${TARGET_NAME} +# Example running FreeRTOS on 1 core +add_executable(hello_freertos_one_core hello_freertos.c ) -target_include_directories(${TARGET_NAME} PRIVATE +target_include_directories(hello_freertos_one_core PRIVATE ${CMAKE_CURRENT_LIST_DIR}/.. ) -target_link_libraries(${TARGET_NAME} PRIVATE +# Linking to FreeRTOS-Kernel-Heap4 means we use a dynamic heap for allocations +target_link_libraries(hello_freertos_one_core PRIVATE pico_async_context_freertos FreeRTOS-Kernel-Heap4 pico_stdlib ) +# Set the nunber of cores to 1. +# This defaults to 2 in FreeRTOSConfig_examples_common.h if not defined in here +target_compile_definitions(hello_freertos_one_core PRIVATE + configNUMBER_OF_CORES=1 + ) if(PICO_CYW43_SUPPORTED) # For led support on pico_w - target_link_libraries(${TARGET_NAME} PRIVATE + target_link_libraries(hello_freertos_one_core PRIVATE pico_cyw43_arch_none - ) + ) endif() -target_compile_definitions(${TARGET_NAME} PRIVATE - configNUMBER_OF_CORES=1 - ) -pico_add_extra_outputs(${TARGET_NAME}) +pico_add_extra_outputs(hello_freertos_one_core) -set(TARGET_NAME hello_freertos2) -add_executable(${TARGET_NAME} +# Example running FreeRTOS on 2 cores +add_executable(hello_freertos_two_cores hello_freertos.c ) -target_include_directories(${TARGET_NAME} PRIVATE +target_include_directories(hello_freertos_two_cores PRIVATE ${CMAKE_CURRENT_LIST_DIR}/.. ) -target_link_libraries(${TARGET_NAME} PRIVATE +# Linking to FreeRTOS-Kernel-Heap4 to use a dynamic heap for allocations +target_link_libraries(hello_freertos_two_cores PRIVATE pico_async_context_freertos FreeRTOS-Kernel-Heap4 pico_stdlib ) if(PICO_CYW43_SUPPORTED) # For led support on pico_w - target_link_libraries(${TARGET_NAME} PRIVATE + target_link_libraries(hello_freertos_two_cores PRIVATE pico_cyw43_arch_none + ) +endif() +pico_add_extra_outputs(hello_freertos_two_cores) + +# Example running FreeRTOS on 2 cores with static RAM allocation +add_executable(hello_freertos_static_allocation + hello_freertos.c ) +target_include_directories(hello_freertos_static_allocation PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/.. + ) +# Linking to FreeRTOS-Kernel-Static to use static memory instead of a dynamic heap for allocations +target_link_libraries(hello_freertos_static_allocation PRIVATE + pico_async_context_freertos + FreeRTOS-Kernel-Static + pico_stdlib + ) +# Change the configuration to just use static RAM allocation +# If configSUPPORT_DYNAMIC_ALLOCATION is left undefined it will default to 1 +# If configSUPPORT_STATIC_ALLOCATION is left undefined it will default to 0 +target_compile_definitions(hello_freertos_static_allocation PRIVATE + configSUPPORT_STATIC_ALLOCATION=1 + configSUPPORT_DYNAMIC_ALLOCATION=0 + ) +if(PICO_CYW43_SUPPORTED) + # For led support on pico_w + target_link_libraries(hello_freertos_static_allocation PRIVATE + pico_cyw43_arch_none + ) endif() -pico_add_extra_outputs(${TARGET_NAME}) +pico_add_extra_outputs(hello_freertos_static_allocation) diff --git a/freertos/hello_freertos/hello_freertos.c b/freertos/hello_freertos/hello_freertos.c index 77a3c8490..af500155e 100755 --- a/freertos/hello_freertos/hello_freertos.c +++ b/freertos/hello_freertos/hello_freertos.c @@ -48,10 +48,14 @@ static async_context_freertos_t async_context_instance; // Create an async context -static async_context_t *example_async_context(void) { +static async_context_t *create_async_context(void) { async_context_freertos_config_t config = async_context_freertos_default_config(); config.task_priority = WORKER_TASK_PRIORITY; // defaults to ASYNC_CONTEXT_DEFAULT_FREERTOS_TASK_PRIORITY config.task_stack_size = WORKER_TASK_STACK_SIZE; // defaults to ASYNC_CONTEXT_DEFAULT_FREERTOS_TASK_STACK_SIZE +#if configSUPPORT_STATIC_ALLOCATION + static StackType_t async_context_freertos_task_stack[WORKER_TASK_STACK_SIZE]; + config.task_stack = async_context_freertos_task_stack; +#endif if (!async_context_freertos_init(&async_context_instance, &config)) return NULL; return &async_context_instance.core; @@ -59,7 +63,7 @@ static async_context_t *example_async_context(void) { #if USE_LED // Turn led on or off -static void pico_set_led(bool led_on) { +static void set_led(bool led_on) { #if defined PICO_DEFAULT_LED_PIN gpio_put(PICO_DEFAULT_LED_PIN, led_on); #elif defined(CYW43_WL_GPIO_LED_PIN) @@ -68,20 +72,20 @@ static void pico_set_led(bool led_on) { } // Initialise led -static void pico_init_led(void) { +static void init_led(void) { #if defined PICO_DEFAULT_LED_PIN gpio_init(PICO_DEFAULT_LED_PIN); gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); #elif defined(CYW43_WL_GPIO_LED_PIN) hard_assert(cyw43_arch_init() == PICO_OK); - pico_set_led(false); // make sure cyw43 is started + set_led(false); // make sure cyw43 is started #endif } void blink_task(__unused void *params) { bool on = false; printf("blink_task starts\n"); - pico_init_led(); + init_led(); while (true) { #if configNUMBER_OF_CORES > 1 static int last_core_id = -1; @@ -90,7 +94,7 @@ void blink_task(__unused void *params) { printf("blink task is on core %d\n", last_core_id); } #endif - pico_set_led(on); + set_led(on); on = !on; #if LED_BUSY_WAIT @@ -122,13 +126,20 @@ static void do_work(async_context_t *context, async_at_time_worker_t *worker) { async_at_time_worker_t worker_timeout = { .do_work = do_work }; void main_task(__unused void *params) { - async_context_t *context = example_async_context(); + async_context_t *context = create_async_context(); // start the worker running async_context_add_at_time_worker_in_ms(context, &worker_timeout, 0); #if USE_LED // start the led blinking +#if configSUPPORT_STATIC_ALLOCATION + static StackType_t blink_stack[BLINK_TASK_STACK_SIZE]; + static StaticTask_t blink_buf; + xTaskCreateStatic(blink_task, "BlinkThread", BLINK_TASK_STACK_SIZE, NULL, BLINK_TASK_PRIORITY, blink_stack, &blink_buf); +#else + static_assert(configSUPPORT_DYNAMIC_ALLOCATION, ""); xTaskCreate(blink_task, "BlinkThread", BLINK_TASK_STACK_SIZE, NULL, BLINK_TASK_PRIORITY, NULL); -#endif +#endif // configSUPPORT_STATIC_ALLOCATION +#endif // USE_LED int count = 0; while(true) { #if configNUMBER_OF_CORES > 1 @@ -146,11 +157,19 @@ void main_task(__unused void *params) { void vLaunch( void) { TaskHandle_t task; +#if configSUPPORT_STATIC_ALLOCATION + static StackType_t main_stack[MAIN_TASK_STACK_SIZE]; + static StaticTask_t main_buf; + task = xTaskCreateStatic(main_task, "MainThread", MAIN_TASK_STACK_SIZE, NULL, MAIN_TASK_PRIORITY, main_stack, &main_buf); +#else + static_assert(configSUPPORT_DYNAMIC_ALLOCATION, ""); xTaskCreate(main_task, "MainThread", MAIN_TASK_STACK_SIZE, NULL, MAIN_TASK_PRIORITY, &task); - +#endif // configSUPPORT_STATIC_ALLOCATION #if configUSE_CORE_AFFINITY && configNUMBER_OF_CORES > 1 // we must bind the main task to one core (well at least while the init is called) vTaskCoreAffinitySet(task, 1); +#else + (void)task; #endif /* Start the tasks and timer running. */