in timers.c [760:905]
static void prvProcessReceivedCommands( void )
{
DaemonTaskMessage_t xMessage;
Timer_t * pxTimer;
BaseType_t xTimerListsWereSwitched;
TickType_t xTimeNow;
while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */
{
#if ( INCLUDE_xTimerPendFunctionCall == 1 )
{
/* Negative commands are pended function calls rather than timer
* commands. */
if( xMessage.xMessageID < ( BaseType_t ) 0 )
{
const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters );
/* The timer uses the xCallbackParameters member to request a
* callback be executed. Check the callback is not NULL. */
configASSERT( pxCallback );
/* Call the function. */
pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* INCLUDE_xTimerPendFunctionCall */
/* Commands that are positive are timer commands rather than pended
* function calls. */
if( xMessage.xMessageID >= ( BaseType_t ) 0 )
{
/* The messages uses the xTimerParameters member to work on a
* software timer. */
pxTimer = xMessage.u.xTimerParameters.pxTimer;
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */
{
/* The timer is in a list, remove it. */
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue );
/* In this case the xTimerListsWereSwitched parameter is not used, but
* it must be present in the function call. prvSampleTimeNow() must be
* called after the message is received from xTimerQueue so there is no
* possibility of a higher priority task adding a message to the message
* queue with a time that is ahead of the timer daemon task (because it
* pre-empted the timer daemon task after the xTimeNow value was set). */
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
switch( xMessage.xMessageID )
{
case tmrCOMMAND_START:
case tmrCOMMAND_START_FROM_ISR:
case tmrCOMMAND_RESET:
case tmrCOMMAND_RESET_FROM_ISR:
/* Start or restart a timer. */
pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;
if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE )
{
/* The timer expired before it was added to the active
* timer list. Process it now. */
if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
{
prvReloadTimer( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow );
}
else
{
pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE );
}
/* Call the timer callback. */
traceTIMER_EXPIRED( pxTimer );
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
break;
case tmrCOMMAND_STOP:
case tmrCOMMAND_STOP_FROM_ISR:
/* The timer has already been removed from the active list. */
pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE );
break;
case tmrCOMMAND_CHANGE_PERIOD:
case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR:
pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;
pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue;
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
/* The new period does not really have a reference, and can
* be longer or shorter than the old one. The command time is
* therefore set to the current time, and as the period cannot
* be zero the next expiry time can only be in the future,
* meaning (unlike for the xTimerStart() case above) there is
* no fail case that needs to be handled here. */
( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
break;
case tmrCOMMAND_DELETE:
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
{
/* The timer has already been removed from the active list,
* just free up the memory if the memory was dynamically
* allocated. */
if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 )
{
vPortFree( pxTimer );
}
else
{
pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE );
}
}
#else /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
{
/* If dynamic allocation is not enabled, the memory
* could not have been dynamically allocated. So there is
* no need to free the memory - just mark the timer as
* "not active". */
pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE );
}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
break;
default:
/* Don't expect to get here. */
break;
}
}
}
}