From eaafe7d53a385dda2d8d914c03ec2a4738e4bf09 Mon Sep 17 00:00:00 2001 From: rtel Date: Fri, 19 Jul 2019 01:39:42 +0000 Subject: [PATCH] Add the files from the MQTT project that were not check in. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2689 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../platform/freertos/iot_clock_freertos.c | 224 +++++++++++ .../platform/freertos/iot_threads_freertos.c | 364 ++++++++++++++++++ 2 files changed, 588 insertions(+) create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_clock_freertos.c create mode 100644 FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_threads_freertos.c diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_clock_freertos.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_clock_freertos.c new file mode 100644 index 000000000..4d74b8278 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_clock_freertos.c @@ -0,0 +1,224 @@ +/* + * Amazon FreeRTOS Platform V1.0.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_clock_freertos.c + * @brief Implementation of the functions in iot_clock.h for Amazon FreeRTOS systems. + */ + +/* The config header is always included first. */ +#include "iot_config.h" + +/* Standard includes. */ +#include + +/* Platform clock include. */ +#include "platform/iot_platform_types_freertos.h" +#include "platform/iot_clock.h" +#include "task.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 ( "CLOCK" ) +#include "iot_logging_setup.h" + +/*-----------------------------------------------------------*/ + +/* + * Time conversion constants. + */ +#define _MILLISECONDS_PER_SECOND ( 1000 ) /**< @brief Milliseconds per second. */ +#define _MILLISECONDS_PER_TICK ( _MILLISECONDS_PER_SECOND / configTICK_RATE_HZ ) /**< Milliseconds per FreeRTOS tick. */ + +/*-----------------------------------------------------------*/ + +/* Private Callback function for timer expiry, delegate work to a Task to free + * up the timer task for managing other timers */ +static void prvTimerCallback( TimerHandle_t xTimerHandle ) +{ + _IotSystemTimer_t * pxTimer = ( _IotSystemTimer_t * ) pvTimerGetTimerID( xTimerHandle ); + + /* The value of the timer ID, set in timer_create, should not be NULL. */ + configASSERT( pxTimer != NULL ); + + /* Restart the timer if it is periodic. */ + if( pxTimer->xTimerPeriod > 0 ) + { + xTimerChangePeriod( xTimerHandle, pxTimer->xTimerPeriod, 0 ); + } + + /* Call timer Callback from this task */ + pxTimer->threadRoutine( ( void * ) pxTimer->pArgument ); +} + +/*-----------------------------------------------------------*/ + +bool IotClock_GetTimestring( char * pBuffer, + size_t bufferSize, + size_t * pTimestringLength ) +{ + uint64_t milliSeconds = IotClock_GetTimeMs(); + int timestringLength = 0; + + configASSERT( pBuffer != NULL ); + configASSERT( pTimestringLength != NULL ); + + /* Convert the localTime struct to a string. */ + timestringLength = snprintf( pBuffer, bufferSize, "%llu", milliSeconds ); + + /* Check for error from no string */ + if( timestringLength == 0 ) + { + return false; + } + + /* Set the output parameter. */ + *pTimestringLength = timestringLength; + + return true; +} + +/*-----------------------------------------------------------*/ + +uint64_t IotClock_GetTimeMs( void ) +{ + TimeOut_t xCurrentTime = { 0 }; + + /* This must be unsigned because the behavior of signed integer overflow is undefined. */ + uint64_t ullTickCount = 0ULL; + + /* Get the current tick count and overflow count. vTaskSetTimeOutState() + * is used to get these values because they are both static in tasks.c. */ + vTaskSetTimeOutState( &xCurrentTime ); + + /* Adjust the tick count for the number of times a TickType_t has overflowed. */ + ullTickCount = ( uint64_t ) ( xCurrentTime.xOverflowCount ) << ( sizeof( TickType_t ) * 8 ); + + /* Add the current tick count. */ + ullTickCount += xCurrentTime.xTimeOnEntering; + + /* Return the ticks converted to Milliseconds */ + return ullTickCount * _MILLISECONDS_PER_TICK; +} +/*-----------------------------------------------------------*/ + +void IotClock_SleepMs( uint32_t sleepTimeMs ) +{ + vTaskDelay( pdMS_TO_TICKS( sleepTimeMs ) ); +} + +/*-----------------------------------------------------------*/ + +bool IotClock_TimerCreate( IotTimer_t * pNewTimer, + IotThreadRoutine_t expirationRoutine, + void * pArgument ) +{ + _IotSystemTimer_t * pxTimer = ( _IotSystemTimer_t * ) pNewTimer; + + configASSERT( pNewTimer != NULL ); + configASSERT( expirationRoutine != NULL ); + + IotLogDebug( "Creating new timer %p.", pNewTimer ); + + /* Set the timer expiration routine, argument and period */ + pxTimer->threadRoutine = expirationRoutine; + pxTimer->pArgument = pArgument; + pxTimer->xTimerPeriod = 0; + + /* Create a new FreeRTOS timer. This call will not fail because the + * memory for it has already been allocated, so the output parameter is + * also set. */ + pxTimer->timer = ( TimerHandle_t ) xTimerCreateStatic( "timer", /* Timer name. */ + portMAX_DELAY, /* Initial timer period. Timers are created disarmed. */ + pdFALSE, /* Don't auto-reload timer. */ + ( void * ) pxTimer, /* Timer id. */ + prvTimerCallback, /* Timer expiration callback. */ + &pxTimer->xTimerBuffer ); /* Pre-allocated memory for timer. */ + + return true; +} + +/*-----------------------------------------------------------*/ + +void IotClock_TimerDestroy( IotTimer_t * pTimer ) +{ + _IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer; + + configASSERT( pTimerInfo != NULL ); + configASSERT( pTimerInfo->timer != NULL ); + + IotLogDebug( "Destroying timer %p.", pTimer ); + + if( xTimerIsTimerActive( pTimerInfo->timer ) == pdTRUE ) + { + /* Stop the FreeRTOS timer. Because the timer is statically allocated, no call + * to xTimerDelete is necessary. The timer is stopped so that it's not referenced + * anywhere. xTimerStop will not fail when it has unlimited block time. */ + ( void ) xTimerStop( pTimerInfo->timer, portMAX_DELAY ); + + /* Wait until the timer stop command is processed. */ + while( xTimerIsTimerActive( pTimerInfo->timer ) == pdTRUE ) + { + vTaskDelay( 1 ); + } + } +} + +/*-----------------------------------------------------------*/ + +bool IotClock_TimerArm( IotTimer_t * pTimer, + uint32_t relativeTimeoutMs, + uint32_t periodMs ) +{ + _IotSystemTimer_t * pTimerInfo = ( _IotSystemTimer_t * ) pTimer; + + configASSERT( pTimerInfo != NULL ); + + TimerHandle_t xTimerHandle = pTimerInfo->timer; + + IotLogDebug( "Arming timer %p with timeout %llu and period %llu.", + pTimer, + relativeTimeoutMs, + periodMs ); + + /* Set the timer period in ticks */ + pTimerInfo->xTimerPeriod = pdMS_TO_TICKS( periodMs ); + + /* Set the timer to expire after relativeTimeoutMs, and restart it. */ + ( void ) xTimerChangePeriod( xTimerHandle, pdMS_TO_TICKS( relativeTimeoutMs ), portMAX_DELAY ); + + return true; +} + +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_threads_freertos.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_threads_freertos.c new file mode 100644 index 000000000..f4a5f97f3 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-IoT-SDK/abstractions/platform/freertos/iot_threads_freertos.c @@ -0,0 +1,364 @@ +/* + * Amazon FreeRTOS Platform V1.0.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 functions in iot_threads.h for POSIX systems. + */ + +/* 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 + +/** + * @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 + +/** + * @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 ); + + /* Assert here, debugging we always want to know that this happened because you think + * that you are waiting successfully on the semaphore but you are not */ + 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 ); + } +} + +/*-----------------------------------------------------------*/ -- 2.39.2