]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c
Correct an err in queue.c introduced when previously updating behaviour when queue...
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-IoT-Libraries / abstractions / platform / freertos / iot_threads_freertos.c
1 /*\r
2  * Amazon FreeRTOS Platform V1.0.0\r
3  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://aws.amazon.com/freertos\r
23  * http://www.FreeRTOS.org\r
24  */\r
25 \r
26 /**\r
27  * @file iot_threads_freertos.c\r
28  * @brief Implementation of the functions in iot_threads.h for POSIX systems.\r
29  */\r
30 \r
31 /* The config header is always included first. */\r
32 #include "iot_config.h"\r
33 \r
34 #include "semphr.h"\r
35 \r
36 /* Platform threads include. */\r
37 #include "platform/iot_platform_types_freertos.h"\r
38 #include "platform/iot_threads.h"\r
39 #include "types/iot_platform_types.h"\r
40 \r
41 /* Configure logs for the functions in this file. */\r
42 #ifdef IOT_LOG_LEVEL_PLATFORM\r
43     #define LIBRARY_LOG_LEVEL        IOT_LOG_LEVEL_PLATFORM\r
44 #else\r
45     #ifdef IOT_LOG_LEVEL_GLOBAL\r
46         #define LIBRARY_LOG_LEVEL    IOT_LOG_LEVEL_GLOBAL\r
47     #else\r
48         #define LIBRARY_LOG_LEVEL    IOT_LOG_NONE\r
49     #endif\r
50 #endif\r
51 \r
52 #define LIBRARY_LOG_NAME    ( "THREAD" )\r
53 #include "iot_logging_setup.h"\r
54 \r
55 /*\r
56  * Provide default values for undefined memory allocation functions based on\r
57  * the usage of dynamic memory allocation.\r
58  */\r
59 #ifndef IotThreads_Malloc\r
60     #include <stdlib.h>\r
61 \r
62 /**\r
63  * @brief Memory allocation. This function should have the same signature\r
64  * as [malloc](http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).\r
65  */\r
66     #define IotThreads_Malloc    malloc\r
67 #endif\r
68 #ifndef IotThreads_Free\r
69     #include <stdlib.h>\r
70 \r
71 /**\r
72  * @brief Free memory. This function should have the same signature as\r
73  * [free](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).\r
74  */\r
75     #define IotThreads_Free    free\r
76 #endif\r
77 \r
78 /*-----------------------------------------------------------*/\r
79 \r
80 static void _threadRoutineWrapper( void * pArgument )\r
81 {\r
82     threadInfo_t * pThreadInfo = ( threadInfo_t * ) pArgument;\r
83 \r
84     /* Run the thread routine. */\r
85     pThreadInfo->threadRoutine( pThreadInfo->pArgument );\r
86     IotThreads_Free( pThreadInfo );\r
87 \r
88     vTaskDelete( NULL );\r
89 }\r
90 \r
91 /*-----------------------------------------------------------*/\r
92 \r
93 bool Iot_CreateDetachedThread( IotThreadRoutine_t threadRoutine,\r
94                                void * pArgument,\r
95                                int32_t priority,\r
96                                size_t stackSize )\r
97 {\r
98     bool status = true;\r
99 \r
100     configASSERT( threadRoutine != NULL );\r
101 \r
102     IotLogDebug( "Creating new thread." );\r
103     threadInfo_t * pThreadInfo = IotThreads_Malloc( sizeof( threadInfo_t ) );\r
104 \r
105     if( pThreadInfo == NULL )\r
106     {\r
107         IotLogDebug( "Unable to allocate memory for threadRoutine %p.", threadRoutine );\r
108         status = false;\r
109     }\r
110 \r
111     /* Create the FreeRTOS task that will run the thread. */\r
112     if( status )\r
113     {\r
114         pThreadInfo->threadRoutine = threadRoutine;\r
115         pThreadInfo->pArgument = pArgument;\r
116 \r
117         if( xTaskCreate( _threadRoutineWrapper,\r
118                          "iot_thread",\r
119                          ( configSTACK_DEPTH_TYPE ) stackSize,\r
120                          pThreadInfo,\r
121                          priority,\r
122                          NULL ) != pdPASS )\r
123         {\r
124             /* Task creation failed. */\r
125             IotLogWarn( "Failed to create thread." );\r
126             IotThreads_Free( pThreadInfo );\r
127             status = false;\r
128         }\r
129     }\r
130 \r
131     return status;\r
132 }\r
133 \r
134 /*-----------------------------------------------------------*/\r
135 \r
136 bool IotMutex_Create( IotMutex_t * pNewMutex,\r
137                       bool recursive )\r
138 {\r
139     _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pNewMutex;\r
140 \r
141     configASSERT( internalMutex != NULL );\r
142 \r
143     IotLogDebug( "Creating new mutex %p.", pNewMutex );\r
144 \r
145     if( recursive )\r
146     {\r
147         ( void ) xSemaphoreCreateRecursiveMutexStatic( &internalMutex->xMutex );\r
148     }\r
149     else\r
150     {\r
151         ( void ) xSemaphoreCreateMutexStatic( &internalMutex->xMutex );\r
152     }\r
153 \r
154     /* remember the type of mutex */\r
155     if( recursive )\r
156     {\r
157         internalMutex->recursive = pdTRUE;\r
158     }\r
159     else\r
160     {\r
161         internalMutex->recursive = pdFALSE;\r
162     }\r
163 \r
164     return true;\r
165 }\r
166 \r
167 /*-----------------------------------------------------------*/\r
168 \r
169 void IotMutex_Destroy( IotMutex_t * pMutex )\r
170 {\r
171     _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;\r
172 \r
173     configASSERT( internalMutex != NULL );\r
174 \r
175     vSemaphoreDelete( ( SemaphoreHandle_t ) &internalMutex->xMutex );\r
176 }\r
177 \r
178 /*-----------------------------------------------------------*/\r
179 \r
180 bool prIotMutexTimedLock( IotMutex_t * pMutex,\r
181                           TickType_t timeout )\r
182 {\r
183     _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;\r
184     BaseType_t lockResult;\r
185 \r
186     configASSERT( internalMutex != NULL );\r
187 \r
188     IotLogDebug( "Locking mutex %p.", internalMutex );\r
189 \r
190     /* Call the correct FreeRTOS mutex take function based on mutex type. */\r
191     if( internalMutex->recursive == pdTRUE )\r
192     {\r
193         lockResult = xSemaphoreTakeRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );\r
194     }\r
195     else\r
196     {\r
197         lockResult = xSemaphoreTake( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );\r
198     }\r
199 \r
200     return( lockResult == pdTRUE );\r
201 }\r
202 \r
203 /*-----------------------------------------------------------*/\r
204 \r
205 void IotMutex_Lock( IotMutex_t * pMutex )\r
206 {\r
207     prIotMutexTimedLock( pMutex, portMAX_DELAY );\r
208 }\r
209 \r
210 /*-----------------------------------------------------------*/\r
211 \r
212 bool IotMutex_TryLock( IotMutex_t * pMutex )\r
213 {\r
214     return prIotMutexTimedLock( pMutex, 0 );\r
215 }\r
216 \r
217 /*-----------------------------------------------------------*/\r
218 \r
219 void IotMutex_Unlock( IotMutex_t * pMutex )\r
220 {\r
221     _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;\r
222 \r
223     configASSERT( internalMutex != NULL );\r
224 \r
225     IotLogDebug( "Unlocking mutex %p.", internalMutex );\r
226 \r
227     /* Call the correct FreeRTOS mutex unlock function based on mutex type. */\r
228     if( internalMutex->recursive == pdTRUE )\r
229     {\r
230         ( void ) xSemaphoreGiveRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex );\r
231     }\r
232     else\r
233     {\r
234         ( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &internalMutex->xMutex );\r
235     }\r
236 }\r
237 \r
238 /*-----------------------------------------------------------*/\r
239 \r
240 bool IotSemaphore_Create( IotSemaphore_t * pNewSemaphore,\r
241                           uint32_t initialValue,\r
242                           uint32_t maxValue )\r
243 {\r
244     _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pNewSemaphore;\r
245 \r
246     configASSERT( internalSemaphore != NULL );\r
247 \r
248     IotLogDebug( "Creating new semaphore %p.", pNewSemaphore );\r
249 \r
250     ( void ) xSemaphoreCreateCountingStatic( maxValue, initialValue, &internalSemaphore->xSemaphore );\r
251 \r
252     return true;\r
253 }\r
254 \r
255 /*-----------------------------------------------------------*/\r
256 \r
257 uint32_t IotSemaphore_GetCount( IotSemaphore_t * pSemaphore )\r
258 {\r
259     _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
260     UBaseType_t count = 0;\r
261 \r
262     configASSERT( internalSemaphore != NULL );\r
263 \r
264     count = uxSemaphoreGetCount( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );\r
265 \r
266     IotLogDebug( "Semaphore %p has count %d.", pSemaphore, count );\r
267 \r
268     return ( uint32_t ) count;\r
269 }\r
270 \r
271 /*-----------------------------------------------------------*/\r
272 \r
273 void IotSemaphore_Destroy( IotSemaphore_t * pSemaphore )\r
274 {\r
275     _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
276 \r
277     configASSERT( internalSemaphore != NULL );\r
278 \r
279     IotLogDebug( "Destroying semaphore %p.", internalSemaphore );\r
280 \r
281     vSemaphoreDelete( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );\r
282 }\r
283 \r
284 /*-----------------------------------------------------------*/\r
285 \r
286 void IotSemaphore_Wait( IotSemaphore_t * pSemaphore )\r
287 {\r
288     _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
289 \r
290     configASSERT( internalSemaphore != NULL );\r
291 \r
292     IotLogDebug( "Waiting on semaphore %p.", internalSemaphore );\r
293 \r
294     /* Take the semaphore using the FreeRTOS API. */\r
295     if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore,\r
296                         portMAX_DELAY ) != pdTRUE )\r
297     {\r
298         IotLogWarn( "Failed to wait on semaphore %p.",\r
299                     pSemaphore );\r
300 \r
301         /* Assert here, debugging we always want to know that this happened because you think\r
302          *   that you are waiting successfully on the semaphore but you are not   */\r
303         configASSERT( false );\r
304     }\r
305 }\r
306 \r
307 /*-----------------------------------------------------------*/\r
308 \r
309 bool IotSemaphore_TryWait( IotSemaphore_t * pSemaphore )\r
310 {\r
311     _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
312 \r
313     configASSERT( internalSemaphore != NULL );\r
314 \r
315     IotLogDebug( "Attempting to wait on semaphore %p.", internalSemaphore );\r
316 \r
317     return IotSemaphore_TimedWait( pSemaphore, 0 );\r
318 }\r
319 \r
320 /*-----------------------------------------------------------*/\r
321 \r
322 bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore,\r
323                              uint32_t timeoutMs )\r
324 {\r
325     _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
326 \r
327     configASSERT( internalSemaphore != NULL );\r
328 \r
329     /* Take the semaphore using the FreeRTOS API. Cast the calculation to 64 bit to avoid overflows*/\r
330     if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore,\r
331                         pdMS_TO_TICKS( timeoutMs ) ) != pdTRUE )\r
332     {\r
333         /* Only warn if timeout > 0 */\r
334         if( timeoutMs > 0 )\r
335         {\r
336             IotLogWarn( "Timeout waiting on semaphore %p.",\r
337                         internalSemaphore );\r
338         }\r
339 \r
340         return false;\r
341     }\r
342 \r
343     return true;\r
344 }\r
345 \r
346 /*-----------------------------------------------------------*/\r
347 \r
348 void IotSemaphore_Post( IotSemaphore_t * pSemaphore )\r
349 {\r
350     _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;\r
351 \r
352     configASSERT( internalSemaphore != NULL );\r
353 \r
354     IotLogDebug( "Posting to semaphore %p.", internalSemaphore );\r
355     /* Give the semaphore using the FreeRTOS API. */\r
356     BaseType_t result = xSemaphoreGive( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );\r
357 \r
358     if( result == pdFALSE )\r
359     {\r
360         IotLogDebug( "Unable to give semaphore over maximum", internalSemaphore );\r
361     }\r
362 }\r
363 \r
364 /*-----------------------------------------------------------*/\r