summaryrefslogtreecommitdiff
path: root/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c')
-rw-r--r--FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c365
1 files changed, 365 insertions, 0 deletions
diff --git a/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c b/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c
new file mode 100644
index 000000000..e1d8119f6
--- /dev/null
+++ b/FreeRTOS-Labs/Source/FreeRTOS-IoT-Libraries/abstractions/platform/freertos/iot_threads_freertos.c
@@ -0,0 +1,365 @@
+/*
+ * Amazon FreeRTOS Platform V1.1.0
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/**
+ * @file iot_threads_freertos.c
+ * @brief Implementation of the platform specific functions in iot_threads.h for
+ * FreeRTOS.
+ */
+
+/* The config header is always included first. */
+#include "iot_config.h"
+
+#include "semphr.h"
+
+/* Platform threads include. */
+#include "platform/iot_platform_types_freertos.h"
+#include "platform/iot_threads.h"
+#include "types/iot_platform_types.h"
+
+/* Configure logs for the functions in this file. */
+#ifdef IOT_LOG_LEVEL_PLATFORM
+ #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_PLATFORM
+#else
+ #ifdef IOT_LOG_LEVEL_GLOBAL
+ #define LIBRARY_LOG_LEVEL IOT_LOG_LEVEL_GLOBAL
+ #else
+ #define LIBRARY_LOG_LEVEL IOT_LOG_NONE
+ #endif
+#endif
+
+#define LIBRARY_LOG_NAME ( "THREAD" )
+#include "iot_logging_setup.h"
+
+/*
+ * Provide default values for undefined memory allocation functions based on
+ * the usage of dynamic memory allocation.
+ */
+#ifndef IotThreads_Malloc
+ #include <stdlib.h>
+
+/**
+ * @brief Memory allocation. This function should have the same signature
+ * as [malloc](http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html).
+ */
+ #define IotThreads_Malloc malloc
+#endif
+#ifndef IotThreads_Free
+ #include <stdlib.h>
+
+/**
+ * @brief Free memory. This function should have the same signature as
+ * [free](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).
+ */
+ #define IotThreads_Free free
+#endif
+
+/*-----------------------------------------------------------*/
+
+static void _threadRoutineWrapper( void * pArgument )
+{
+ threadInfo_t * pThreadInfo = ( threadInfo_t * ) pArgument;
+
+ /* Run the thread routine. */
+ pThreadInfo->threadRoutine( pThreadInfo->pArgument );
+ IotThreads_Free( pThreadInfo );
+
+ vTaskDelete( NULL );
+}
+
+/*-----------------------------------------------------------*/
+
+bool Iot_CreateDetachedThread( IotThreadRoutine_t threadRoutine,
+ void * pArgument,
+ int32_t priority,
+ size_t stackSize )
+{
+ bool status = true;
+
+ configASSERT( threadRoutine != NULL );
+
+ IotLogDebug( "Creating new thread." );
+ threadInfo_t * pThreadInfo = IotThreads_Malloc( sizeof( threadInfo_t ) );
+
+ if( pThreadInfo == NULL )
+ {
+ IotLogDebug( "Unable to allocate memory for threadRoutine %p.", threadRoutine );
+ status = false;
+ }
+
+ /* Create the FreeRTOS task that will run the thread. */
+ if( status )
+ {
+ pThreadInfo->threadRoutine = threadRoutine;
+ pThreadInfo->pArgument = pArgument;
+
+ if( xTaskCreate( _threadRoutineWrapper,
+ "iot_thread",
+ ( configSTACK_DEPTH_TYPE ) stackSize,
+ pThreadInfo,
+ priority,
+ NULL ) != pdPASS )
+ {
+ /* Task creation failed. */
+ IotLogWarn( "Failed to create thread." );
+ IotThreads_Free( pThreadInfo );
+ status = false;
+ }
+ }
+
+ return status;
+}
+
+/*-----------------------------------------------------------*/
+
+bool IotMutex_Create( IotMutex_t * pNewMutex,
+ bool recursive )
+{
+ _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pNewMutex;
+
+ configASSERT( internalMutex != NULL );
+
+ IotLogDebug( "Creating new mutex %p.", pNewMutex );
+
+ if( recursive )
+ {
+ ( void ) xSemaphoreCreateRecursiveMutexStatic( &internalMutex->xMutex );
+ }
+ else
+ {
+ ( void ) xSemaphoreCreateMutexStatic( &internalMutex->xMutex );
+ }
+
+ /* remember the type of mutex */
+ if( recursive )
+ {
+ internalMutex->recursive = pdTRUE;
+ }
+ else
+ {
+ internalMutex->recursive = pdFALSE;
+ }
+
+ return true;
+}
+
+/*-----------------------------------------------------------*/
+
+void IotMutex_Destroy( IotMutex_t * pMutex )
+{
+ _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;
+
+ configASSERT( internalMutex != NULL );
+
+ vSemaphoreDelete( ( SemaphoreHandle_t ) &internalMutex->xMutex );
+}
+
+/*-----------------------------------------------------------*/
+
+bool prIotMutexTimedLock( IotMutex_t * pMutex,
+ TickType_t timeout )
+{
+ _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;
+ BaseType_t lockResult;
+
+ configASSERT( internalMutex != NULL );
+
+ IotLogDebug( "Locking mutex %p.", internalMutex );
+
+ /* Call the correct FreeRTOS mutex take function based on mutex type. */
+ if( internalMutex->recursive == pdTRUE )
+ {
+ lockResult = xSemaphoreTakeRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );
+ }
+ else
+ {
+ lockResult = xSemaphoreTake( ( SemaphoreHandle_t ) &internalMutex->xMutex, timeout );
+ }
+
+ return( lockResult == pdTRUE );
+}
+
+/*-----------------------------------------------------------*/
+
+void IotMutex_Lock( IotMutex_t * pMutex )
+{
+ prIotMutexTimedLock( pMutex, portMAX_DELAY );
+}
+
+/*-----------------------------------------------------------*/
+
+bool IotMutex_TryLock( IotMutex_t * pMutex )
+{
+ return prIotMutexTimedLock( pMutex, 0 );
+}
+
+/*-----------------------------------------------------------*/
+
+void IotMutex_Unlock( IotMutex_t * pMutex )
+{
+ _IotSystemMutex_t * internalMutex = ( _IotSystemMutex_t * ) pMutex;
+
+ configASSERT( internalMutex != NULL );
+
+ IotLogDebug( "Unlocking mutex %p.", internalMutex );
+
+ /* Call the correct FreeRTOS mutex unlock function based on mutex type. */
+ if( internalMutex->recursive == pdTRUE )
+ {
+ ( void ) xSemaphoreGiveRecursive( ( SemaphoreHandle_t ) &internalMutex->xMutex );
+ }
+ else
+ {
+ ( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &internalMutex->xMutex );
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+bool IotSemaphore_Create( IotSemaphore_t * pNewSemaphore,
+ uint32_t initialValue,
+ uint32_t maxValue )
+{
+ _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pNewSemaphore;
+
+ configASSERT( internalSemaphore != NULL );
+
+ IotLogDebug( "Creating new semaphore %p.", pNewSemaphore );
+
+ ( void ) xSemaphoreCreateCountingStatic( maxValue, initialValue, &internalSemaphore->xSemaphore );
+
+ return true;
+}
+
+/*-----------------------------------------------------------*/
+
+uint32_t IotSemaphore_GetCount( IotSemaphore_t * pSemaphore )
+{
+ _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
+ UBaseType_t count = 0;
+
+ configASSERT( internalSemaphore != NULL );
+
+ count = uxSemaphoreGetCount( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );
+
+ IotLogDebug( "Semaphore %p has count %d.", pSemaphore, count );
+
+ return ( uint32_t ) count;
+}
+
+/*-----------------------------------------------------------*/
+
+void IotSemaphore_Destroy( IotSemaphore_t * pSemaphore )
+{
+ _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
+
+ configASSERT( internalSemaphore != NULL );
+
+ IotLogDebug( "Destroying semaphore %p.", internalSemaphore );
+
+ vSemaphoreDelete( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );
+}
+
+/*-----------------------------------------------------------*/
+
+void IotSemaphore_Wait( IotSemaphore_t * pSemaphore )
+{
+ _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
+
+ configASSERT( internalSemaphore != NULL );
+
+ IotLogDebug( "Waiting on semaphore %p.", internalSemaphore );
+
+ /* Take the semaphore using the FreeRTOS API. */
+ if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore,
+ portMAX_DELAY ) != pdTRUE )
+ {
+ IotLogWarn( "Failed to wait on semaphore %p.",
+ pSemaphore );
+
+ /* There is an assert here because during debugging we could falsely
+ * believe that we are waiting successfully on a semaphore. */
+ configASSERT( false );
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+bool IotSemaphore_TryWait( IotSemaphore_t * pSemaphore )
+{
+ _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
+
+ configASSERT( internalSemaphore != NULL );
+
+ IotLogDebug( "Attempting to wait on semaphore %p.", internalSemaphore );
+
+ return IotSemaphore_TimedWait( pSemaphore, 0 );
+}
+
+/*-----------------------------------------------------------*/
+
+bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore,
+ uint32_t timeoutMs )
+{
+ _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
+
+ configASSERT( internalSemaphore != NULL );
+
+ /* Take the semaphore using the FreeRTOS API. Cast the calculation to 64 bit to avoid overflows. */
+ if( xSemaphoreTake( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore,
+ pdMS_TO_TICKS( timeoutMs ) ) != pdTRUE )
+ {
+ /* Only warn if timeout > 0. */
+ if( timeoutMs > 0 )
+ {
+ IotLogWarn( "Timeout waiting on semaphore %p.",
+ internalSemaphore );
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
+/*-----------------------------------------------------------*/
+
+void IotSemaphore_Post( IotSemaphore_t * pSemaphore )
+{
+ _IotSystemSemaphore_t * internalSemaphore = ( _IotSystemSemaphore_t * ) pSemaphore;
+
+ configASSERT( internalSemaphore != NULL );
+
+ IotLogDebug( "Posting to semaphore %p.", internalSemaphore );
+ /* Give the semaphore using the FreeRTOS API. */
+ BaseType_t result = xSemaphoreGive( ( SemaphoreHandle_t ) &internalSemaphore->xSemaphore );
+
+ if( result == pdFALSE )
+ {
+ IotLogDebug( "Unable to give semaphore over maximum", internalSemaphore );
+ }
+}
+
+/*-----------------------------------------------------------*/