2 * Amazon FreeRTOS Platform V1.0.0
\r
3 * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\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
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\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
22 * http://aws.amazon.com/freertos
\r
23 * http://www.FreeRTOS.org
\r
27 * @file iot_threads_freertos.c
\r
28 * @brief Implementation of the functions in iot_threads.h for POSIX systems.
\r
31 /* The config header is always included first. */
\r
32 #include "iot_config.h"
\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
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
45 #ifdef IOT_LOG_LEVEL_GLOBAL
\r
46 #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_GLOBAL
\r
48 #define LIBRARY_LOG_LEVEL IOT_LOG_NONE
\r
52 #define LIBRARY_LOG_NAME ( "THREAD" )
\r
53 #include "iot_logging_setup.h"
\r
56 * Provide default values for undefined memory allocation functions based on
\r
57 * the usage of dynamic memory allocation.
\r
59 #ifndef IotThreads_Malloc
\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
66 #define IotThreads_Malloc malloc
\r
68 #ifndef IotThreads_Free
\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
75 #define IotThreads_Free free
\r
78 /*-----------------------------------------------------------*/
\r
80 static void _threadRoutineWrapper( void * pArgument )
\r
82 threadInfo_t * pThreadInfo = ( threadInfo_t * ) pArgument;
\r
84 /* Run the thread routine. */
\r
85 pThreadInfo->threadRoutine( pThreadInfo->pArgument );
\r
86 IotThreads_Free( pThreadInfo );
\r
88 vTaskDelete( NULL );
\r
91 /*-----------------------------------------------------------*/
\r
93 bool Iot_CreateDetachedThread( IotThreadRoutine_t threadRoutine,
\r
100 configASSERT( threadRoutine != NULL );
\r
102 IotLogDebug( "Creating new thread." );
\r
103 threadInfo_t * pThreadInfo = IotThreads_Malloc( sizeof( threadInfo_t ) );
\r
105 if( pThreadInfo == NULL )
\r
107 IotLogDebug( "Unable to allocate memory for threadRoutine %p.", threadRoutine );
\r
111 /* Create the FreeRTOS task that will run the thread. */
\r
114 pThreadInfo->threadRoutine = threadRoutine;
\r
115 pThreadInfo->pArgument = pArgument;
\r
117 if( xTaskCreate( _threadRoutineWrapper,
\r
119 ( configSTACK_DEPTH_TYPE ) stackSize,
\r
124 /* Task creation failed. */
\r
125 IotLogWarn( "Failed to create thread." );
\r
126 IotThreads_Free( pThreadInfo );
\r
134 /*-----------------------------------------------------------*/
\r
136 bool IotMutex_Create( IotMutex_t * pNewMutex,
\r
139 _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pNewMutex;
\r
141 configASSERT( internalMutex != NULL );
\r
143 IotLogDebug( "Creating new mutex %p.", pNewMutex );
\r
147 ( void ) xSemaphoreCreateRecursiveMutexStatic( &internalMutex->xMutex );
\r
151 ( void ) xSemaphoreCreateMutexStatic( &internalMutex->xMutex );
\r
154 /* remember the type of mutex */
\r
157 internalMutex->recursive = pdTRUE;
\r
161 internalMutex->recursive = pdFALSE;
\r
167 /*-----------------------------------------------------------*/
\r
169 void IotMutex_Destroy( IotMutex_t * pMutex )
\r
171 _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;
\r
173 configASSERT( internalMutex != NULL );
\r
175 vSemaphoreDelete( ( SemaphoreHandle_t ) &internalMutex->xMutex );
\r
178 /*-----------------------------------------------------------*/
\r
180 bool prIotMutexTimedLock( IotMutex_t * pMutex,
\r
181 TickType_t timeout )
\r
183 _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;
\r
184 BaseType_t lockResult;
\r
186 configASSERT( internalMutex != NULL );
\r
188 IotLogDebug( "Locking mutex %p.", internalMutex );
\r
190 /* Call the correct FreeRTOS mutex take function based on mutex type. */
\r
191 if( internalMutex->recursive == pdTRUE )
\r
193 lockResult = xSemaphoreTakeRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );
\r
197 lockResult = xSemaphoreTake( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );
\r
200 return( lockResult == pdTRUE );
\r
203 /*-----------------------------------------------------------*/
\r
205 void IotMutex_Lock( IotMutex_t * pMutex )
\r
207 prIotMutexTimedLock( pMutex, portMAX_DELAY );
\r
210 /*-----------------------------------------------------------*/
\r
212 bool IotMutex_TryLock( IotMutex_t * pMutex )
\r
214 return prIotMutexTimedLock( pMutex, 0 );
\r
217 /*-----------------------------------------------------------*/
\r
219 void IotMutex_Unlock( IotMutex_t * pMutex )
\r
221 _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;
\r
223 configASSERT( internalMutex != NULL );
\r
225 IotLogDebug( "Unlocking mutex %p.", internalMutex );
\r
227 /* Call the correct FreeRTOS mutex unlock function based on mutex type. */
\r
228 if( internalMutex->recursive == pdTRUE )
\r
230 ( void ) xSemaphoreGiveRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex );
\r
234 ( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &internalMutex->xMutex );
\r
238 /*-----------------------------------------------------------*/
\r
240 bool IotSemaphore_Create( IotSemaphore_t * pNewSemaphore,
\r
241 uint32_t initialValue,
\r
242 uint32_t maxValue )
\r
244 _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pNewSemaphore;
\r
246 configASSERT( internalSemaphore != NULL );
\r
248 IotLogDebug( "Creating new semaphore %p.", pNewSemaphore );
\r
250 ( void ) xSemaphoreCreateCountingStatic( maxValue, initialValue, &internalSemaphore->xSemaphore );
\r
255 /*-----------------------------------------------------------*/
\r
257 uint32_t IotSemaphore_GetCount( IotSemaphore_t * pSemaphore )
\r
259 _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
\r
260 UBaseType_t count = 0;
\r
262 configASSERT( internalSemaphore != NULL );
\r
264 count = uxSemaphoreGetCount( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );
\r
266 IotLogDebug( "Semaphore %p has count %d.", pSemaphore, count );
\r
268 return ( uint32_t ) count;
\r
271 /*-----------------------------------------------------------*/
\r
273 void IotSemaphore_Destroy( IotSemaphore_t * pSemaphore )
\r
275 _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
\r
277 configASSERT( internalSemaphore != NULL );
\r
279 IotLogDebug( "Destroying semaphore %p.", internalSemaphore );
\r
281 vSemaphoreDelete( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );
\r
284 /*-----------------------------------------------------------*/
\r
286 void IotSemaphore_Wait( IotSemaphore_t * pSemaphore )
\r
288 _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
\r
290 configASSERT( internalSemaphore != NULL );
\r
292 IotLogDebug( "Waiting on semaphore %p.", internalSemaphore );
\r
294 /* Take the semaphore using the FreeRTOS API. */
\r
295 if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore,
\r
296 portMAX_DELAY ) != pdTRUE )
\r
298 IotLogWarn( "Failed to wait on semaphore %p.",
\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
307 /*-----------------------------------------------------------*/
\r
309 bool IotSemaphore_TryWait( IotSemaphore_t * pSemaphore )
\r
311 _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
\r
313 configASSERT( internalSemaphore != NULL );
\r
315 IotLogDebug( "Attempting to wait on semaphore %p.", internalSemaphore );
\r
317 return IotSemaphore_TimedWait( pSemaphore, 0 );
\r
320 /*-----------------------------------------------------------*/
\r
322 bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore,
\r
323 uint32_t timeoutMs )
\r
325 _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
\r
327 configASSERT( internalSemaphore != NULL );
\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
333 /* Only warn if timeout > 0 */
\r
334 if( timeoutMs > 0 )
\r
336 IotLogWarn( "Timeout waiting on semaphore %p.",
\r
337 internalSemaphore );
\r
346 /*-----------------------------------------------------------*/
\r
348 void IotSemaphore_Post( IotSemaphore_t * pSemaphore )
\r
350 _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
\r
352 configASSERT( internalSemaphore != NULL );
\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
358 if( result == pdFALSE )
\r
360 IotLogDebug( "Unable to give semaphore over maximum", internalSemaphore );
\r
364 /*-----------------------------------------------------------*/
\r