1 /* 2 * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _PICO_ASYNC_CONTEXT_FREERTOS_H 8 #define _PICO_ASYNC_CONTEXT_FREERTOS_H 9 10 /** \file pico/async_context.h 11 * \defgroup async_context_freertos async_context_freertos 12 * \ingroup pico_async_context 13 * 14 * async_context_freertos provides an implementation of \ref async_context that handles asynchronous 15 * work in a separate FreeRTOS task. 16 */ 17 #include "pico/async_context.h" 18 19 // FreeRTOS includes 20 #include "FreeRTOS.h" 21 #include "semphr.h" 22 #include "timers.h" 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 #ifndef ASYNC_CONTEXT_DEFAULT_FREERTOS_TASK_PRIORITY 29 #define ASYNC_CONTEXT_DEFAULT_FREERTOS_TASK_PRIORITY ( tskIDLE_PRIORITY + 4) 30 #endif 31 32 #ifndef ASYNC_CONTEXT_DEFAULT_FREERTOS_TASK_STACK_SIZE 33 #define ASYNC_CONTEXT_DEFAULT_FREERTOS_TASK_STACK_SIZE configMINIMAL_STACK_SIZE 34 #endif 35 36 typedef struct async_context_freertos async_context_freertos_t; 37 38 /** 39 * \brief Configuration object for async_context_freertos instances. 40 */ 41 typedef struct async_context_freertos_config { 42 /** 43 * Task priority for the async_context task 44 */ 45 UBaseType_t task_priority; 46 /** 47 * Stack size for the async_context task 48 */ 49 configSTACK_DEPTH_TYPE task_stack_size; 50 /** 51 * the core ID (see \ref portGET_CORE_ID()) to pin the task to. 52 * This is only relevant in SMP mode. 53 */ 54 #if configUSE_CORE_AFFINITY && configNUM_CORES > 1 55 UBaseType_t task_core_id; 56 #endif 57 } async_context_freertos_config_t; 58 59 struct async_context_freertos { 60 async_context_t core; 61 SemaphoreHandle_t lock_mutex; 62 SemaphoreHandle_t work_needed_sem; 63 TimerHandle_t timer_handle; 64 TaskHandle_t task_handle; 65 uint8_t nesting; 66 volatile bool task_should_exit; 67 }; 68 69 /*! 70 * \brief Initialize an async_context_freertos instance using the specified configuration 71 * \ingroup async_context_freertos 72 * 73 * If this method succeeds (returns true), then the async_context is available for use 74 * and can be de-initialized by calling async_context_deinit(). 75 * 76 * \param self a pointer to async_context_freertos structure to initialize 77 * \param config the configuration object specifying characteristics for the async_context 78 * \return true if initialization is successful, false otherwise 79 */ 80 bool async_context_freertos_init(async_context_freertos_t *self, async_context_freertos_config_t *config); 81 82 /*! 83 * \brief Return a copy of the default configuration object used by \ref async_context_freertos_init_with_defaults() 84 * \ingroup async_context_freertos 85 * 86 * The caller can then modify just the settings it cares about, and call \ref async_context_freertos_init() 87 * \return the default configuration object 88 */ async_context_freertos_default_config(void)89 static inline async_context_freertos_config_t async_context_freertos_default_config(void) { 90 async_context_freertos_config_t config = { 91 .task_priority = ASYNC_CONTEXT_DEFAULT_FREERTOS_TASK_PRIORITY, 92 .task_stack_size = ASYNC_CONTEXT_DEFAULT_FREERTOS_TASK_STACK_SIZE, 93 #if configUSE_CORE_AFFINITY && configNUM_CORES > 1 94 .task_core_id = (UBaseType_t)-1, // none 95 #endif 96 }; 97 return config; 98 99 } 100 101 /*! 102 * \brief Initialize an async_context_freertos instance with default values 103 * \ingroup async_context_freertos 104 * 105 * If this method succeeds (returns true), then the async_context is available for use 106 * and can be de-initialized by calling async_context_deinit(). 107 * 108 * \param self a pointer to async_context_freertos structure to initialize 109 * \return true if initialization is successful, false otherwise 110 */ async_context_freertos_init_with_defaults(async_context_freertos_t * self)111 static inline bool async_context_freertos_init_with_defaults(async_context_freertos_t *self) { 112 async_context_freertos_config_t config = async_context_freertos_default_config(); 113 return async_context_freertos_init(self, &config); 114 } 115 116 #ifdef __cplusplus 117 } 118 #endif 119 120 #endif 121