Skip to content

Commit

Permalink
Fix: Two one line fixes, xTaskCheckForTimeOut() and ulTaskGenericNoti…
Browse files Browse the repository at this point in the history
…fyValueClear(). (FreeRTOS#82)

ulTaskGenericNotifyValueClear() returned the notification value of the
currently running task, not the target task.  Now it returns the
notification value of the target task.

Some users expected xTaskCheckForTimeOut() to clear the 'last wake time'
value each time a timeout occurred, whereas it only did that in one path.
It now clears the last wake time in all paths that return that a timeout
occurred.
  • Loading branch information
RichardBarry authored Aug 9, 2020
1 parent 2873610 commit 55da959
Showing 1 changed file with 31 additions and 30 deletions.
61 changes: 31 additions & 30 deletions tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
} \
\
/* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \
* the same priority get an equal share of the processor time. */ \
* the same priority get an equal share of the processor time. */ \
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \
uxTopReadyPriority = uxTopPriority; \
} /* taskSELECT_HIGHEST_PRIORITY_TASK */
Expand Down Expand Up @@ -954,7 +954,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
vListInitialiseItem( &( pxNewTCB->xEventListItem ) );

/* Set the pxNewTCB as a link back from the ListItem_t. This is so we can get
* back to the containing TCB from a generic item in a list. */
* back to the containing TCB from a generic item in a list. */
listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB );

/* Event lists are always in priority order. */
Expand Down Expand Up @@ -1287,7 +1287,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
{
/* The tick count has overflowed since this function was
* lasted called. In this case the only time we should ever
* actually delay is if the wake time has also overflowed,
* actually delay is if the wake time has also overflowed,
* and the wake time is greater than the tick time. When this
* is the case it is as if neither time had overflowed. */
if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) )
Expand Down Expand Up @@ -1519,16 +1519,16 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
UBaseType_t uxReturn, uxSavedInterruptState;

