|
|
@@ -7,6 +7,7 @@
|
|
|
#pragma once
|
|
|
|
|
|
#include "sdkconfig.h"
|
|
|
+#include "idf_additions_inc.h"
|
|
|
|
|
|
/**
|
|
|
* This file will be included in `tasks.c` file, thus, it must NOT be included
|
|
|
@@ -393,3 +394,204 @@ void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, B
|
|
|
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
|
|
|
|
|
|
#endif // CONFIG_FREERTOS_SMP
|
|
|
+
|
|
|
+#if ( INCLUDE_vTaskPrioritySet == 1 )
|
|
|
+
|
|
|
+void prvTaskPriorityRaise( prvTaskSavedPriority_t * pxSavedPriority, UBaseType_t uxNewPriority )
|
|
|
+{
|
|
|
+ TCB_t * pxTCB;
|
|
|
+ UBaseType_t uxPriorityUsedOnEntry;
|
|
|
+
|
|
|
+ configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );
|
|
|
+
|
|
|
+ /* Ensure the new priority is valid. */
|
|
|
+ if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
|
|
|
+ {
|
|
|
+ uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
|
|
|
+ }
|
|
|
+
|
|
|
+#if CONFIG_FREERTOS_SMP
|
|
|
+ taskENTER_CRITICAL();
|
|
|
+#else
|
|
|
+ taskENTER_CRITICAL( &xKernelLock );
|
|
|
+#endif
|
|
|
+ {
|
|
|
+ pxTCB = prvGetTCBFromHandle( NULL );
|
|
|
+
|
|
|
+ #if ( configUSE_MUTEXES == 1 )
|
|
|
+ {
|
|
|
+ pxSavedPriority->uxPriority = pxTCB->uxPriority;
|
|
|
+ pxSavedPriority->uxBasePriority = pxTCB->uxBasePriority;
|
|
|
+
|
|
|
+ /* If uxNewPriority < uxBasePriority, then there is nothing else to
|
|
|
+ * do, as uxBasePriority is always <= uxPriority. */
|
|
|
+ if( uxNewPriority > pxTCB->uxBasePriority )
|
|
|
+ {
|
|
|
+ pxTCB->uxBasePriority = uxNewPriority;
|
|
|
+
|
|
|
+ /* Remember the task's current priority before attempting to
|
|
|
+ * change it. If the task's current priority is changed, it must
|
|
|
+ * be done so before moving the task between task lists) in order
|
|
|
+ * for the taskRESET_READY_PRIORITY() macro to function correctly. */
|
|
|
+ uxPriorityUsedOnEntry = pxTCB->uxPriority;
|
|
|
+
|
|
|
+ if( uxNewPriority > 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. */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If the task is in the blocked or suspended list we need do
|
|
|
+ * nothing more than change its 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->xStateListItem ) ) != pdFALSE )
|
|
|
+ {
|
|
|
+ /* The task is currently in its ready list - remove before
|
|
|
+ * adding it to its new ready list. As we are in a critical
|
|
|
+ * section we can do this even if the scheduler is suspended. */
|
|
|
+ if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( 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 );
|
|
|
+ }
|
|
|
+ prvAddTaskToReadyList( pxTCB );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #else /* if ( configUSE_MUTEXES == 1 ) */
|
|
|
+ {
|
|
|
+ pxSavedPriority->uxPriority = pxTCB->uxPriority;
|
|
|
+ if ( uxNewPriority > pxTCB->uxPriority)
|
|
|
+ {
|
|
|
+ vTaskPrioritySet( NULL, uxNewPriority );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+#if CONFIG_FREERTOS_SMP
|
|
|
+ taskEXIT_CRITICAL();
|
|
|
+#else
|
|
|
+ taskEXIT_CRITICAL( &xKernelLock );
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+void prvTaskPriorityRestore( prvTaskSavedPriority_t * pxSavedPriority )
|
|
|
+{
|
|
|
+ TCB_t * pxTCB;
|
|
|
+ UBaseType_t uxNewPriority;
|
|
|
+ UBaseType_t uxPriorityUsedOnEntry;
|
|
|
+ UBaseType_t uxBasePriorityUsedOnEntry;
|
|
|
+ BaseType_t xYieldRequired = pdFALSE;
|
|
|
+
|
|
|
+#if CONFIG_FREERTOS_SMP
|
|
|
+ taskENTER_CRITICAL();
|
|
|
+#else
|
|
|
+ taskENTER_CRITICAL( &xKernelLock );
|
|
|
+#endif
|
|
|
+ {
|
|
|
+ pxTCB = prvGetTCBFromHandle( NULL );
|
|
|
+
|
|
|
+ #if ( configUSE_MUTEXES == 1 )
|
|
|
+ {
|
|
|
+ /* If the saved uxBasePriority == the task's uxBasePriority, it means
|
|
|
+ * that prvTaskPriorityRaise() never raised the task's uxBasePriority.
|
|
|
+ * In that case, there is nothing else to do. */
|
|
|
+ if( pxSavedPriority->uxBasePriority != pxTCB->uxBasePriority )
|
|
|
+ {
|
|
|
+ uxBasePriorityUsedOnEntry = pxTCB->uxBasePriority;
|
|
|
+ pxTCB->uxBasePriority = pxSavedPriority->uxBasePriority;
|
|
|
+
|
|
|
+ /* Remember the task's current priority before attempting to
|
|
|
+ * change it. If the task's current priority is changed, it must
|
|
|
+ * be done so before moving the task between task lists in order
|
|
|
+ * for the taskRESET_READY_PRIORITY() macro to function correctly. */
|
|
|
+ uxPriorityUsedOnEntry = pxTCB->uxPriority;
|
|
|
+
|
|
|
+ /* Check if the task inherited a priority after prvTaskPriorityRaise().
|
|
|
+ * If this is the case, there is nothing else to do. The priority
|
|
|
+ * will be restored when the task disinherits its priority. */
|
|
|
+ if( pxTCB->uxPriority == uxBasePriorityUsedOnEntry )
|
|
|
+ {
|
|
|
+ if( pxTCB->uxMutexesHeld == 0 )
|
|
|
+ {
|
|
|
+ /* The task may have inherited a priority before prvTaskPriorityRaise()
|
|
|
+ * then disinherited a priority after prvTaskPriorityRaise().
|
|
|
+ * Thus we need set the uxPriority to the saved base priority
|
|
|
+ * so that the task's priority gets restored to the priority
|
|
|
+ * before any inheritance or raising. */
|
|
|
+ pxTCB->uxPriority = pxSavedPriority->uxBasePriority;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* The task may have inherited a priority before prvTaskPriorityRaise()
|
|
|
+ * was called. Thus, we need to restore uxPriority to the
|
|
|
+ * "saved uxPriority" so that the task still retains that
|
|
|
+ * inherited priority. */
|
|
|
+ pxTCB->uxPriority = pxSavedPriority->uxPriority;
|
|
|
+ }
|
|
|
+ uxNewPriority = pxTCB->uxPriority;
|
|
|
+
|
|
|
+ if( uxNewPriority < uxPriorityUsedOnEntry )
|
|
|
+ {
|
|
|
+ /* 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 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. */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If the task is in the blocked or suspended list we need do
|
|
|
+ * nothing more than change its 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->xStateListItem ) ) != pdFALSE )
|
|
|
+ {
|
|
|
+ /* The task is currently in its ready list - remove before
|
|
|
+ * adding it to its new ready list. As we are in a critical
|
|
|
+ * section we can do this even if the scheduler is suspended. */
|
|
|
+ if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( 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 );
|
|
|
+ }
|
|
|
+ prvAddTaskToReadyList( pxTCB );
|
|
|
+ }
|
|
|
+
|
|
|
+ if( xYieldRequired != pdFALSE )
|
|
|
+ {
|
|
|
+ taskYIELD_IF_USING_PREEMPTION();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #else /* if ( configUSE_MUTEXES == 1 ) */
|
|
|
+ {
|
|
|
+ vTaskPrioritySet( NULL, pxSavedPriority->uxPriority );
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+#if CONFIG_FREERTOS_SMP
|
|
|
+ taskEXIT_CRITICAL();
|
|
|
+#else
|
|
|
+ taskEXIT_CRITICAL( &xKernelLock );
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+#endif // ( INCLUDE_vTaskPrioritySet == 1 )
|