Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/FreeRTOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -1770,6 +1770,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
Expand Down
37 changes: 37 additions & 0 deletions include/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,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 interval.
*
* @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,
Comment thread
kstribrnAmzn marked this conversation as resolved.
const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION;

/**
* task. h
* @code{c}
Expand Down
49 changes: 49 additions & 0 deletions tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -2362,6 +2362,55 @@

#if ( INCLUDE_xTaskDelayUntil == 1 )

TickType_t xTaskPeriodicDelay( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement )
{
TickType_t xIncrements, xTicksIncrements, xTicksToWait;

Check warning on line 2368 in tasks.c

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define each identifier in a dedicated statement.

See more on https://sonarcloud.io/project/issues?id=FreeRTOS_FreeRTOS-Kernel&issues=AZ-4-92ZlRq_5BkED0gq&open=AZ-4-92ZlRq_5BkED0gq&pullRequest=1368

traceENTER_xTaskPeriodicDelay( pxPreviousWakeTime, xTimeIncrement );

configASSERT( pxPreviousWakeTime );
configASSERT( ( xTimeIncrement > 0U ) );

vTaskSuspendAll();
{
/* As long as everything is the same type, 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;
Comment thread
kstribrnAmzn marked this conversation as resolved.

/* Update to the last wake time */
*pxPreviousWakeTime += xTicksIncrements;

/* Ticks to the next wake time */
xTicksToWait = xTimeIncrement - ( xTicksElapsed - xTicksIncrements );

prvAddCurrentTaskToDelayedList( xTicksToWait, pdFALSE );
}

/* Force a reschedule if xTaskResumeAll has not already done so, we may
* have put ourselves to sleep. */
if( xTaskResumeAll() == pdFALSE )
{
taskYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}

traceRETURN_xTaskPeriodicDelay( xIncrements );

return xIncrements;
}


BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement )
{
Expand Down
Loading