From 40ad9be2e8208721dd568c4e7e192ecde7986e6f Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 20 Apr 2017 18:08:34 +0200 Subject: [PATCH] freertos: wait on event group insted of queue --- ...tstack_run_loop_freertos_single_threaded.c | 38 ++++++++++++++----- ...tstack_run_loop_freertos_single_threaded.h | 10 +++++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/platform/freertos/btstack_run_loop_freertos_single_threaded.c b/platform/freertos/btstack_run_loop_freertos_single_threaded.c index 2b9b941d5..a8eff35b3 100644 --- a/platform/freertos/btstack_run_loop_freertos_single_threaded.c +++ b/platform/freertos/btstack_run_loop_freertos_single_threaded.c @@ -53,6 +53,7 @@ uint32_t hal_time_ms(void); #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" +#include "freertos/event_groups.h" typedef struct function_call { void (*fn)(void * arg); @@ -61,7 +62,11 @@ typedef struct function_call { static const btstack_run_loop_t btstack_run_loop_freertos_single_threaded; -static QueueHandle_t btstack_run_loop_queue; +static QueueHandle_t btstack_run_loop_queue; +static EventGroupHandle_t btstack_run_loop_event_group; + +// bit 0 event group reserved to wakeup run loop +#define EVENT_GROUP_FLAG_RUN_LOOP 1 // the run loop static btstack_linked_list_t timers; @@ -113,6 +118,10 @@ static void btstack_run_loop_freertos_single_threaded_dump_timer(void){ } // schedules execution from regular thread +void btstack_run_loop_freertos_trigger(void){ + xEventGroupSetBits(btstack_run_loop_event_group, EVENT_GROUP_FLAG_RUN_LOOP); +} + void btstack_run_loop_freertos_single_threaded_execute_code_on_main_thread(void (*fn)(void *arg), void * arg){ function_call_t message; message.fn = fn; @@ -121,16 +130,23 @@ void btstack_run_loop_freertos_single_threaded_execute_code_on_main_thread(void if (res != pdTRUE){ log_error("Failed to post fn %p", fn); } + btstack_run_loop_freertos_trigger(); +} + +#if (INCLUDE_xEventGroupSetBitFromISR == 1) +void btstack_run_loop_freertos_trigger_from_isr(void){ + xEventGroupSetBits(btstack_run_loop_event_group, EVENT_GROUP_FLAG_RUN_LOOP); } -// schedules execution from regular thread void btstack_run_loop_freertos_single_threaded_execute_code_on_main_thread_from_isr(void (*fn)(void *arg), void * arg){ function_call_t message; message.fn = fn; message.arg = arg; BaseType_t xHigherPriorityTaskWoken; xQueueSendToBackFromISR(btstack_run_loop_queue, &message, &xHigherPriorityTaskWoken); + btstack_run_loop_freertos_trigger_from_isr(); } +#endif /** * Execute run_loop @@ -160,17 +176,16 @@ static void btstack_run_loop_freertos_single_threaded_task(void *pvParameter){ timeout_ms = ts->timeout - now; } - // pop function call - function_call_t message = { NULL, NULL }; + // wait for timeout of event group log_debug("RL: wait with timeout %u", (int) timeout_ms); - BaseType_t res = xQueueReceive( btstack_run_loop_queue, &message, pdMS_TO_TICKS(timeout_ms)); - log_debug("RL: queue receive res %u", res); - if (res == pdPASS && message.fn){ + xEventGroupWaitBits(btstack_run_loop_event_group, EVENT_GROUP_FLAG_RUN_LOOP, 1, 0, pdMS_TO_TICKS(timeout_ms)); + + // try pop function call + function_call_t message = { NULL, NULL }; + BaseType_t res = xQueueReceive( btstack_run_loop_queue, &message, 0); + if (res == pdTRUE && message.fn){ // execute code on run loop - log_debug("RL: execute %p", message.fn); message.fn(message.arg); - } else { - log_debug("RL: just timeout"); } } } @@ -187,6 +202,9 @@ static void btstack_run_loop_freertos_single_threaded_init(void){ // queue to receive events: up to 2 calls from transport, up to 3 for app btstack_run_loop_queue = xQueueCreate(20, sizeof(function_call_t)); + // event group to wake run loop + btstack_run_loop_event_group = xEventGroupCreate(); + log_info("run loop init, queue item size %u", (int) sizeof(function_call_t)); } diff --git a/platform/freertos/btstack_run_loop_freertos_single_threaded.h b/platform/freertos/btstack_run_loop_freertos_single_threaded.h index f7fbd53c2..9d453c6ba 100644 --- a/platform/freertos/btstack_run_loop_freertos_single_threaded.h +++ b/platform/freertos/btstack_run_loop_freertos_single_threaded.h @@ -66,6 +66,16 @@ void btstack_run_loop_freertos_single_threaded_execute_code_on_main_thread(void */ void btstack_run_loop_freertos_single_threaded_execute_code_on_main_thread_from_isr(void (*fn)(void *arg), void * arg); +/** + * @brief Triggers processing of data sources from thread context. Has to be called after enabling a poll data source to wake-pup run loop. + */ +void btstack_run_loop_freertos_trigger(void); + +/** + * @brief Triggers processing of data sources from an ISR. Has to be called after enabling a poll data source to wake-pup run loop. + */ +void btstack_run_loop_freertos_trigger_from_isr(void); + /* API_END */ #if defined __cplusplus