mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 03:34:32 +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;
|
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.
|
* Suspend a task.
|
||||||
*
|
*
|
||||||
|
@@ -1770,6 +1770,141 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
|||||||
taskEXIT_CRITICAL(&xTaskQueueMutex);
|
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 */
|
#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
|
// Temporarily raise current task priority to prevent a deadlock while
|
||||||
// waiting for IPC task to start on the other CPU
|
// waiting for IPC task to start on the other CPU
|
||||||
int old_prio = uxTaskPriorityGet(NULL);
|
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
|
// 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.
|
// disable cache there and block other tasks from executing.
|
||||||
s_flash_op_can_start = false;
|
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
|
// Disable scheduler on the current CPU
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
// Can now set the priority back to the normal one
|
// 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
|
// This is guaranteed to run on CPU <cpuid> because the other CPU is now
|
||||||
// occupied by highest priority task
|
// occupied by highest priority task
|
||||||
assert(xPortGetCoreID() == cpuid);
|
assert(xPortGetCoreID() == cpuid);
|
||||||
|
Reference in New Issue
Block a user