/* RTOS ports that support interrupt nesting have the concept of a
* maximum system call (or maximum API call) interrupt priority.
* Interrupts that are above the maximum system call priority are keep
* maximum system call (or maximum API call) interrupt priority.
* Interrupts that are above the maximum system call priority are keep
* permanently enabled, even when the RTOS kernel is in a critical section,
* but cannot make any calls to FreeRTOS API functions. If configASSERT()
* is defined in FreeRTOSConfig.h then
* portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
* failure if a FreeRTOS API function is called from an interrupt that has
* been assigned a priority above the configured maximum system call
* priority. Only FreeRTOS functions that end in FromISR can be called
* from interrupts that have been assigned a priority at or (logically)
* from interrupts that have been assigned a priority at or (logically)
* below the maximum system call interrupt priority. FreeRTOS maintains a
* separate interrupt safe API to ensure interrupt entry is as fast and as
* simple as possible. More information (albeit Cortex-M specific) is
Expand Down Expand Up @@ -1842,7 +1842,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
/* Has the task already been resumed from within an ISR? */
if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE )
{
/* Is it in the suspended list because it is in the Suspended
/* Is it in the suspended list because it is in the Suspended
* state, or because is is blocked with no timeout? */
if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) /*lint !e961. The cast is only redundant when NULL is used. */
{
Expand Down Expand Up @@ -1934,16 +1934,16 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
configASSERT( xTaskToResume );

/* RTOS ports that support interrupt nesting have the concept of a
* maximum system call (or maximum API call) interrupt priority.
* Interrupts that are above the maximum system call priority are keep
* maximum system call (or maximum API call) interrupt priority.
* Interrupts that are above the maximum system call priority are keep
* permanently enabled, even when the RTOS kernel is in a critical section,
* but cannot make any calls to FreeRTOS API functions. If configASSERT()
* is defined in FreeRTOSConfig.h then
* portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
* failure if a FreeRTOS API function is called from an interrupt that has
* been assigned a priority above the configured maximum system call
* priority. Only FreeRTOS functions that end in FromISR can be called
* from interrupts that have been assigned a priority at or (logically)
* from interrupts that have been assigned a priority at or (logically)
* below the maximum system call interrupt priority. FreeRTOS maintains a
* separate interrupt safe API to ensure interrupt entry is as fast and as
* simple as possible. More information (albeit Cortex-M specific) is
Expand Down Expand Up @@ -2123,7 +2123,7 @@ void vTaskEndScheduler( void )
{
/* Stop the scheduler interrupts and call the portable scheduler end
* routine so the original ISRs can be restored if necessary. The port
* layer must ensure interrupts enable bit is left in the correct state. */
* layer must ensure interrupts enable bit is left in the correct state. */
portDISABLE_INTERRUPTS();
xSchedulerRunning = pdFALSE;
vPortEndScheduler();
Expand Down Expand Up @@ -2270,7 +2270,7 @@ BaseType_t xTaskResumeAll( void )

/* If any ticks occurred while the scheduler was suspended then
* they should be processed now. This ensures the tick count does
* not slip, and that any delayed tasks are resumed at the correct
* not slip, and that any delayed tasks are resumed at the correct
* time. */
{
TickType_t xPendedCounts = xPendedTicks; /* Non-volatile copy. */
Expand Down Expand Up @@ -2355,7 +2355,7 @@ TickType_t xTaskGetTickCountFromISR( void )
* assigned a priority above the configured maximum system call priority.
* Only FreeRTOS functions that end in FromISR can be called from interrupts
* that have been assigned a priority at or (logically) below the maximum
* system call interrupt priority. FreeRTOS maintains a separate interrupt
* system call interrupt priority. FreeRTOS maintains a separate interrupt
* safe API to ensure interrupt entry is as fast and as simple as possible.
* More information (albeit Cortex-M specific) is provided on the following
* link: https://www.freertos.org/RTOS-Cortex-M3-M4.html */
Expand Down Expand Up @@ -2760,7 +2760,7 @@ BaseType_t xTaskIncrementTick( void )
}

/* See if this tick has made a timeout expire. Tasks are stored in
* the queue in the order of their wake time - meaning once one task
* the queue in the order of their wake time - meaning once one task
* has been found whose block time has not expired there is no need to
* look any further down the list. */
if( xConstTickCount >= xNextTaskUnblockTime )
Expand Down Expand Up @@ -2791,7 +2791,7 @@ BaseType_t xTaskIncrementTick( void )
/* It is not time to unblock this item yet, but the
* item value is the time at which the task at the head
* of the blocked list must be removed from the Blocked
* state - so record the item value in
* state - so record the item value in
* xNextTaskUnblockTime. */
xNextTaskUnblockTime = xItemValue;
break; /*lint !e9011 Code structure here is deedmed easier to understand with multiple breaks. */
Expand Down Expand Up @@ -3309,7 +3309,7 @@ void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut )
BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
TickType_t * const pxTicksToWait )
{
BaseType_t xReturn;
BaseType_t xReturn;

configASSERT( pxTimeOut );
configASSERT( pxTicksToWait );
Expand All @@ -3320,7 +3320,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
const TickType_t xConstTickCount = xTickCount;
const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering;

#if ( INCLUDE_xTaskAbortDelay == 1 )
#if( INCLUDE_xTaskAbortDelay == 1 )
if( pxCurrentTCB->ucDelayAborted != ( uint8_t ) pdFALSE )
{
/* The delay was aborted, which is not the same as a time out,
Expand Down Expand Up @@ -3350,6 +3350,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
* around and gone past again. This passed since vTaskSetTimeout()
* was called. */
xReturn = pdTRUE;
*pxTicksToWait = ( TickType_t ) 0;
}
else if( xElapsedTime < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */
{
Expand All @@ -3360,7 +3361,7 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
}
else
{
*pxTicksToWait = 0;
*pxTicksToWait = ( TickType_t ) 0;
xReturn = pdTRUE;
}
}
Expand Down Expand Up @@ -3492,7 +3493,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )

