diff --git a/components/freertos/include/freertos/FreeRTOS.h b/components/freertos/include/freertos/FreeRTOS.h index 0b0fce99dc..b311f53b1f 100644 --- a/components/freertos/include/freertos/FreeRTOS.h +++ b/components/freertos/include/freertos/FreeRTOS.h @@ -53,12 +53,13 @@ #endif /* *INDENT-ON* */ +#ifdef ESP_PLATFORM /* for likely and unlikely */ #include "esp_compiler.h" +#endif // ESP_PLATFORM /* Application specific configuration options. */ #include "freertos/FreeRTOSConfig.h" - /* Basic FreeRTOS definitions. */ #include "projdefs.h" @@ -129,8 +130,28 @@ #define INCLUDE_vTaskSuspend 0 #endif -#ifndef INCLUDE_vTaskDelayUntil - #define INCLUDE_vTaskDelayUntil 0 +#ifdef INCLUDE_xTaskDelayUntil + #ifdef INCLUDE_vTaskDelayUntil + /* INCLUDE_vTaskDelayUntil was replaced by INCLUDE_xTaskDelayUntil. Backward + * compatibility is maintained if only one or the other is defined, but + * there is a conflict if both are defined. */ + #error INCLUDE_vTaskDelayUntil and INCLUDE_xTaskDelayUntil are both defined. INCLUDE_vTaskDelayUntil is no longer required and should be removed + #endif +#endif + +#ifndef INCLUDE_xTaskDelayUntil + #ifdef INCLUDE_vTaskDelayUntil + /* If INCLUDE_vTaskDelayUntil is set but INCLUDE_xTaskDelayUntil is not then + * the project's FreeRTOSConfig.h probably pre-dates the introduction of + * xTaskDelayUntil and setting INCLUDE_xTaskDelayUntil to whatever + * INCLUDE_vTaskDelayUntil is set to will ensure backward compatibility. + */ + #define INCLUDE_xTaskDelayUntil INCLUDE_vTaskDelayUntil + #endif +#endif + +#ifndef INCLUDE_xTaskDelayUntil + #define INCLUDE_xTaskDelayUntil 0 #endif #ifndef INCLUDE_vTaskDelay @@ -888,12 +909,14 @@ #endif #ifndef configSTACK_DEPTH_TYPE + /* Defaults to uint16_t for backward compatibility, but can be overridden * in FreeRTOSConfig.h if uint16_t is too restrictive. */ #define configSTACK_DEPTH_TYPE uint16_t #endif #ifndef configMESSAGE_BUFFER_LENGTH_TYPE + /* Defaults to size_t for backward compatibility, but can be overridden * in FreeRTOSConfig.h if lengths will always be less than the number of bytes * in a size_t. */ @@ -920,6 +943,7 @@ #endif #if ( portTICK_TYPE_IS_ATOMIC == 0 ) + /* Either variables of tick type cannot be read atomically, or * portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when * the tick count is returned to the standard critical section macros. */ @@ -1005,9 +1029,11 @@ #define pxContainer pvContainer #endif /* configENABLE_BACKWARD_COMPATIBILITY */ +#ifdef ESP_PLATFORM #ifndef configESP32_PER_TASK_DATA #define configESP32_PER_TASK_DATA 1 #endif +#endif // ESP_PLATFORM #if ( configUSE_ALTERNATIVE_API != 0 ) #error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 @@ -1246,9 +1272,7 @@ typedef struct xSTATIC_QUEUE UBaseType_t uxDummy8; uint8_t ucDummy9; #endif - portMUX_TYPE xDummy10; - } StaticQueue_t; typedef StaticQueue_t StaticSemaphore_t; @@ -1278,9 +1302,7 @@ typedef struct xSTATIC_EVENT_GROUP #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) uint8_t ucDummy4; #endif - portMUX_TYPE xDummy5; - } StaticEventGroup_t; /* @@ -1332,9 +1354,7 @@ typedef struct xSTATIC_STREAM_BUFFER #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxDummy4; #endif - portMUX_TYPE xDummy5; - } StaticStreamBuffer_t; /* Message buffers are built on stream buffers. */ diff --git a/components/freertos/include/freertos/queue.h b/components/freertos/include/freertos/queue.h index 9ff31d7eb8..3464e65b2e 100644 --- a/components/freertos/include/freertos/queue.h +++ b/components/freertos/include/freertos/queue.h @@ -80,8 +80,30 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; /** @endcond */ /** - * Creates a new queue instance. This allocates the storage required by the - * new queue and returns a handle for the queue. + * @cond + * queue. h + * @code{c} + * QueueHandle_t xQueueCreate( + * UBaseType_t uxQueueLength, + * UBaseType_t uxItemSize + * ); + * @endcode + * @endcond + * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * https://www.FreeRTOS.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * https://www.FreeRTOS.org/Embedded-RTOS-Queues.html * * @param uxQueueLength The maximum number of items that the queue can contain. * @@ -1562,7 +1584,8 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; * preferably in ROM/Flash), not on the stack. */ #if ( configQUEUE_REGISTRY_SIZE > 0 ) - void vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + void vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ #endif /** diff --git a/components/freertos/include/freertos/task.h b/components/freertos/include/freertos/task.h index 8d525f244b..8f8f3545e5 100644 --- a/components/freertos/include/freertos/task.h +++ b/components/freertos/include/freertos/task.h @@ -867,7 +867,10 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** - * Delay a task for a given number of ticks. + * task. h + * @code{c} + * void vTaskDelay( const TickType_t xTicksToDelay ); + * @endcode * * Delay a task for a given number of ticks. The actual time that the * task remains blocked depends on the tick rate. The constant @@ -885,7 +888,7 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; * of controlling the frequency of a periodic task as the path taken through the * code, as well as other task and interrupt activity, will effect the frequency * at which vTaskDelay() gets called and therefore the time at which the task - * next executes. See vTaskDelayUntil() for an alternative API function designed + * next executes. See xTaskDelayUntil() for an alternative API function designed * to facilitate fixed frequency execution. It does this by specifying an * absolute time (rather than a relative time) at which the calling task should * unblock. @@ -917,9 +920,12 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; /** - * Delay a task until a specified time. + * task. h + * @code{c} + * BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement ); + * @endcode * - * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available. * See the configuration section for more information. * * Delay a task until a specified time. This function can be used by periodic @@ -934,22 +940,26 @@ void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; * each time it executes]. * * Whereas vTaskDelay () specifies a wake time relative to the time at which the function - * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * is called, xTaskDelayUntil () specifies the absolute (exact) time at which it wishes to * unblock. * - * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick - * rate - with the resolution of one tick period. + * The macro pdMS_TO_TICKS() can be used to calculate the number of ticks from a + * time specified in milliseconds with a resolution of one tick period. * * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the * task was last unblocked. The variable must be initialised with the current time * prior to its first use (see the example below). Following this the variable is - * automatically updated within vTaskDelayUntil (). + * automatically updated within xTaskDelayUntil (). * * @param xTimeIncrement The cycle time period. The task will be unblocked at - * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * time *pxPreviousWakeTime + xTimeIncrement. Calling xTaskDelayUntil with the * same xTimeIncrement parameter value will cause the task to execute with * a fixed interface period. * + * @return Value which can be used to check whether the task was actually delayed. + * Will be pdTRUE if the task way delayed and pdFALSE otherwise. A task will not + * be delayed if the next expected wake time is in the past. + * * Example usage: * @code{c} * // Perform an action every 10 ticks. @@ -957,15 +967,17 @@ void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; * { * TickType_t xLastWakeTime; * const TickType_t xFrequency = 10; + * BaseType_t xWasDelayed; * * // Initialise the xLastWakeTime variable with the current time. * xLastWakeTime = xTaskGetTickCount (); * for( ;; ) * { * // Wait for the next cycle. - * vTaskDelayUntil( &xLastWakeTime, xFrequency ); + * xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency ); * - * // Perform action here. + * // Perform action here. xWasDelayed value can be used to determine + * // whether a deadline was missed if the code here took too long. * } * } * @endcode @@ -974,9 +986,19 @@ void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; * @endcond * \ingroup TaskCtrl */ -void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, +BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; +/* + * vTaskDelayUntil() is the older version of xTaskDelayUntil() and does not + * return a value. + */ +#define vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ) \ +{ \ + ( void ) xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); \ +} + + /** * @cond * task. h diff --git a/components/freertos/linker.lf b/components/freertos/linker.lf index 23de74c1e7..4ae70fe789 100644 --- a/components/freertos/linker.lf +++ b/components/freertos/linker.lf @@ -34,6 +34,7 @@ entries: tasks: xTaskGetCurrentTaskHandleForCPU (default) tasks: vTaskDelete (default) tasks: vTaskDelayUntil (default) + tasks: xTaskDelayUntil (default) tasks: vTaskDelay (default) tasks: vTaskSuspend (default) tasks: xTaskResumeAll (default) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index 4b02759566..011c9ea344 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -1440,19 +1440,36 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB, #endif /* INCLUDE_vTaskDelete */ /*-----------------------------------------------------------*/ -#if ( INCLUDE_vTaskDelayUntil == 1 ) - +#if ( INCLUDE_xTaskDelayUntil == 1 ) +#ifdef ESP_PLATFORM + // backward binary compatibility - remove later + #undef vTaskDelayUntil void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) + { + xTaskDelayUntil(pxPreviousWakeTime, xTimeIncrement); + } +#endif // ESP_PLATFORM + + BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) { TickType_t xTimeToWake; +#ifdef ESP_PLATFORM BaseType_t xShouldDelay = pdFALSE; +#else + BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; +#endif // ESP_PLATFORM configASSERT( pxPreviousWakeTime ); configASSERT( ( xTimeIncrement > 0U ) ); configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 ); +#ifdef ESP_PLATFORM taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { /* Minor optimisation. The tick count cannot change in this * block. */ @@ -1508,13 +1525,30 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB, mtCOVERAGE_TEST_MARKER(); } } +#ifdef ESP_PLATFORM taskEXIT_CRITICAL(); +#else + xAlreadyYielded = xTaskResumeAll(); +#endif // ESP_PLATFORM - /* Force a reschedule, we may have put ourselves to sleep. */ + /* Force a reschedule if xTaskResumeAll has not already done so, we may + * have put ourselves to sleep. */ +#ifdef ESP_PLATFORM portYIELD_WITHIN_API(); +#else + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +#endif // ESP_PLATFORM + return xShouldDelay; } -#endif /* INCLUDE_vTaskDelayUntil */ +#endif /* INCLUDE_xTaskDelayUntil */ /*-----------------------------------------------------------*/ #if ( INCLUDE_vTaskDelay == 1 )