tinyusb
osal_freeRTOS.h
Go to the documentation of this file.
1 /**************************************************************************/
37 /**************************************************************************/
38 
44 #ifndef _TUSB_OSAL_FREERTOS_H_
45 #define _TUSB_OSAL_FREERTOS_H_
46 
47 #include "osal_common.h"
48 
49 //------------- FreeRTOS Headers -------------//
50 #include "FreeRTOS.h"
51 #include "semphr.h"
52 #include "queue.h"
53 #include "task.h"
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 //--------------------------------------------------------------------+
60 // TICK API
61 //--------------------------------------------------------------------+
62 #define osal_tick_get xTaskGetTickCount
63 
64 //--------------------------------------------------------------------+
65 // TASK API
66 //--------------------------------------------------------------------+
67 #define OSAL_TASK_FUNCTION portTASK_FUNCTION
68 
69 typedef struct {
70  char const * name;
71  pdTASK_CODE code;
72  unsigned portSHORT stack_depth;
73  unsigned portBASE_TYPE prio;
74 } osal_task_t;
75 
76 #define OSAL_TASK_DEF(task_code, task_stack_depth, task_prio) \
77  osal_task_t osal_task_def_##task_code = {\
78  .name = #task_code , \
79  .code = task_code , \
80  .stack_depth = task_stack_depth , \
81  .prio = task_prio \
82  }
83 
84 #define OSAL_TASK_REF(name) (&osal_task_def_##name)
85 
86 static inline tusb_error_t osal_task_create(osal_task_t *task) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
87 static inline tusb_error_t osal_task_create(osal_task_t *task)
88 {
89  return pdPASS == xTaskCreate(task->code, (signed portCHAR const *) task->name, task->stack_depth, NULL, task->prio, NULL) ?
90  TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TASK_CREATE_FAILED;
91 }
92 
93 static inline void osal_task_delay(uint32_t msec) ATTR_ALWAYS_INLINE;
94 static inline void osal_task_delay(uint32_t msec)
95 {
96  vTaskDelay( (TUSB_CFG_TICKS_HZ * msec) / 1000 );
97 }
98 
99 //--------------------------------------------------------------------+
100 // Semaphore API
101 //--------------------------------------------------------------------+
102 #define OSAL_SEM_DEF(name)
103 typedef xSemaphoreHandle osal_semaphore_handle_t;
104 
105 // create FreeRTOS binary semaphore with zero as init value TODO: omit semaphore take from vSemaphoreCreateBinary API, should double checks this
106 #define osal_semaphore_create(x) \
107  xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
108 
109 // TODO add timeout (with instant return from ISR option) for semaphore post & queue send
110 static inline tusb_error_t osal_semaphore_post(osal_semaphore_handle_t const sem_hdl) ATTR_ALWAYS_INLINE;
111 static inline tusb_error_t osal_semaphore_post(osal_semaphore_handle_t const sem_hdl)
112 {
113  portBASE_TYPE task_waken;
114  return (xSemaphoreGiveFromISR(sem_hdl, &task_waken) == pdTRUE) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_SEMAPHORE_FAILED;
115 }
116 
117 static inline void osal_semaphore_wait(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error) ATTR_ALWAYS_INLINE;
118 static inline void osal_semaphore_wait(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error)
119 {
120  (*p_error) = ( xSemaphoreTake(sem_hdl, osal_tick_from_msec(msec)) == pdPASS ) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT;
121 }
122 
123 static inline void osal_semaphore_reset(osal_semaphore_handle_t const sem_hdl) ATTR_ALWAYS_INLINE;
124 static inline void osal_semaphore_reset(osal_semaphore_handle_t const sem_hdl)
125 {
126  portBASE_TYPE task_waken;
127  xSemaphoreTakeFromISR(sem_hdl, &task_waken);
128 }
129 
130 //--------------------------------------------------------------------+
131 // MUTEX API (priority inheritance)
132 //--------------------------------------------------------------------+
133 #define OSAL_MUTEX_DEF OSAL_SEM_DEF
134 typedef xSemaphoreHandle osal_mutex_handle_t;
135 
136 #define osal_mutex_create(x) \
137  xSemaphoreCreateMutex()
138 
139 static inline tusb_error_t osal_mutex_release(osal_mutex_handle_t const mutex_hdl) ATTR_ALWAYS_INLINE;
140 static inline tusb_error_t osal_mutex_release(osal_mutex_handle_t const mutex_hdl)
141 {
142  return (xSemaphoreGive(mutex_hdl) == pdPASS) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_MUTEX_FAILED;
143 }
144 
145 static inline void osal_mutex_wait(osal_mutex_handle_t const mutex_hdl, uint32_t msec, tusb_error_t *p_error) ATTR_ALWAYS_INLINE;
146 static inline void osal_mutex_wait(osal_mutex_handle_t const mutex_hdl, uint32_t msec, tusb_error_t *p_error)
147 {
148  (*p_error) = ( xSemaphoreTake(mutex_hdl, osal_tick_from_msec(msec)) == pdPASS ) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT;
149 }
150 
151 static inline void osal_mutex_reset(osal_mutex_handle_t const mutex_hdl) ATTR_ALWAYS_INLINE;
152 static inline void osal_mutex_reset(osal_mutex_handle_t const mutex_hdl)
153 {
154  xSemaphoreGive(mutex_hdl);
155 }
156 
157 //--------------------------------------------------------------------+
158 // QUEUE API
159 //--------------------------------------------------------------------+
160 typedef struct{
161  uint8_t const depth;
162  uint8_t const item_size;
163 } osal_queue_t;
164 
165 typedef xQueueHandle osal_queue_handle_t;
166 
167 #define OSAL_QUEUE_DEF(name, queue_depth, type)\
168  osal_queue_t name = {\
169  .depth = queue_depth,\
170  .item_size = sizeof(type)\
171  }
172 
173 #define OSAL_QUEUE_REF(name) (&name)
174 
175 #define osal_queue_create(p_queue) \
176  xQueueCreate((p_queue)->depth, (p_queue)->item_size)
177 
178 static inline void osal_queue_receive (osal_queue_handle_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) ATTR_ALWAYS_INLINE;
179 static inline void osal_queue_receive (osal_queue_handle_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error)
180 {
181  (*p_error) = ( xQueueReceive(queue_hdl, p_data, osal_tick_from_msec(msec)) == pdPASS ) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT;
182 }
183 
184 static inline tusb_error_t osal_queue_send(osal_queue_handle_t const queue_hdl, void const * data) ATTR_ALWAYS_INLINE;
185 static inline tusb_error_t osal_queue_send(osal_queue_handle_t const queue_hdl, void const * data)
186 {
187  portBASE_TYPE taskWaken;
188  return ( xQueueSendFromISR(queue_hdl, data, &taskWaken) == pdTRUE ) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_QUEUE_FAILED;
189 }
190 
191 static inline void osal_queue_flush(osal_queue_handle_t const queue_hdl) ATTR_ALWAYS_INLINE;
192 static inline void osal_queue_flush(osal_queue_handle_t const queue_hdl)
193 {
194  xQueueReset(queue_hdl);
195 }
196 
197 #ifdef __cplusplus
198  }
199 #endif
200 
201 #endif /* _TUSB_OSAL_FREERTOS_H_ */
202 
#define ATTR_WARN_UNUSED_RESULT
The warn_unused_result attribute causes a warning to be emitted if a caller of the function with this...
Definition: compiler_gcc.h:118
uint8_t const item_size
size of each item
Definition: osal_freeRTOS.h:162
Definition: osal_freeRTOS.h:160
tusb_error_t
Error Code returned.
Definition: tusb_errors.h:100
#define TUSB_CFG_TICKS_HZ
The rate ticks in hert. This is used in conjunction with tusb_tick_get to calculate timing...
Definition: configuration.txt:24
uint8_t const depth
buffer size
Definition: osal_freeRTOS.h:161
#define ATTR_ALWAYS_INLINE
Generally, functions are not inlined unless optimization is specified. For functions declared inline...
Definition: compiler_gcc.h:89
Definition: osal_freeRTOS.h:69