This commit is contained in:
Nicola Fontana 2026-02-25 11:34:48 +00:00 committed by GitHub
commit a1a98bb7b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 103 additions and 0 deletions

View file

@ -1766,6 +1766,14 @@
#define traceRETURN_vTaskDelete()
#endif
#ifndef traceENTER_xTaskPeriodicDelay
#define traceENTER_xTaskPeriodicDelay( pxPreviousWakeTime, xTimeIncrement )
#endif
#ifndef traceRETURN_xTaskPeriodicDelay
#define traceRETURN_xTaskPeriodicDelay( xIncrements )
#endif
#ifndef traceENTER_xTaskDelayUntil
#define traceENTER_xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement )
#endif

View file

@ -862,6 +862,43 @@ void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;
*/
void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION;
/**
* task. h
* @code{c}
* TickType_t xTaskPeriodicDelay( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
* @endcode
*
* INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available.
* See the configuration section for more information.
*
* Periodic task delay to ensure a constant execution frequency.
*
* This function is similar to xTaskDelayUntil () with a few important differences:
* - pxPreviousWakeTime contains the last past wake time, so it never runs away
* - if you suspend the task, when you resume it pxPreviousWakeTime will instantly
* catch up all skipped increments
* - it returns the number of increments added to pxPreviosWakeTime
*
* @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. Following this the variable is automatically updated.
*
* @param xTimeIncrement The cycle time period. The task will be unblocked at
* time *pxPreviousWakeTime + xTimeIncrement. Passing the same xTimeIncrement
* parameter value will cause the task to execute with a fixed interface period.
*
* @return Number of times xTimeIncrement has been added to pxPreviousWakeTime.
* It is 0 on the first call or if not enough ticks have been elapsed since the
* last call, 1 in normal circumstances or more than 1 if some period has been
* skipped for some reason (e.g. when the caller task is suspended for more than
* xTimeIncrement ticks).
*
* \defgroup xTaskPeriodicDelay xTaskPeriodicDelay
* \ingroup TaskCtrl
*/
TickType_t xTaskPeriodicDelay( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION;
/**
* task. h
* @code{c}

58
tasks.c
View file

@ -2374,6 +2374,64 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
#if ( INCLUDE_xTaskDelayUntil == 1 )
TickType_t xTaskPeriodicDelay( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement )
{
BaseType_t xAlreadyYielded;
TickType_t xIncrements, xTicksIncrements, xTicksToWait;
traceENTER_xTaskPeriodicDelay( pxPreviousWakeTime, xTimeIncrement );
configASSERT( pxPreviousWakeTime );
configASSERT( xTimeIncrement > 0 );
vTaskSuspendAll();
{
/* This plays well with overflows */
const TickType_t xTicksElapsed = xTickCount - *pxPreviousWakeTime;
configASSERT( uxSchedulerSuspended == 1U );
/* Number of increments to catch up: it could be 0 if
* not enough ticks have elapsed, 1 in the common case or
* more than 1 if the task has not been resumed in time */
xIncrements = xTicksElapsed / xTimeIncrement;
xTicksIncrements = xIncrements * xTimeIncrement;
/* Update to the last wake time */
*pxPreviousWakeTime += xTicksIncrements;
/* Ticks to the next wake time */
xTicksToWait = xTimeIncrement - ( xTicksElapsed - xTicksIncrements );
if( xTicksToWait > 0 )
{
prvAddCurrentTaskToDelayedList( xTicksToWait, pdFALSE );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
xAlreadyYielded = xTaskResumeAll();
/* Force a reschedule if xTaskResumeAll has not already done so, we may
* have put ourselves to sleep. */
if( xAlreadyYielded == pdFALSE )
{
taskYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
traceRETURN_xTaskPeriodicDelay( xIncrements );
return xIncrements;
}
BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement )
{