mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
Add vTaskPrioritySetCurrent()
This commit is contained in:
@ -974,6 +974,19 @@ eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
*/
|
||||
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* Set the current priority of any task.
|
||||
*
|
||||
* This function sets the current priority of a task, and does not modify the
|
||||
* base priority at all.
|
||||
*
|
||||
* @param xTask Handle to the task for which the priority is being set.
|
||||
* Passing a NULL handle results in the priority of the calling task being set.
|
||||
*
|
||||
* @param uxNewPriority The priority to which the task will be set.
|
||||
*/
|
||||
void vTaskPrioritySetCurrent( TaskHandle_t xTask, UBaseType_t uxNewPriority )
|
||||
|
||||
/**
|
||||
* Suspend a task.
|
||||
*
|
||||
|
@ -1770,6 +1770,141 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
||||
taskEXIT_CRITICAL(&xTaskQueueMutex);
|
||||
}
|
||||
|
||||
void vTaskPrioritySetCurrent( TaskHandle_t xTask, UBaseType_t uxNewPriority )
|
||||
{
|
||||
TCB_t *pxTCB;
|
||||
UBaseType_t uxCurrentPriority, uxPriorityUsedOnEntry;
|
||||
BaseType_t xYieldRequired = pdFALSE;
|
||||
|
||||
configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );
|
||||
|
||||
/* Ensure the new priority is valid. */
|
||||
if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
|
||||
{
|
||||
uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
{
|
||||
/* If null is passed in here then it is the priority of the calling
|
||||
task that is being changed. */
|
||||
pxTCB = prvGetTCBFromHandle( xTask );
|
||||
|
||||
traceTASK_PRIORITY_SET( pxTCB, uxNewPriority );
|
||||
|
||||
uxCurrentPriority = pxTCB->uxPriority;
|
||||
|
||||
if( uxCurrentPriority != uxNewPriority )
|
||||
{
|
||||
/* The priority change may have readied a task of higher
|
||||
priority than the calling task. */
|
||||
if( uxNewPriority > uxCurrentPriority )
|
||||
{
|
||||
if( pxTCB != pxCurrentTCB[ xPortGetCoreID() ] )
|
||||
{
|
||||
/* The priority of a task other than the currently
|
||||
running task is being raised. Is the priority being
|
||||
raised above that of the running task? */
|
||||
if ( tskCAN_RUN_HERE(pxTCB->xCoreID) && uxNewPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority )
|
||||
{
|
||||
xYieldRequired = pdTRUE;
|
||||
}
|
||||
else if ( pxTCB->xCoreID != xPortGetCoreID() )
|
||||
{
|
||||
taskYIELD_OTHER_CORE( pxTCB->xCoreID, uxNewPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The priority of the running task is being raised,
|
||||
but the running task must already be the highest
|
||||
priority task able to run so no yield is required. */
|
||||
}
|
||||
}
|
||||
else if( pxTCB == pxCurrentTCB[ xPortGetCoreID() ] )
|
||||
{
|
||||
/* Setting the priority of the running task down means
|
||||
there may now be another task of higher priority that
|
||||
is ready to execute. */
|
||||
xYieldRequired = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Setting the priority of any other task down does not
|
||||
require a yield as the running task must be above the
|
||||
new priority of the task being modified. */
|
||||
}
|
||||
|
||||
/* Remember the ready list the task might be referenced from
|
||||
before its uxPriority member is changed so the
|
||||
taskRESET_READY_PRIORITY() macro can function correctly. */
|
||||
uxPriorityUsedOnEntry = pxTCB->uxPriority;
|
||||
|
||||
pxTCB->uxPriority = uxNewPriority;
|
||||
|
||||
/* Only reset the event list item value if the value is not
|
||||
being used for anything else. */
|
||||
if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL )
|
||||
{
|
||||
listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* If the task is in the blocked or suspended list we need do
|
||||
nothing more than change it's priority variable. However, if
|
||||
the task is in a ready list it needs to be removed and placed
|
||||
in the list appropriate to its new priority. */
|
||||
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
|
||||
{
|
||||
/* The task is currently in its ready list - remove before adding
|
||||
it to it's new ready list. As we are in a critical section we
|
||||
can do this even if the scheduler is suspended. */
|
||||
if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* It is known that the task is in its ready list so
|
||||
there is no need to check again and the port level
|
||||
reset macro can be called directly. */
|
||||
portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
prvReaddTaskToReadyList( pxTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
if( xYieldRequired == pdTRUE )
|
||||
{
|
||||
taskYIELD_IF_USING_PREEMPTION();
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
/* Remove compiler warning about unused variables when the port
|
||||
optimised task selection is not being used. */
|
||||
( void ) uxPriorityUsedOnEntry;
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL(&xTaskQueueMutex);
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_vTaskPrioritySet */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -113,7 +113,7 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu()
|
||||
// Temporarily raise current task priority to prevent a deadlock while
|
||||
// waiting for IPC task to start on the other CPU
|
||||
int old_prio = uxTaskPriorityGet(NULL);
|
||||
vTaskPrioritySet(NULL, configMAX_PRIORITIES - 1);
|
||||
vTaskPrioritySetCurrent(NULL, configMAX_PRIORITIES - 1);
|
||||
// Signal to the spi_flash_op_block_task on the other CPU that we need it to
|
||||
// disable cache there and block other tasks from executing.
|
||||
s_flash_op_can_start = false;
|
||||
@ -126,7 +126,7 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu()
|
||||
// Disable scheduler on the current CPU
|
||||
vTaskSuspendAll();
|
||||
// Can now set the priority back to the normal one
|
||||
vTaskPrioritySet(NULL, old_prio);
|
||||
vTaskPrioritySetCurrent(NULL, old_prio);
|
||||
// This is guaranteed to run on CPU <cpuid> because the other CPU is now
|
||||
// occupied by highest priority task
|
||||
assert(xPortGetCoreID() == cpuid);
|
||||
|
Reference in New Issue
Block a user