mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-30 16:20:24 +00:00
btstack_run_loop_freertos: implement execute on main thread
This commit is contained in:
parent
38b6e83679
commit
c51a1d5a2d
@ -67,6 +67,7 @@
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "event_groups.h"
|
||||
#include "semphr.h"
|
||||
#endif
|
||||
|
||||
typedef struct function_call {
|
||||
@ -90,10 +91,12 @@ typedef struct function_call {
|
||||
#ifdef USE_STATIC_ALLOC
|
||||
static StaticQueue_t btstack_run_loop_queue_object;
|
||||
static uint8_t btstack_run_loop_queue_storage[ RUN_LOOP_QUEUE_LENGTH * RUN_LOOP_QUEUE_ITEM_SIZE ];
|
||||
static StaticSemaphore_t btstack_run_loop_callback_mutex_object;
|
||||
#endif
|
||||
|
||||
static QueueHandle_t btstack_run_loop_queue;
|
||||
static TaskHandle_t btstack_run_loop_task;
|
||||
static SemaphoreHandle_t btstack_run_loop_callbacks_mutex;
|
||||
|
||||
#ifndef HAVE_FREERTOS_TASK_NOTIFICATIONS
|
||||
static EventGroupHandle_t btstack_run_loop_event_group;
|
||||
@ -114,8 +117,7 @@ static void btstack_run_loop_freertos_set_timer(btstack_timer_source_t *ts, uint
|
||||
ts->timeout = btstack_run_loop_freertos_get_time_ms() + timeout_in_ms + 1;
|
||||
}
|
||||
|
||||
// schedules execution from regular thread
|
||||
void btstack_run_loop_freertos_trigger(void){
|
||||
static void btstack_run_loop_freertos_trigger_from_thread(void){
|
||||
#ifdef HAVE_FREERTOS_TASK_NOTIFICATIONS
|
||||
xTaskNotify(btstack_run_loop_task, EVENT_GROUP_FLAG_RUN_LOOP, eSetBits);
|
||||
#else
|
||||
@ -123,24 +125,6 @@ void btstack_run_loop_freertos_trigger(void){
|
||||
#endif
|
||||
}
|
||||
|
||||
void btstack_run_loop_freertos_execute_code_on_main_thread(void (*fn)(void *arg), void * arg){
|
||||
|
||||
// directly call function if already on btstack task
|
||||
if (xTaskGetCurrentTaskHandle() == btstack_run_loop_task){
|
||||
(*fn)(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
function_call_t message;
|
||||
message.fn = fn;
|
||||
message.arg = arg;
|
||||
BaseType_t res = xQueueSendToBack(btstack_run_loop_queue, &message, 0); // portMAX_DELAY);
|
||||
if (res != pdTRUE){
|
||||
log_error("Failed to post fn %p", fn);
|
||||
}
|
||||
btstack_run_loop_freertos_trigger();
|
||||
}
|
||||
|
||||
#if defined(HAVE_FREERTOS_TASK_NOTIFICATIONS) || (INCLUDE_xEventGroupSetBitFromISR == 1)
|
||||
static void btstack_run_loop_freertos_poll_data_sources_from_irq(void){
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
@ -157,19 +141,12 @@ static void btstack_run_loop_freertos_poll_data_sources_from_irq(void){
|
||||
xEventGroupSetBitsFromISR(btstack_run_loop_event_group, EVENT_GROUP_FLAG_RUN_LOOP, &xHigherPriorityTaskWoken);
|
||||
#endif
|
||||
}
|
||||
void btstack_run_loop_freertos_trigger_from_isr(void){
|
||||
btstack_run_loop_freertos_trigger_from_isr();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void btstack_run_loop_freertos_trigger_exit_internal(void){
|
||||
run_loop_exit_requested = true;
|
||||
}
|
||||
|
||||
void btstack_run_loop_freertos_trigger_exit(void){
|
||||
btstack_run_loop_freertos_trigger_exit_internal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute run_loop
|
||||
*/
|
||||
@ -183,7 +160,18 @@ static void btstack_run_loop_freertos_execute(void) {
|
||||
// process data sources
|
||||
btstack_run_loop_base_poll_data_sources();
|
||||
|
||||
// process registered function calls on run loop thread
|
||||
// execute callbacks - protect list with mutex
|
||||
while (1){
|
||||
xSemaphoreTake(btstack_run_loop_callbacks_mutex, portMAX_DELAY);
|
||||
btstack_context_callback_registration_t * callback_registration = (btstack_context_callback_registration_t *) btstack_linked_list_pop(&btstack_run_loop_base_callbacks);
|
||||
xSemaphoreGive(btstack_run_loop_callbacks_mutex);
|
||||
if (callback_registration == NULL){
|
||||
break;
|
||||
}
|
||||
(*callback_registration->callback)(callback_registration->context);
|
||||
}
|
||||
|
||||
// process registered function calls on run loop thread (deprecated)
|
||||
while (true){
|
||||
function_call_t message = { NULL, NULL };
|
||||
BaseType_t res = xQueueReceive( btstack_run_loop_queue, &message, 0);
|
||||
@ -197,7 +185,7 @@ static void btstack_run_loop_freertos_execute(void) {
|
||||
uint32_t now = btstack_run_loop_freertos_get_time_ms();
|
||||
btstack_run_loop_base_process_timers(now);
|
||||
|
||||
// exit triggered by btstack_run_loop_freertos_trigger_exit (from data source, timer, run on main thread)
|
||||
// exit triggered by btstack_run_loop_trigger_exit (main thread or other thread)
|
||||
if (run_loop_exit_requested) break;
|
||||
|
||||
// wait for timeout or event group/task notification
|
||||
@ -217,13 +205,23 @@ static void btstack_run_loop_freertos_execute(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static void btstack_run_loop_freertos_execute_on_main_thread(btstack_context_callback_registration_t * callback_registration){
|
||||
// protect list with mutex
|
||||
xSemaphoreTake(btstack_run_loop_callbacks_mutex, portMAX_DELAY);
|
||||
btstack_run_loop_base_add_callback(callback_registration);
|
||||
xSemaphoreGive(btstack_run_loop_callbacks_mutex);
|
||||
btstack_run_loop_freertos_trigger_from_thread();
|
||||
}
|
||||
|
||||
static void btstack_run_loop_freertos_init(void){
|
||||
btstack_run_loop_base_init();
|
||||
|
||||
#ifdef USE_STATIC_ALLOC
|
||||
btstack_run_loop_queue = xQueueCreateStatic(RUN_LOOP_QUEUE_LENGTH, RUN_LOOP_QUEUE_ITEM_SIZE, btstack_run_loop_queue_storage, &btstack_run_loop_queue_object);
|
||||
btstack_run_loop_mutex = xSemaphoreCreateMutexStatic(&btstack_run_loop_callback_mutex_object);
|
||||
#else
|
||||
btstack_run_loop_queue = xQueueCreate(RUN_LOOP_QUEUE_LENGTH, RUN_LOOP_QUEUE_ITEM_SIZE);
|
||||
btstack_run_loop_callbacks_mutex = xSemaphoreCreateMutex();
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FREERTOS_TASK_NOTIFICATIONS
|
||||
@ -258,10 +256,45 @@ static const btstack_run_loop_t btstack_run_loop_freertos = {
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
NULL,
|
||||
btstack_run_loop_freertos_execute_on_main_thread,
|
||||
&btstack_run_loop_freertos_trigger_exit_internal,
|
||||
};
|
||||
|
||||
const btstack_run_loop_t * btstack_run_loop_freertos_get_instance(void){
|
||||
return &btstack_run_loop_freertos;
|
||||
}
|
||||
|
||||
|
||||
// @deprecated functions
|
||||
|
||||
// schedules execution from regular thread
|
||||
void btstack_run_loop_freertos_trigger(void){
|
||||
btstack_run_loop_freertos_trigger_from_thread();
|
||||
}
|
||||
|
||||
void btstack_run_loop_freertos_execute_code_on_main_thread(void (*fn)(void *arg), void * arg){
|
||||
// directly call function if already on btstack task
|
||||
if (xTaskGetCurrentTaskHandle() == btstack_run_loop_task){
|
||||
(*fn)(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
function_call_t message;
|
||||
message.fn = fn;
|
||||
message.arg = arg;
|
||||
BaseType_t res = xQueueSendToBack(btstack_run_loop_queue, &message, 0); // portMAX_DELAY);
|
||||
if (res != pdTRUE){
|
||||
log_error("Failed to post fn %p", fn);
|
||||
}
|
||||
btstack_run_loop_freertos_trigger();
|
||||
}
|
||||
|
||||
void btstack_run_loop_freertos_trigger_exit(void){
|
||||
btstack_run_loop_freertos_trigger_exit_internal();
|
||||
}
|
||||
|
||||
#if defined(HAVE_FREERTOS_TASK_NOTIFICATIONS) || (INCLUDE_xEventGroupSetBitFromISR == 1)
|
||||
void btstack_run_loop_freertos_trigger_from_isr(void){
|
||||
btstack_run_loop_freertos_trigger_from_isr();
|
||||
}
|
||||
#endif
|
||||
|
@ -58,12 +58,16 @@ const btstack_run_loop_t * btstack_run_loop_freertos_get_instance(void);
|
||||
|
||||
/**
|
||||
* @brief Execute code on BTstack run loop. Can be used to control BTstack from a different thread
|
||||
|
||||
* @deprecated Please use btstack_run_loop_execute_on_main_thread() instead
|
||||
*/
|
||||
void btstack_run_loop_freertos_execute_code_on_main_thread(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.
|
||||
*
|
||||
* @deprecated Please use btstack_run_loop_execute_on_main_thread() instead
|
||||
*/
|
||||
void btstack_run_loop_freertos_trigger(void);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user