/* This conditional compilation should use inequality to 0, not equality
* to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when
* user defined low power mode implementations require
* user defined low power mode implementations require
* configUSE_TICKLESS_IDLE to be set to a value other than 1. */
#if ( configUSE_TICKLESS_IDLE != 0 )
{
Expand Down Expand Up @@ -3996,7 +3997,7 @@ static void prvResetNextTaskUnblockTime( void )
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
{
/* The new current delayed list is empty. Set xNextTaskUnblockTime to
* the maximum possible value so it is extremely unlikely that the
* the maximum possible value so it is extremely unlikely that the
* if( xTickCount >= xNextTaskUnblockTime ) test will pass until
* there is an item in the delayed list. */
xNextTaskUnblockTime = portMAX_DELAY;
Expand Down Expand Up @@ -4186,7 +4187,7 @@ static void prvResetNextTaskUnblockTime( void )
}

/* Disinherit the priority before adding the task into the
* new ready list. */
* new ready list. */
traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );
pxTCB->uxPriority = pxTCB->uxBasePriority;

Expand Down Expand Up @@ -4344,7 +4345,7 @@ static void prvResetNextTaskUnblockTime( void )
( pxCurrentTCB->uxCriticalNesting )++;

/* This is not the interrupt safe version of the enter critical
* function so assert() if it is being called from an interrupt
* function so assert() if it is being called from an interrupt
* context. Only API functions that end in "FromISR" can be used in an
* interrupt. Only assert if the critical nesting count is 1 to
* protect against recursive calls if the assert function also uses a
Expand Down Expand Up @@ -4775,7 +4776,7 @@ TickType_t uxTaskResetEventItemValue( void )
if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED )
{
/* Clear bits in the task's notification value as bits may get
* set by the notifying task or interrupt. This can be used to
* set by the notifying task or interrupt. This can be used to
* clear the value to zero. */
pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnEntry;

Expand Down Expand Up @@ -4984,16 +4985,16 @@ TickType_t uxTaskResetEventItemValue( void )
configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES );

/* RTOS ports that support interrupt nesting have the concept of a
* maximum system call (or maximum API call) interrupt priority.
* Interrupts that are above the maximum system call priority are keep
* maximum system call (or maximum API call) interrupt priority.
* Interrupts that are above the maximum system call priority are keep
* permanently enabled, even when the RTOS kernel is in a critical section,
* but cannot make any calls to FreeRTOS API functions. If configASSERT()
* is defined in FreeRTOSConfig.h then
* portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
* failure if a FreeRTOS API function is called from an interrupt that has
* been assigned a priority above the configured maximum system call
* priority. Only FreeRTOS functions that end in FromISR can be called
* from interrupts that have been assigned a priority at or (logically)
* from interrupts that have been assigned a priority at or (logically)
* below the maximum system call interrupt priority. FreeRTOS maintains a
* separate interrupt safe API to ensure interrupt entry is as fast and as
* simple as possible. More information (albeit Cortex-M specific) is
Expand Down Expand Up @@ -5119,16 +5120,16 @@ TickType_t uxTaskResetEventItemValue( void )
configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES );

/* RTOS ports that support interrupt nesting have the concept of a
* maximum system call (or maximum API call) interrupt priority.
* Interrupts that are above the maximum system call priority are keep
* maximum system call (or maximum API call) interrupt priority.
* Interrupts that are above the maximum system call priority are keep
* permanently enabled, even when the RTOS kernel is in a critical section,
* but cannot make any calls to FreeRTOS API functions. If configASSERT()
* is defined in FreeRTOSConfig.h then
* portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
* failure if a FreeRTOS API function is called from an interrupt that has
* been assigned a priority above the configured maximum system call
* priority. Only FreeRTOS functions that end in FromISR can be called
* from interrupts that have been assigned a priority at or (logically)
* from interrupts that have been assigned a priority at or (logically)
* below the maximum system call interrupt priority. FreeRTOS maintains a
* separate interrupt safe API to ensure interrupt entry is as fast and as
* simple as possible. More information (albeit Cortex-M specific) is
Expand Down Expand Up @@ -5245,7 +5246,7 @@ TickType_t uxTaskResetEventItemValue( void )
{
/* Return the notification as it was before the bits were cleared,
* then clear the bit mask. */
ulReturn = pxCurrentTCB->ulNotifiedValue[ uxIndexToClear ];
ulReturn = pxTCB->ulNotifiedValue[ uxIndexToClear ];
pxTCB->ulNotifiedValue[ uxIndexToClear ] &= ~ulBitsToClear;
}
taskEXIT_CRITICAL();
Expand Down

0 comments on commit 55da959

Please sign in to comment.