@ -317,10 +317,10 @@
# define taskATTRIBUTE_IS_IDLE ( UBaseType_t ) ( 1U << 0U )
# define taskATTRIBUTE_IS_IDLE ( UBaseType_t ) ( 1U << 0U )
# if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) )
# if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) )
# define portGET_CRITICAL_NESTING_COUNT( ) ( pxCurrentTCBs[ portGET_CORE_ID( ) ]->uxCriticalNesting )
# define portGET_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting )
# define portSET_CRITICAL_NESTING_COUNT( x ) ( pxCurrentTCBs[ portGET_CORE_ID( ) ]->uxCriticalNesting = ( x ) )
# define portSET_CRITICAL_NESTING_COUNT( x CoreID, x ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting = ( x ) )
# define portINCREMENT_CRITICAL_NESTING_COUNT( ) ( pxCurrentTCBs[ portGET_CORE_ID( ) ]->uxCriticalNesting++ )
# define portINCREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting++ )
# define portDECREMENT_CRITICAL_NESTING_COUNT( ) ( pxCurrentTCBs[ portGET_CORE_ID( ) ]->uxCriticalNesting-- )
# define portDECREMENT_CRITICAL_NESTING_COUNT( xCoreID ) ( pxCurrentTCBs[ ( xCoreID ) ]->uxCriticalNesting-- )
# endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) ) */
# endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( portCRITICAL_NESTING_IN_TCB == 1 ) ) */
# define taskBITS_PER_BYTE ( ( size_t ) 8 )
# define taskBITS_PER_BYTE ( ( size_t ) 8 )
@ -807,13 +807,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
{
{
UBaseType_t uxPrevCriticalNesting ;
UBaseType_t uxPrevCriticalNesting ;
const TCB_t * pxThisTCB ;
const TCB_t * pxThisTCB ;
BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID ( ) ;
/* This must only be called from within a task. */
/* This must only be called from within a task. */
portASSERT_IF_IN_ISR ( ) ;
portASSERT_IF_IN_ISR ( ) ;
/* This function is always called with interrupts disabled
/* This function is always called with interrupts disabled
* so this is safe . */
* so this is safe . */
pxThisTCB = pxCurrentTCBs [ portGET_CORE_ID ( ) ] ;
pxThisTCB = pxCurrentTCBs [ xCoreID ] ;
while ( pxThisTCB - > xTaskRunState = = taskTASK_SCHEDULED_TO_YIELD )
while ( pxThisTCB - > xTaskRunState = = taskTASK_SCHEDULED_TO_YIELD )
{
{
@ -825,11 +826,11 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
* the suspension and critical nesting counts , as well as release
* the suspension and critical nesting counts , as well as release
* and reacquire the correct locks . And then , do it all over again
* and reacquire the correct locks . And then , do it all over again
* if our state changed again during the reacquisition . */
* if our state changed again during the reacquisition . */
uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT ( ) ;
uxPrevCriticalNesting = portGET_CRITICAL_NESTING_COUNT ( xCoreID ) ;
if ( uxPrevCriticalNesting > 0U )
if ( uxPrevCriticalNesting > 0U )
{
{
portSET_CRITICAL_NESTING_COUNT ( 0U ) ;
portSET_CRITICAL_NESTING_COUNT ( xCoreID , 0U ) ;
portRELEASE_ISR_LOCK ( ) ;
portRELEASE_ISR_LOCK ( ) ;
}
}
else
else
@ -854,8 +855,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
portDISABLE_INTERRUPTS ( ) ;
portDISABLE_INTERRUPTS ( ) ;
portGET_TASK_LOCK ( ) ;
portGET_TASK_LOCK ( ) ;
portGET_ISR_LOCK ( ) ;
portGET_ISR_LOCK ( ) ;
xCoreID = ( BaseType_t ) portGET_CORE_ID ( ) ;
portSET_CRITICAL_NESTING_COUNT ( uxPrevCriticalNesting ) ;
portSET_CRITICAL_NESTING_COUNT ( xCoreID, uxPrevCriticalNesting ) ;
if ( uxPrevCriticalNesting = = 0U )
if ( uxPrevCriticalNesting = = 0U )
{
{
@ -874,13 +876,14 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
BaseType_t xCurrentCoreTaskPriority ;
BaseType_t xCurrentCoreTaskPriority ;
BaseType_t xLowestPriorityCore = ( BaseType_t ) - 1 ;
BaseType_t xLowestPriorityCore = ( BaseType_t ) - 1 ;
BaseType_t xCoreID ;
BaseType_t xCoreID ;
const BaseType_t xCurrentCoreID = portGET_CORE_ID ( ) ;
# if ( configRUN_MULTIPLE_PRIORITIES == 0 )
# if ( configRUN_MULTIPLE_PRIORITIES == 0 )
BaseType_t xYieldCount = 0 ;
BaseType_t xYieldCount = 0 ;
# endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */
# endif /* #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) */
/* This must be called from a critical section. */
/* This must be called from a critical section. */
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( ) > 0U ) ;
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( xCurrentCoreID ) > 0U ) ;
# if ( configRUN_MULTIPLE_PRIORITIES == 0 )
# if ( configRUN_MULTIPLE_PRIORITIES == 0 )
@ -969,11 +972,11 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
# if ( configRUN_MULTIPLE_PRIORITIES == 0 )
# if ( configRUN_MULTIPLE_PRIORITIES == 0 )
/* Verify that the calling core always yields to higher priority tasks. */
/* Verify that the calling core always yields to higher priority tasks. */
if ( ( ( pxCurrentTCBs [ portGET_CORE_ID ( ) ] - > uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) = = 0U ) & &
if ( ( ( pxCurrentTCBs [ xCurrentCoreID ] - > uxTaskAttributes & taskATTRIBUTE_IS_IDLE ) = = 0U ) & &
( pxTCB - > uxPriority > pxCurrentTCBs [ portGET_CORE_ID ( ) ] - > uxPriority ) )
( pxTCB - > uxPriority > pxCurrentTCBs [ xCurrentCoreID ] - > uxPriority ) )
{
{
configASSERT ( ( xYieldPendings [ portGET_CORE_ID ( ) ] = = pdTRUE ) | |
configASSERT ( ( xYieldPendings [ xCurrentCoreID ] = = pdTRUE ) | |
( taskTASK_IS_RUNNING ( pxCurrentTCBs [ portGET_CORE_ID ( ) ] ) = = pdFALSE ) ) ;
( taskTASK_IS_RUNNING ( pxCurrentTCBs [ xCurrentCoreID ] ) = = pdFALSE ) ) ;
}
}
# endif
# endif
}
}
@ -3880,7 +3883,7 @@ void vTaskSuspendAll( void )
ulState = portSET_INTERRUPT_MASK ( ) ;
ulState = portSET_INTERRUPT_MASK ( ) ;
/* This must never be called from inside a critical section. */
/* This must never be called from inside a critical section. */
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( ) = = 0 ) ;
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( portGET_CORE_ID ( ) ) = = 0 ) ;
/* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that
/* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that
* do not otherwise exhibit real time behaviour . */
* do not otherwise exhibit real time behaviour . */
@ -4003,8 +4006,7 @@ BaseType_t xTaskResumeAll( void )
* tasks from this list into their appropriate ready list . */
* tasks from this list into their appropriate ready list . */
taskENTER_CRITICAL ( ) ;
taskENTER_CRITICAL ( ) ;
{
{
BaseType_t xCoreID ;
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID ( ) ;
xCoreID = ( BaseType_t ) portGET_CORE_ID ( ) ;
/* If uxSchedulerSuspended is zero then this function does not match a
/* If uxSchedulerSuspended is zero then this function does not match a
* previous call to vTaskSuspendAll ( ) . */
* previous call to vTaskSuspendAll ( ) . */
@ -5187,7 +5189,7 @@ BaseType_t xTaskIncrementTick( void )
/* vTaskSwitchContext() must never be called from within a critical section.
/* vTaskSwitchContext() must never be called from within a critical section.
* This is not necessarily true for single core FreeRTOS , but it is for this
* This is not necessarily true for single core FreeRTOS , but it is for this
* SMP port . */
* SMP port . */
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( ) = = 0 ) ;
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) = = 0 ) ;
if ( uxSchedulerSuspended ! = ( UBaseType_t ) 0U )
if ( uxSchedulerSuspended ! = ( UBaseType_t ) 0U )
{
{
@ -6937,16 +6939,24 @@ static void prvResetNextTaskUnblockTime( void )
*/
*/
void vTaskYieldWithinAPI ( void )
void vTaskYieldWithinAPI ( void )
{
{
UBaseType_t ulState ;
traceENTER_vTaskYieldWithinAPI ( ) ;
traceENTER_vTaskYieldWithinAPI ( ) ;
if ( portGET_CRITICAL_NESTING_COUNT ( ) = = 0U )
ulState = portSET_INTERRUPT_MASK ( ) ;
{
portYIELD ( ) ;
}
else
{
{
xYieldPendings [ portGET_CORE_ID ( ) ] = pdTRUE ;
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID ( ) ;
if ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) = = 0U )
{
portYIELD ( ) ;
}
else
{
xYieldPendings [ xCoreID ] = pdTRUE ;
}
}
}
portCLEAR_INTERRUPT_MASK ( ulState ) ;
traceRETURN_vTaskYieldWithinAPI ( ) ;
traceRETURN_vTaskYieldWithinAPI ( ) ;
}
}
@ -6995,40 +7005,43 @@ static void prvResetNextTaskUnblockTime( void )
traceENTER_vTaskEnterCritical ( ) ;
traceENTER_vTaskEnterCritical ( ) ;
portDISABLE_INTERRUPTS ( ) ;
portDISABLE_INTERRUPTS ( ) ;
if ( xSchedulerRunning ! = pdFALSE )
{
{
if ( portGET_CRITICAL_NESTING_COUNT ( ) = = 0U )
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID ( ) ;
{
portGET_TASK_LOCK ( ) ;
portGET_ISR_LOCK ( ) ;
}
portINCREMENT_CRITICAL_NESTING_COUNT ( ) ;
/* This is not the interrupt safe version of the enter critical
if ( xSchedulerRunning ! = pdFALSE )
* 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
* critical section . */
if ( portGET_CRITICAL_NESTING_COUNT ( ) = = 1U )
{
{
portASSERT_IF_IN_ISR ( ) ;
if ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) = = 0U )
{
portGET_TASK_LOCK ( ) ;
portGET_ISR_LOCK ( ) ;
}
if ( uxSchedulerSuspended = = 0U )
portINCREMENT_CRITICAL_NESTING_COUNT ( xCoreID ) ;
/* This is not the interrupt safe version of the enter critical
* 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
* critical section . */
if ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) = = 1U )
{
{
/* The only time there would be a problem is if this is called
portASSERT_IF_IN_ISR ( ) ;
* before a context switch and vTaskExitCritical ( ) is called
* after pxCurrentTCB changes . Therefore this should not be
if ( uxSchedulerSuspended = = 0U )
* used within vTaskSwitchContext ( ) . */
{
prvCheckForRunStateChange ( ) ;
/* The only time there would be a problem is if this is called
* before a context switch and vTaskExitCritical ( ) is called
* after pxCurrentTCB changes . Therefore this should not be
* used within vTaskSwitchContext ( ) . */
prvCheckForRunStateChange ( ) ;
}
}
}
}
}
}
else
else
{
{
mtCOVERAGE_TEST_MARKER ( ) ;
mtCOVERAGE_TEST_MARKER ( ) ;
}
}
}
traceRETURN_vTaskEnterCritical ( ) ;
traceRETURN_vTaskEnterCritical ( ) ;
@ -7043,6 +7056,7 @@ static void prvResetNextTaskUnblockTime( void )
UBaseType_t vTaskEnterCriticalFromISR ( void )
UBaseType_t vTaskEnterCriticalFromISR ( void )
{
{
UBaseType_t uxSavedInterruptStatus = 0 ;
UBaseType_t uxSavedInterruptStatus = 0 ;
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID ( ) ;
traceENTER_vTaskEnterCriticalFromISR ( ) ;
traceENTER_vTaskEnterCriticalFromISR ( ) ;
@ -7050,12 +7064,12 @@ static void prvResetNextTaskUnblockTime( void )
{
{
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR ( ) ;
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR ( ) ;
if ( portGET_CRITICAL_NESTING_COUNT ( ) = = 0U )
if ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) = = 0U )
{
{
portGET_ISR_LOCK ( ) ;
portGET_ISR_LOCK ( ) ;
}
}
portINCREMENT_CRITICAL_NESTING_COUNT ( ) ;
portINCREMENT_CRITICAL_NESTING_COUNT ( xCoreID ) ;
}
}
else
else
{
{
@ -7119,28 +7133,30 @@ static void prvResetNextTaskUnblockTime( void )
void vTaskExitCritical ( void )
void vTaskExitCritical ( void )
{
{
const BaseType_t xCoreID = ( BaseType_t ) portGET_CORE_ID ( ) ;
traceENTER_vTaskExitCritical ( ) ;
traceENTER_vTaskExitCritical ( ) ;
if ( xSchedulerRunning ! = pdFALSE )
if ( xSchedulerRunning ! = pdFALSE )
{
{
/* If critical nesting count is zero then this function
/* If critical nesting count is zero then this function
* does not match a previous call to vTaskEnterCritical ( ) . */
* does not match a previous call to vTaskEnterCritical ( ) . */
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( ) > 0U ) ;
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) > 0U ) ;
/* This function should not be called in ISR. Use vTaskExitCriticalFromISR
/* This function should not be called in ISR. Use vTaskExitCriticalFromISR
* to exit critical section from ISR . */
* to exit critical section from ISR . */
portASSERT_IF_IN_ISR ( ) ;
portASSERT_IF_IN_ISR ( ) ;
if ( portGET_CRITICAL_NESTING_COUNT ( ) > 0U )
if ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) > 0U )
{
{
portDECREMENT_CRITICAL_NESTING_COUNT ( ) ;
portDECREMENT_CRITICAL_NESTING_COUNT ( xCoreID ) ;
if ( portGET_CRITICAL_NESTING_COUNT ( ) = = 0U )
if ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) = = 0U )
{
{
BaseType_t xYieldCurrentTask ;
BaseType_t xYieldCurrentTask ;
/* Get the xYieldPending stats inside the critical section. */
/* Get the xYieldPending stats inside the critical section. */
xYieldCurrentTask = xYieldPendings [ portGET_CORE_ID ( ) ] ;
xYieldCurrentTask = xYieldPendings [ xCoreID ] ;
portRELEASE_ISR_LOCK ( ) ;
portRELEASE_ISR_LOCK ( ) ;
portRELEASE_TASK_LOCK ( ) ;
portRELEASE_TASK_LOCK ( ) ;
@ -7180,19 +7196,23 @@ static void prvResetNextTaskUnblockTime( void )
void vTaskExitCriticalFromISR ( UBaseType_t uxSavedInterruptStatus )
void vTaskExitCriticalFromISR ( UBaseType_t uxSavedInterruptStatus )
{
{
BaseType_t xCoreID ;
traceENTER_vTaskExitCriticalFromISR ( uxSavedInterruptStatus ) ;
traceENTER_vTaskExitCriticalFromISR ( uxSavedInterruptStatus ) ;
if ( xSchedulerRunning ! = pdFALSE )
if ( xSchedulerRunning ! = pdFALSE )
{
{
xCoreID = ( BaseType_t ) portGET_CORE_ID ( ) ;
/* If critical nesting count is zero then this function
/* If critical nesting count is zero then this function
* does not match a previous call to vTaskEnterCritical ( ) . */
* does not match a previous call to vTaskEnterCritical ( ) . */
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( ) > 0U ) ;
configASSERT ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) > 0U ) ;
if ( portGET_CRITICAL_NESTING_COUNT ( ) > 0U )
if ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) > 0U )
{
{
portDECREMENT_CRITICAL_NESTING_COUNT ( ) ;
portDECREMENT_CRITICAL_NESTING_COUNT ( xCoreID ) ;
if ( portGET_CRITICAL_NESTING_COUNT ( ) = = 0U )
if ( portGET_CRITICAL_NESTING_COUNT ( xCoreID ) = = 0U )
{
{
portRELEASE_ISR_LOCK ( ) ;
portRELEASE_ISR_LOCK ( ) ;
portCLEAR_INTERRUPT_MASK_FROM_ISR ( uxSavedInterruptStatus ) ;
portCLEAR_INTERRUPT_MASK_FROM_ISR ( uxSavedInterruptStatus ) ;