diff --git a/components/freertos/esp_additions/freertos_compatibility.c b/components/freertos/esp_additions/freertos_compatibility.c index 009fde8b8e..66211af185 100644 --- a/components/freertos/esp_additions/freertos_compatibility.c +++ b/components/freertos/esp_additions/freertos_compatibility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,23 +12,26 @@ * This file maintains these legacy APIs until the next ESP-IDF major release. * * Todo: Clean up for ESP-IDF v6.0 (IDF-8144) -*/ + */ #include "FreeRTOS.h" #include "queue.h" #include "semphr.h" -BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xPeek ) +BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait, + const BaseType_t xPeek ) { - if ( xPeek == pdTRUE ) - { - return xQueuePeek( xQueue, pvBuffer, xTicksToWait ); - } + if( xPeek == pdTRUE ) + { + return xQueuePeek( xQueue, pvBuffer, xTicksToWait ); + } - if ( pvBuffer == NULL ) - { - return xQueueSemaphoreTake( xQueue, xTicksToWait ); - } + if( pvBuffer == NULL ) + { + return xQueueSemaphoreTake( xQueue, xTicksToWait ); + } - return xQueueReceive( xQueue, pvBuffer, xTicksToWait ); + return xQueueReceive( xQueue, pvBuffer, xTicksToWait ); } diff --git a/components/freertos/esp_additions/freertos_tasks_c_additions.h b/components/freertos/esp_additions/freertos_tasks_c_additions.h index 31e41c3496..6dbff63ead 100644 --- a/components/freertos/esp_additions/freertos_tasks_c_additions.h +++ b/components/freertos/esp_additions/freertos_tasks_c_additions.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,9 @@ #include "sdkconfig.h" #include "freertos/idf_additions.h" +#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT + #include "freertos/task_snapshot.h" +#endif /* CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT */ #include "esp_private/freertos_idf_additions_priv.h" /** @@ -18,23 +21,401 @@ * additional API. */ -/* ------------------------------------------------- Static asserts ---------------------------------------------------- - * - * ------------------------------------------------------------------------------------------------------------------ */ +/* ------------------------------------------------- Static Asserts ------------------------------------------------- */ /** * Both StaticTask_t and TCB_t structures are provided by FreeRTOS sources. * This is just an additional check of the consistency of these structures. */ +_Static_assert( offsetof( StaticTask_t, pxDummy6 ) == offsetof( TCB_t, pxStack ) ); +_Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfStack ) ); +#if CONFIG_FREERTOS_SMP + _Static_assert( tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "CONFIG_FREERTOS_NO_AFFINITY must be the same as tskNO_AFFINITY" ); +#endif /* CONFIG_FREERTOS_SMP */ -_Static_assert(offsetof( StaticTask_t, pxDummy6 ) == offsetof( TCB_t, pxStack )); -_Static_assert(offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfStack )); +/* -------------------------------------------------- Task Creation ------------------------------------------------- */ -/* ----------------------------------------------------- Newlib -------------------------------------------------------- - * - * ------------------------------------------------------------------------------------------------------------------ */ +#if CONFIG_FREERTOS_SMP + + BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + const BaseType_t xCoreID ) + { + BaseType_t ret; + + #if ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) + { + /* Convert xCoreID into an affinity mask */ + UBaseType_t uxCoreAffinityMask; + + if( xCoreID == tskNO_AFFINITY ) + { + uxCoreAffinityMask = tskNO_AFFINITY; + } + else + { + uxCoreAffinityMask = ( 1 << xCoreID ); + } + + ret = xTaskCreateAffinitySet( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, uxCoreAffinityMask, pxCreatedTask ); + } + #else /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */ + { + ret = xTaskCreate( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + } + #endif /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */ + return ret; + } + +#endif /* CONFIG_FREERTOS_SMP */ +/*----------------------------------------------------------*/ + +#if ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer, + const BaseType_t xCoreID ) + { + TaskHandle_t ret; + + #if ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) + { + /* Convert xCoreID into an affinity mask */ + UBaseType_t uxCoreAffinityMask; + + if( xCoreID == tskNO_AFFINITY ) + { + uxCoreAffinityMask = tskNO_AFFINITY; + } + else + { + uxCoreAffinityMask = ( 1 << xCoreID ); + } + + ret = xTaskCreateStaticAffinitySet( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, uxCoreAffinityMask ); + } + #else /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */ + { + ret = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + } + #endif /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */ + return ret; + } + +#endif /* CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + +/* ------------------------------------------------- Task Utilities ------------------------------------------------- */ + +#if CONFIG_FREERTOS_SMP + + TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID ) + { + TaskHandle_t xTaskHandleTemp; + + assert( xCoreID >= 0 && xCoreID < configNUM_CORES ); + taskENTER_CRITICAL(); + xTaskHandleTemp = ( TaskHandle_t ) pxCurrentTCBs[ xCoreID ]; + taskEXIT_CRITICAL(); + return xTaskHandleTemp; + } + +#endif /* CONFIG_FREERTOS_SMP */ +/*----------------------------------------------------------*/ + +#if CONFIG_FREERTOS_SMP + + TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID ) + { + assert( xCoreID >= 0 && xCoreID < configNUM_CORES ); + return ( TaskHandle_t ) xIdleTaskHandle[ xCoreID ]; + } + +#endif /* CONFIG_FREERTOS_SMP */ +/*----------------------------------------------------------*/ + +#if CONFIG_FREERTOS_SMP + + BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) + { + taskENTER_CRITICAL(); + UBaseType_t uxCoreAffinityMask; + #if ( configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 ) + TCB_t * pxTCB = prvGetTCBFromHandle( xTask ); + uxCoreAffinityMask = pxTCB->uxCoreAffinityMask; + #else + uxCoreAffinityMask = tskNO_AFFINITY; + #endif + taskEXIT_CRITICAL(); + BaseType_t ret; + + /* If the task is not pinned to a particular core, treat it as tskNO_AFFINITY */ + if( uxCoreAffinityMask & ( uxCoreAffinityMask - 1 ) ) /* If more than one bit set */ + { + ret = tskNO_AFFINITY; + } + else + { + int index_plus_one = __builtin_ffs( uxCoreAffinityMask ); + assert( index_plus_one >= 1 ); + ret = index_plus_one - 1; + } + + return ret; + } + +#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 ( configUSE_MUTEXES == 1 ) */ + } + #if CONFIG_FREERTOS_SMP + taskEXIT_CRITICAL(); + #else + taskEXIT_CRITICAL( &xKernelLock ); + #endif + } + +#endif /* INCLUDE_vTaskPrioritySet == 1 */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + 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 ( configUSE_MUTEXES == 1 ) */ + } + #if CONFIG_FREERTOS_SMP + taskEXIT_CRITICAL(); + #else + taskEXIT_CRITICAL( &xKernelLock ); + #endif + } + +#endif /* ( INCLUDE_vTaskPrioritySet == 1 ) */ +/*----------------------------------------------------------*/ + +/* --------------------------------------------- TLSP Deletion Callbacks -------------------------------------------- */ + +#if ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) + + void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue, + TlsDeleteCallbackFunction_t pvDelCallback ) + { + /* Verify that the offsets of pvThreadLocalStoragePointers and pvDummy15 match. */ + /* pvDummy15 is part of the StaticTask_t struct and is used to access the TLSPs */ + /* while deletion. */ + _Static_assert( offsetof( StaticTask_t, pvDummy15 ) == offsetof( TCB_t, pvThreadLocalStoragePointers ), "Offset of pvDummy15 must match the offset of pvThreadLocalStoragePointers" ); + + /*Set the local storage pointer first */ + vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + + /*Set the deletion callback at an offset of configNUM_THREAD_LOCAL_STORAGE_POINTERS/2 */ + vTaskSetThreadLocalStoragePointer( xTaskToSet, ( xIndex + ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ), pvDelCallback ); + } + +#endif /* CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */ +/*----------------------------------------------------------*/ + +/* ----------------------------------------------------- Newlib ----------------------------------------------------- */ #if ( configUSE_NEWLIB_REENTRANT == 1 ) + /** * @brief Get reentrancy structure of the current task * @@ -44,51 +425,54 @@ _Static_assert(offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSta * * @return Pointer to a the (current taks's)/(globa) reent struct */ -struct _reent *__getreent(void) -{ - // No lock needed because if this changes, we won't be running anymore. - TCB_t *pxCurTask = xTaskGetCurrentTaskHandle(); - struct _reent *ret; - if (pxCurTask == NULL) { - // No task running. Return global struct. - ret = _GLOBAL_REENT; - } else { - // We have a task; return its reentrant struct. - ret = &pxCurTask->xNewLib_reent; + struct _reent * __getreent( void ) + { + /* No lock needed because if this changes, we won't be running anymore. */ + TCB_t * pxCurTask = xTaskGetCurrentTaskHandle(); + struct _reent * ret; + + if( pxCurTask == NULL ) + { + /* No task running. Return global struct. */ + ret = _GLOBAL_REENT; + } + else + { + /* We have a task; return its reentrant struct. */ + ret = &pxCurTask->xNewLib_reent; + } + + return ret; } - return ret; -} -#endif // configUSE_NEWLIB_REENTRANT == 1 -/* -------------------------------------------------- Task Snapshot ---------------------------------------------------- - * - * ------------------------------------------------------------------------------------------------------------------ */ +#endif /* configUSE_NEWLIB_REENTRANT == 1 */ -#include "freertos/task_snapshot.h" +/* -------------------------------------------------- Task Snapshot ------------------------------------------------- */ /** * @brief List of all task lists in FreeRTOS * * @note There are currently differing number of task list between SMP FreeRTOS and ESP-IDF FreeRTOS */ -static List_t *non_ready_task_lists[] = { +static List_t * non_ready_task_lists[] = { #ifdef CONFIG_FREERTOS_SMP &xPendingReadyList, - #else - &xPendingReadyList[0], + #else /* CONFIG_FREERTOS_SMP */ + &xPendingReadyList[ 0 ], #ifndef CONFIG_FREERTOS_UNICORE - &xPendingReadyList[1], - #endif // CONFIG_FREERTOS_UNICORE - #endif //CONFIG_FREERTOS_SMP + &xPendingReadyList[ 1 ], + #endif /* CONFIG_FREERTOS_UNICORE */ + #endif /* CONFIG_FREERTOS_SMP */ &xDelayedTaskList1, &xDelayedTaskList2, - #if( INCLUDE_vTaskDelete == 1 ) + #if ( INCLUDE_vTaskDelete == 1 ) &xTasksWaitingTermination, #endif - #if( INCLUDE_vTaskSuspend == 1 ) + #if ( INCLUDE_vTaskSuspend == 1 ) &xSuspendedTaskList, #endif }; +/*----------------------------------------------------------*/ /** * @brief Get the next task list to traverse @@ -105,49 +489,57 @@ static List_t *non_ready_task_lists[] = { * @param pxCurTaskList Previously traversed task list (or NULL if obtaining the first task list) * @return List_t* The next task list to traverse (or NULL of all task lists have been traversed) */ -static List_t *pxGetNextTaskList(List_t *pxCurTaskList) +static List_t * pxGetNextTaskList( List_t * pxCurTaskList ) { - List_t *pxNextTaskList = NULL; + List_t * pxNextTaskList = NULL; - // No Current List. Start from the highest priority ready task list - if (pxCurTaskList == NULL) + /* No Current List. Start from the highest priority ready task list */ + if( pxCurTaskList == NULL ) { - pxNextTaskList = &pxReadyTasksLists[configMAX_PRIORITIES - 1]; + pxNextTaskList = &pxReadyTasksLists[ configMAX_PRIORITIES - 1 ]; } - // Current list is one of the ready task lists. Find the current priority, and return the next lower priority ready task list - else if (pxCurTaskList >= &pxReadyTasksLists[0] && pxCurTaskList <= &pxReadyTasksLists[configMAX_PRIORITIES - 1] ) + /* Current list is one of the ready task lists. Find the current priority, and return the next lower priority ready task list */ + else if( ( pxCurTaskList >= &pxReadyTasksLists[ 0 ] ) && ( pxCurTaskList <= &pxReadyTasksLists[ configMAX_PRIORITIES - 1 ] ) ) { - // Find the current priority + /* Find the current priority */ int cur_priority; - for (cur_priority = configMAX_PRIORITIES - 1; cur_priority >= 0; cur_priority--) { - if (pxCurTaskList == &pxReadyTasksLists[cur_priority]) { + + for( cur_priority = configMAX_PRIORITIES - 1; cur_priority >= 0; cur_priority-- ) + { + if( pxCurTaskList == &pxReadyTasksLists[ cur_priority ] ) + { break; } } - // Return the ready task list at (cur_priority - 1), or the pending ready task list - if (cur_priority > 0) + + /* Return the ready task list at (cur_priority - 1), or the pending ready task list */ + if( cur_priority > 0 ) { - pxNextTaskList = &pxReadyTasksLists[cur_priority - 1]; + pxNextTaskList = &pxReadyTasksLists[ cur_priority - 1 ]; } - // We've reached the end of the Ready Task Lists. We get the next list from the non-ready task lists - else if (cur_priority == 0) + /* We've reached the end of the Ready Task Lists. We get the next list from the non-ready task lists */ + else if( cur_priority == 0 ) { - pxNextTaskList = non_ready_task_lists[0]; + pxNextTaskList = non_ready_task_lists[ 0 ]; } else { - abort(); // This should never occur + abort(); /* This should never occur */ } } - // Current list is one of the non-ready task lists. Fetch the next non-ready task list - if (pxNextTaskList == NULL) { + /* Current list is one of the non-ready task lists. Fetch the next non-ready task list */ + if( pxNextTaskList == NULL ) + { int cur_list_idx; - const int num_non_ready_task_lists = (sizeof(non_ready_task_lists) / sizeof(List_t *)); - // Note: - 1 so that if the current list is the last on non_ready_task_lists[], the next list will return NULL - for (cur_list_idx = 0; cur_list_idx < num_non_ready_task_lists - 1; cur_list_idx++) { - if (pxCurTaskList == non_ready_task_lists[cur_list_idx]) { - pxNextTaskList = non_ready_task_lists[cur_list_idx + 1]; + const int num_non_ready_task_lists = ( sizeof( non_ready_task_lists ) / sizeof( List_t * ) ); + + /* Note: - 1 so that if the current list is the last on non_ready_task_lists[], the next list will return NULL */ + for( cur_list_idx = 0; cur_list_idx < num_non_ready_task_lists - 1; cur_list_idx++ ) + { + if( pxCurTaskList == non_ready_task_lists[ cur_list_idx ] ) + { + pxNextTaskList = non_ready_task_lists[ cur_list_idx + 1 ]; break; } } @@ -155,99 +547,132 @@ static List_t *pxGetNextTaskList(List_t *pxCurTaskList) return pxNextTaskList; } +/*----------------------------------------------------------*/ TaskHandle_t pxTaskGetNext( TaskHandle_t pxTask ) { - TCB_t *pxTCB = (TCB_t *)pxTask; - // Check current task is valid - if (pxTCB != NULL && !portVALID_TCB_MEM(pxTCB)) { + TCB_t * pxTCB = ( TCB_t * ) pxTask; + + /* Check current task is valid */ + if( ( pxTCB != NULL ) && !portVALID_TCB_MEM( pxTCB ) ) + { return NULL; } - List_t *pxCurTaskList; - const ListItem_t *pxCurListItem; - if (pxTCB == NULL) { - // Starting traversal for the first time - pxCurTaskList = pxGetNextTaskList(NULL); - pxCurListItem = listGET_END_MARKER(pxCurTaskList); - } else { - // Continuing traversal - pxCurTaskList = listLIST_ITEM_CONTAINER(&pxTCB->xStateListItem); + List_t * pxCurTaskList; + const ListItem_t * pxCurListItem; + + if( pxTCB == NULL ) + { + /* Starting traversal for the first time */ + pxCurTaskList = pxGetNextTaskList( NULL ); + pxCurListItem = listGET_END_MARKER( pxCurTaskList ); + } + else + { + /* Continuing traversal */ + pxCurTaskList = listLIST_ITEM_CONTAINER( &pxTCB->xStateListItem ); pxCurListItem = &pxTCB->xStateListItem; } - ListItem_t *pxNextListItem = NULL; - if (pxCurListItem->pxNext == listGET_END_MARKER(pxCurTaskList)) { - List_t *pxNextTaskList = pxGetNextTaskList(pxCurTaskList); - while (pxNextTaskList != NULL) { - if (!listLIST_IS_EMPTY(pxNextTaskList)) { - // Get the first item in the next task list - pxNextListItem = listGET_HEAD_ENTRY(pxNextTaskList); + ListItem_t * pxNextListItem = NULL; + + if( pxCurListItem->pxNext == listGET_END_MARKER( pxCurTaskList ) ) + { + List_t * pxNextTaskList = pxGetNextTaskList( pxCurTaskList ); + + while( pxNextTaskList != NULL ) + { + if( !listLIST_IS_EMPTY( pxNextTaskList ) ) + { + /* Get the first item in the next task list */ + pxNextListItem = listGET_HEAD_ENTRY( pxNextTaskList ); break; } - // Task list is empty. Get the next task list - pxNextTaskList = pxGetNextTaskList(pxNextTaskList); + + /* Task list is empty. Get the next task list */ + pxNextTaskList = pxGetNextTaskList( pxNextTaskList ); } - } else { - //There are still more items in the current task list. Get the next item - pxNextListItem = listGET_NEXT(pxCurListItem); + } + else + { + /*There are still more items in the current task list. Get the next item */ + pxNextListItem = listGET_NEXT( pxCurListItem ); } - TCB_t *pxNextTCB; - if (pxNextListItem == NULL) { + TCB_t * pxNextTCB; + + if( pxNextListItem == NULL ) + { pxNextTCB = NULL; - } else { - pxNextTCB = (TCB_t *)listGET_LIST_ITEM_OWNER(pxNextListItem); + } + else + { + pxNextTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxNextListItem ); } return pxNextTCB; } +/*----------------------------------------------------------*/ -BaseType_t vTaskGetSnapshot( TaskHandle_t pxTask, TaskSnapshot_t *pxTaskSnapshot ) +BaseType_t vTaskGetSnapshot( TaskHandle_t pxTask, + TaskSnapshot_t * pxTaskSnapshot ) { - if (portVALID_TCB_MEM(pxTask) == false || pxTaskSnapshot == NULL) { + if( ( portVALID_TCB_MEM( pxTask ) == false ) || ( pxTaskSnapshot == NULL ) ) + { return pdFALSE; } - TCB_t *pxTCB = (TCB_t *)pxTask; + TCB_t * pxTCB = ( TCB_t * ) pxTask; pxTaskSnapshot->pxTCB = pxTCB; - pxTaskSnapshot->pxTopOfStack = (StackType_t *)pxTCB->pxTopOfStack; - pxTaskSnapshot->pxEndOfStack = (StackType_t *)pxTCB->pxEndOfStack; + pxTaskSnapshot->pxTopOfStack = ( StackType_t * ) pxTCB->pxTopOfStack; + pxTaskSnapshot->pxEndOfStack = ( StackType_t * ) pxTCB->pxEndOfStack; return pdTRUE; } +/*----------------------------------------------------------*/ -UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArrayLength, UBaseType_t * const pxTCBSize ) +UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, + const UBaseType_t uxArrayLength, + UBaseType_t * const pxTCBSize ) { UBaseType_t uxArrayNumFilled = 0; - //Traverse all of the tasks lists - List_t *pxCurTaskList = pxGetNextTaskList(NULL); //Get the first task list - while (pxCurTaskList != NULL && uxArrayNumFilled < uxArrayLength) { - if (!listLIST_IS_EMPTY(pxCurTaskList)) { - const ListItem_t *pxCurListItem; - //Walk each task on the current task list - pxCurListItem = listGET_HEAD_ENTRY(pxCurTaskList); - while (pxCurListItem != listGET_END_MARKER(pxCurTaskList)) { - TCB_t *pxTCB = (TCB_t *)listGET_LIST_ITEM_OWNER(pxCurListItem); - vTaskGetSnapshot((TaskHandle_t)pxTCB, &pxTaskSnapshotArray[uxArrayNumFilled]); + /*Traverse all of the tasks lists */ + List_t * pxCurTaskList = pxGetNextTaskList( NULL ); /*Get the first task list */ + + while( pxCurTaskList != NULL && uxArrayNumFilled < uxArrayLength ) + { + if( !listLIST_IS_EMPTY( pxCurTaskList ) ) + { + const ListItem_t * pxCurListItem; + /*Walk each task on the current task list */ + pxCurListItem = listGET_HEAD_ENTRY( pxCurTaskList ); + + while( pxCurListItem != listGET_END_MARKER( pxCurTaskList ) ) + { + TCB_t * pxTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxCurListItem ); + vTaskGetSnapshot( ( TaskHandle_t ) pxTCB, &pxTaskSnapshotArray[ uxArrayNumFilled ] ); uxArrayNumFilled++; - if (!(uxArrayNumFilled < uxArrayLength)) { + + if( !( uxArrayNumFilled < uxArrayLength ) ) + { break; } - pxCurListItem = listGET_NEXT(pxCurListItem); + + pxCurListItem = listGET_NEXT( pxCurListItem ); } } - //Get the next task list - pxCurTaskList = pxGetNextTaskList(pxCurTaskList); + + /*Get the next task list */ + pxCurTaskList = pxGetNextTaskList( pxCurTaskList ); } - *pxTCBSize = sizeof(TCB_t); + *pxTCBSize = sizeof( TCB_t ); return uxArrayNumFilled; } +/*----------------------------------------------------------*/ -/* ----------------------------------------------------- OpenOCD ------------------------------------------------------- - * - * ------------------------------------------------------------------------------------------------------------------ */ +/* ----------------------------------------------------- OpenOCD ---------------------------------------------------- */ #if CONFIG_FREERTOS_DEBUG_OCDAWARE @@ -255,352 +680,30 @@ UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, co * Debug param indexes. DO NOT change the order. OpenOCD uses the same indexes * Entries in FreeRTOS_openocd_params must match the order of these indexes */ -enum { - ESP_FREERTOS_DEBUG_TABLE_SIZE = 0, - ESP_FREERTOS_DEBUG_TABLE_VERSION, - ESP_FREERTOS_DEBUG_KERNEL_VER_MAJOR, - ESP_FREERTOS_DEBUG_KERNEL_VER_MINOR, - ESP_FREERTOS_DEBUG_KERNEL_VER_BUILD, - ESP_FREERTOS_DEBUG_UX_TOP_USED_PIORITY, - ESP_FREERTOS_DEBUG_PX_TOP_OF_STACK, - ESP_FREERTOS_DEBUG_PC_TASK_NAME, - /* New entries must be inserted here */ - ESP_FREERTOS_DEBUG_TABLE_END, -}; - -const DRAM_ATTR uint8_t FreeRTOS_openocd_params[ESP_FREERTOS_DEBUG_TABLE_END] = { - ESP_FREERTOS_DEBUG_TABLE_END, /* table size */ - 1, /* table version */ - tskKERNEL_VERSION_MAJOR, - tskKERNEL_VERSION_MINOR, - tskKERNEL_VERSION_BUILD, - configMAX_PRIORITIES - 1, /* uxTopUsedPriority */ - offsetof(TCB_t, pxTopOfStack), /* thread_stack_offset; */ - offsetof(TCB_t, pcTaskName), /* thread_name_offset; */ -}; - -#endif // CONFIG_FREERTOS_DEBUG_OCDAWARE - -/* -------------------------------------------- FreeRTOS IDF API Additions --------------------------------------------- - * FreeRTOS related API that were added by IDF - * ------------------------------------------------------------------------------------------------------------------ */ - -#if CONFIG_FREERTOS_SMP -_Static_assert(tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "CONFIG_FREERTOS_NO_AFFINITY must be the same as tskNO_AFFINITY"); - -BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode, - const char * const pcName, - const uint32_t usStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - TaskHandle_t * const pxCreatedTask, - const BaseType_t xCoreID) -{ - BaseType_t ret; - #if ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) - { - // Convert xCoreID into an affinity mask - UBaseType_t uxCoreAffinityMask; - if (xCoreID == tskNO_AFFINITY) { - uxCoreAffinityMask = tskNO_AFFINITY; - } else { - uxCoreAffinityMask = (1 << xCoreID); - } - ret = xTaskCreateAffinitySet(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, uxCoreAffinityMask, pxCreatedTask); - } - #else /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */ - { - ret = xTaskCreate(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask); - } - #endif /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */ - return ret; -} - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) -TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode, - const char * const pcName, - const uint32_t ulStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - StackType_t * const puxStackBuffer, - StaticTask_t * const pxTaskBuffer, - const BaseType_t xCoreID) -{ - TaskHandle_t ret; - #if ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) - { - // Convert xCoreID into an affinity mask - UBaseType_t uxCoreAffinityMask; - if (xCoreID == tskNO_AFFINITY) { - uxCoreAffinityMask = tskNO_AFFINITY; - } else { - uxCoreAffinityMask = (1 << xCoreID); - } - ret = xTaskCreateStaticAffinitySet(pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, uxCoreAffinityMask); - } - #else /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */ - { - ret = xTaskCreateStatic(pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer); - } - #endif /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */ - return ret; -} -#endif /* configSUPPORT_STATIC_ALLOCATION */ - -TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID ) -{ - TaskHandle_t xTaskHandleTemp; - assert(xCoreID >= 0 && xCoreID < configNUM_CORES); - taskENTER_CRITICAL(); - xTaskHandleTemp = (TaskHandle_t) pxCurrentTCBs[xCoreID]; - taskEXIT_CRITICAL(); - return xTaskHandleTemp; -} - -TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID ) -{ - assert(xCoreID >= 0 && xCoreID < configNUM_CORES); - return (TaskHandle_t) xIdleTaskHandle[xCoreID]; -} - -BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) -{ - taskENTER_CRITICAL(); - UBaseType_t uxCoreAffinityMask; -#if ( configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 ) - TCB_t *pxTCB = prvGetTCBFromHandle( xTask ); - uxCoreAffinityMask = pxTCB->uxCoreAffinityMask; -#else - uxCoreAffinityMask = tskNO_AFFINITY; -#endif - taskEXIT_CRITICAL(); - BaseType_t ret; - // If the task is not pinned to a particular core, treat it as tskNO_AFFINITY - if (uxCoreAffinityMask & (uxCoreAffinityMask - 1)) { // If more than one bit set - ret = tskNO_AFFINITY; - } else { - int index_plus_one = __builtin_ffs(uxCoreAffinityMask); - assert(index_plus_one >= 1); - ret = index_plus_one - 1; - } - return ret; -} - -#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) -void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue, TlsDeleteCallbackFunction_t pvDelCallback) + enum { - // Verify that the offsets of pvThreadLocalStoragePointers and pvDummy15 match. - // pvDummy15 is part of the StaticTask_t struct and is used to access the TLSPs - // while deletion. - _Static_assert(offsetof( StaticTask_t, pvDummy15 ) == offsetof( TCB_t, pvThreadLocalStoragePointers ), "Offset of pvDummy15 must match the offset of pvThreadLocalStoragePointers"); + ESP_FREERTOS_DEBUG_TABLE_SIZE = 0, + ESP_FREERTOS_DEBUG_TABLE_VERSION, + ESP_FREERTOS_DEBUG_KERNEL_VER_MAJOR, + ESP_FREERTOS_DEBUG_KERNEL_VER_MINOR, + ESP_FREERTOS_DEBUG_KERNEL_VER_BUILD, + ESP_FREERTOS_DEBUG_UX_TOP_USED_PIORITY, + ESP_FREERTOS_DEBUG_PX_TOP_OF_STACK, + ESP_FREERTOS_DEBUG_PC_TASK_NAME, + /* New entries must be inserted here */ + ESP_FREERTOS_DEBUG_TABLE_END, + }; - //Set the local storage pointer first - vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + const DRAM_ATTR uint8_t FreeRTOS_openocd_params[ ESP_FREERTOS_DEBUG_TABLE_END ] = { + ESP_FREERTOS_DEBUG_TABLE_END, /* table size */ + 1, /* table version */ + tskKERNEL_VERSION_MAJOR, + tskKERNEL_VERSION_MINOR, + tskKERNEL_VERSION_BUILD, + configMAX_PRIORITIES - 1, /* uxTopUsedPriority */ + offsetof( TCB_t, pxTopOfStack ), /* thread_stack_offset; */ + offsetof( TCB_t, pcTaskName ), /* thread_name_offset; */ + }; - //Set the deletion callback at an offset of configNUM_THREAD_LOCAL_STORAGE_POINTERS/2 - vTaskSetThreadLocalStoragePointer( xTaskToSet, ( xIndex + ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ), pvDelCallback ); - } -#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 ) +#endif /* CONFIG_FREERTOS_DEBUG_OCDAWARE */ +/*----------------------------------------------------------*/ diff --git a/components/freertos/esp_additions/idf_additions.c b/components/freertos/esp_additions/idf_additions.c index aac9911b40..4bd428981f 100644 --- a/components/freertos/esp_additions/idf_additions.c +++ b/components/freertos/esp_additions/idf_additions.c @@ -4,6 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +/* + * This file contains the implementation for some the functions in + * idf_additions.h + */ + #include "sdkconfig.h" #include #include "freertos/FreeRTOS.h" @@ -17,19 +22,12 @@ #include "freertos/idf_additions.h" #include "esp_heap_caps.h" -/* - * This file contains the implementation for some the functions in - * idf_additions.h - */ - -/* ----------------------------------------------------------------------------- - * Creation With Memory Caps - * -------------------------------------------------------------------------- */ - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) +/* -------------------------------------------- Creation With Memory Caps ------------------------------------------- */ /* ---------------------------------- Tasks --------------------------------- */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xTaskCreatePinnedToCoreWithCaps( TaskFunction_t pvTaskCode, const char * const pcName, const configSTACK_DEPTH_TYPE usStackDepth, @@ -78,6 +76,11 @@ err: return pdFAIL; } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + void vTaskDeleteWithCaps( TaskHandle_t xTaskToDelete ) { BaseType_t xResult; @@ -95,8 +98,13 @@ err: vPortFree( pxTaskBuffer ); } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + /* ---------------------------------- Queue --------------------------------- */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t xQueueCreateWithCaps( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, UBaseType_t uxMemoryCaps ) @@ -138,6 +146,11 @@ err: return NULL; } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + void vQueueDeleteWithCaps( QueueHandle_t xQueue ) { BaseType_t xResult; @@ -156,8 +169,13 @@ err: heap_caps_free( pucQueueStorageBuffer ); } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + /* -------------------------------- Semaphore ------------------------------- */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + SemaphoreHandle_t xSemaphoreCreateGenericWithCaps( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, const uint8_t ucQueueType, @@ -200,6 +218,11 @@ err: return xSemaphore; } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + void vSemaphoreDeleteWithCaps( SemaphoreHandle_t xSemaphore ) { BaseType_t xResult; @@ -217,8 +240,13 @@ err: heap_caps_free( pxSemaphoreBuffer ); } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + /* ------------------------- Stream & Message Buffers ----------------------- */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + StreamBufferHandle_t xStreamBufferGenericCreateWithCaps( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, @@ -261,6 +289,11 @@ err: return NULL; } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + void vStreamBufferGenericDeleteWithCaps( StreamBufferHandle_t xStreamBuffer, BaseType_t xIsMessageBuffer ) { @@ -296,8 +329,13 @@ err: heap_caps_free( pucStreamBufferStorageArea ); } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + /* ------------------------------ Event Groups ------------------------------ */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreateWithCaps( UBaseType_t uxMemoryCaps ) { EventGroupHandle_t xEventGroup; @@ -322,6 +360,11 @@ err: return xEventGroup; } +#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + void vEventGroupDeleteWithCaps( EventGroupHandle_t xEventGroup ) { BaseType_t xResult; @@ -340,3 +383,4 @@ err: } #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*----------------------------------------------------------*/ diff --git a/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h b/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h index c6e6ba81c0..2670a46ad2 100644 --- a/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h +++ b/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h @@ -8,25 +8,29 @@ /* * This file is like "idf_additions.h" but for private API (i.e., only meant to - * be called by other internally by other - * ESP-IDF components. + * be called internally by other ESP-IDF components. */ #include "sdkconfig.h" #include "freertos/FreeRTOS.h" +/* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif +/* *INDENT-ON* */ -/* ----------------------------------------------------------------------------- - * Priority Raise/Restore - * - Special functions to forcefully raise and restore a task's priority - * - Used by cache_utils.c when disabling/enabling the cache - * -------------------------------------------------------------------------- */ - +/*------------------------------------------------------------------------------ + * TASK UTILITIES (PRIVATE) + *----------------------------------------------------------------------------*/ #if ( INCLUDE_vTaskPrioritySet == 1 ) +/** + * @brief Structure to save a task's previous priority + * + * This structure is meant to be used with prvTaskPriorityRaise() and + * prvTaskPriorityRestore(). + */ typedef struct { UBaseType_t uxPriority; @@ -35,13 +39,17 @@ #endif } prvTaskSavedPriority_t; +#endif /* INCLUDE_vTaskPrioritySet == 1 */ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + /** * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be * available. See the configuration section for more information. * - * Saves the current priority and current base priority of a task, then - * raises the task's current and base priority to uxNewPriority if - * uxNewPriority is of a higher priority. + * Saves the current priority and current base priority of a task, then raises + * the task's current and base priority to uxNewPriority if uxNewPriority is of + * a higher priority. * * Once a task's priority has been raised with this function, the priority * can be restored by calling prvTaskPriorityRestore() @@ -53,8 +61,8 @@ * forced immediately to a higher priority. * * For configUSE_MUTEXES == 0: A context switch will occur before the - * function returns if the priority being set is higher than the currently - * executing task. + * function returns if the priority being set is higher than the priority of the + * currently executing task. * * @note This functions is private and should only be called internally * within various IDF components. Users should never call this function from @@ -71,17 +79,20 @@ void prvTaskPriorityRaise( prvTaskSavedPriority_t * pxSavedPriority, UBaseType_t uxNewPriority ); +#endif /* INCLUDE_vTaskPrioritySet == 1 */ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + /** * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be - * available. - * See the configuration section for more information. + * available. See the configuration section for more information. * * Restore a task's priority that was previously raised by * prvTaskPriorityRaise(). * * For configUSE_MUTEXES == 0: A context switch will occur before the function - * returns if the priority - * being set is higher than the currently executing task. + * returns if the priority being set is higher than the priority of the currently + * executing task. * * @note This functions is private and should only be called internally within * various IDF components. Users should never call this function from their @@ -92,8 +103,10 @@ */ void prvTaskPriorityRestore( prvTaskSavedPriority_t * pxSavedPriority ); -#endif // ( INCLUDE_vTaskPrioritySet == 1) +#endif /* INCLUDE_vTaskPrioritySet == 1 */ +/* *INDENT-OFF* */ #ifdef __cplusplus } #endif +/* *INDENT-ON* */ diff --git a/components/freertos/esp_additions/include/freertos/idf_additions.h b/components/freertos/esp_additions/include/freertos/idf_additions.h index 07e3495e48..41ca5ee14a 100644 --- a/components/freertos/esp_additions/include/freertos/idf_additions.h +++ b/components/freertos/esp_additions/include/freertos/idf_additions.h @@ -25,20 +25,20 @@ #include "freertos/event_groups.h" #include "esp_heap_caps.h" +/* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif +/* *INDENT-ON* */ -/* ----------------------------------------------------------------------------- - * SMP related API additions to FreeRTOS - * - * Todo: Move IDF FreeRTOS SMP related additions to this header as well (see - * IDF-7201) - * Todo: Add these SMP related additions to docs once they are combined with - * IDF FreeRTOS. - * -------------------------------------------------------------------------- */ +/* -------------------------------------------------- Task Creation --------------------------------------------------- +* Task Creation APIs added by ESP-IDF +* +* Todo: Move IDF FreeRTOS SMP related additions to this header as well (see IDF-7201) +* Todo: Add these SMP related additions to docs once they are combined with IDF FreeRTOS. +* ------------------------------------------------------------------------------------------------------------------ */ -#if CONFIG_FREERTOS_SMP +#if ( CONFIG_FREERTOS_SMP && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) /** * @brief Create a new task that is pinned to a particular core @@ -69,6 +69,9 @@ TaskHandle_t * const pxCreatedTask, const BaseType_t xCoreID ); +#endif /* ( CONFIG_FREERTOS_SMP && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ + +#if ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) /** * @brief Create a new static task that is pinned to a particular core @@ -89,16 +92,22 @@ * the task has no core affinity * @return The task handle if the task was created, NULL otherwise. */ - #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) - TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode, - const char * const pcName, - const uint32_t ulStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - StackType_t * const puxStackBuffer, - StaticTask_t * const pxTaskBuffer, - const BaseType_t xCoreID ); - #endif /* configSUPPORT_STATIC_ALLOCATION */ + TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer, + const BaseType_t xCoreID ); + +#endif /* ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ + +/* ------------------------------------------------- Task Utilities ---------------------------------------------------- + * Todo: Move IDF FreeRTOS SMP related additions to this header as well (see IDF-7201) + * ------------------------------------------------------------------------------------------------------------------ */ + +#if CONFIG_FREERTOS_SMP /** * @brief Get the handle of the task running on a certain core @@ -115,6 +124,10 @@ */ TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID ); +#endif /* CONFIG_FREERTOS_SMP */ + +#if CONFIG_FREERTOS_SMP + /** * @brief Get the handle of idle task for the given CPU. * @@ -126,6 +139,10 @@ */ TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID ); +#endif /* CONFIG_FREERTOS_SMP */ + +#if CONFIG_FREERTOS_SMP + /** * @brief Get the current core affinity of a particular task * @@ -141,26 +158,27 @@ */ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ); -#endif // CONFIG_FREERTOS_SMP +#endif /* CONFIG_FREERTOS_SMP */ -/* ----------------------------------------------------------------------------- - * TLSP Deletion Callback related API additions +/* --------------------------------------------- TLSP Deletion Callbacks ----------------------------------------------- + * TLSP Deletion Callback API Additions * - * Todo: Move IDF FreeRTOS TLSP Deletion Callback related additions to this - * header as well (see IDF-7201) - * Todo: Add these SMP related additions to docs once they are combined with - * IDF FreeRTOS. - * -------------------------------------------------------------------------- */ + * Todo: Move IDF FreeRTOS TLSP Deletion Callback related additions to this header as well (see IDF-7201) + * Todo: Add these SMP related additions to docs once they are combined with IDF FreeRTOS. + * ------------------------------------------------------------------------------------------------------------------ */ -#if CONFIG_FREERTOS_SMP - - #if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) +#if ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) /** * Prototype of local storage pointer deletion callback. */ - typedef void (* TlsDeleteCallbackFunction_t)( int, - void * ); + typedef void (* TlsDeleteCallbackFunction_t)( int, + void * ); + +#endif /* ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) */ + + +#if ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) /** * Set local storage pointer and deletion callback. @@ -184,25 +202,22 @@ * @param pvDelCallback Function to call to dispose of the local storage * pointer when the task is deleted. */ - void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, - BaseType_t xIndex, - void * pvValue, - TlsDeleteCallbackFunction_t pvDelCallback ); - #endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS + void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue, + TlsDeleteCallbackFunction_t pvDelCallback ); -#endif // CONFIG_FREERTOS_SMP +#endif /* ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) */ -/* ----------------------------------------------------------------------------- - * Creation With Memory Caps - * - * Helper functions to create various FreeRTOS objects (e.g., queues, - * semaphores) with specific memory capabilities (e.g., MALLOC_CAP_INTERNAL). - * -------------------------------------------------------------------------- */ - -#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) +/* -------------------------------------------- Creation With Memory Caps ---------------------------------------------- + * Helper functions to create various FreeRTOS objects (e.g., queues, semaphores) with specific memory capabilities + * (e.g., MALLOC_CAP_INTERNAL). + * ------------------------------------------------------------------------------------------------------------------ */ /* ---------------------------------- Tasks --------------------------------- */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates a pinned task where its stack has specific memory capabilities * @@ -238,6 +253,10 @@ const BaseType_t xCoreID, UBaseType_t uxMemoryCaps ); +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates a task where its stack has specific memory capabilities * @@ -275,6 +294,10 @@ return xTaskCreatePinnedToCoreWithCaps( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask, tskNO_AFFINITY, uxMemoryCaps ); } +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Deletes a task previously created using xTaskCreateWithCaps() or * xTaskCreatePinnedToCoreWithCaps() @@ -283,8 +306,12 @@ */ void vTaskDeleteWithCaps( TaskHandle_t xTaskToDelete ); +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + /* ---------------------------------- Queue --------------------------------- */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates a queue with specific memory capabilities * @@ -304,6 +331,10 @@ UBaseType_t uxItemSize, UBaseType_t uxMemoryCaps ); +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Deletes a queue previously created using xQueueCreateWithCaps() * @@ -311,15 +342,19 @@ */ void vQueueDeleteWithCaps( QueueHandle_t xQueue ); +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + /* -------------------------------- Semaphore ------------------------------- */ /** @cond */ /* Doxygen command to hide this from docs */ - SemaphoreHandle_t xSemaphoreCreateGenericWithCaps( UBaseType_t uxMaxCount, - UBaseType_t uxInitialCount, - const uint8_t ucQueueType, - UBaseType_t uxMemoryCaps ); +SemaphoreHandle_t xSemaphoreCreateGenericWithCaps( UBaseType_t uxMaxCount, + UBaseType_t uxInitialCount, + const uint8_t ucQueueType, + UBaseType_t uxMemoryCaps ); /** @endcond */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates a binary semaphore with specific memory capabilities * @@ -338,6 +373,10 @@ return xSemaphoreCreateGenericWithCaps( 0, 0, queueQUEUE_TYPE_BINARY_SEMAPHORE, uxMemoryCaps ); } +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates a counting semaphore with specific memory capabilities * @@ -361,6 +400,10 @@ return xSemaphoreCreateGenericWithCaps( uxMaxCount, uxInitialCount, queueQUEUE_TYPE_COUNTING_SEMAPHORE, uxMemoryCaps ); } +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates a mutex semaphore with specific memory capabilities * @@ -379,6 +422,10 @@ return xSemaphoreCreateGenericWithCaps( 0, 0, queueQUEUE_TYPE_MUTEX, uxMemoryCaps ); } +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates a recursive mutex with specific memory capabilities * @@ -397,6 +444,10 @@ return xSemaphoreCreateGenericWithCaps( 0, 0, queueQUEUE_TYPE_RECURSIVE_MUTEX, uxMemoryCaps ); } +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Deletes a semaphore previously created using one of the * xSemaphoreCreate...WithCaps() functions @@ -405,18 +456,22 @@ */ void vSemaphoreDeleteWithCaps( SemaphoreHandle_t xSemaphore ); +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + /* ------------------------ Stream & Message Buffers ------------------------ */ /** @cond */ /* Doxygen command to hide this from docs */ - StreamBufferHandle_t xStreamBufferGenericCreateWithCaps( size_t xBufferSizeBytes, - size_t xTriggerLevelBytes, - BaseType_t xIsMessageBuffer, - UBaseType_t uxMemoryCaps ); +StreamBufferHandle_t xStreamBufferGenericCreateWithCaps( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + UBaseType_t uxMemoryCaps ); - void vStreamBufferGenericDeleteWithCaps( StreamBufferHandle_t xStreamBuffer, - BaseType_t xIsMessageBuffer ); +void vStreamBufferGenericDeleteWithCaps( StreamBufferHandle_t xStreamBuffer, + BaseType_t xIsMessageBuffer ); /** @endcond */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates a stream buffer with specific memory capabilities * @@ -441,6 +496,10 @@ return xStreamBufferGenericCreateWithCaps( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, uxMemoryCaps ); } +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Deletes a stream buffer previously created using * xStreamBufferCreateWithCaps() @@ -452,6 +511,10 @@ vStreamBufferGenericDeleteWithCaps( xStreamBuffer, pdFALSE ); } +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates a message buffer with specific memory capabilities * @@ -473,6 +536,10 @@ return ( MessageBufferHandle_t ) xStreamBufferGenericCreateWithCaps( xBufferSizeBytes, ( size_t ) 0, pdTRUE, uxMemoryCaps ); } +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Deletes a stream buffer previously created using * xMessageBufferCreateWithCaps() @@ -484,8 +551,12 @@ vStreamBufferGenericDeleteWithCaps( ( StreamBufferHandle_t ) xMessageBuffer, pdTRUE ); } +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + /* ------------------------------ Event Groups ------------------------------ */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Creates an event group with specific memory capabilities * @@ -501,6 +572,10 @@ */ EventGroupHandle_t xEventGroupCreateWithCaps( UBaseType_t uxMemoryCaps ); +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + /** * @brief Deletes an event group previously created using * xEventGroupCreateWithCaps() @@ -509,8 +584,10 @@ */ void vEventGroupDeleteWithCaps( EventGroupHandle_t xEventGroup ); -#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ +/* *INDENT-OFF* */ #ifdef __cplusplus -} + } #endif +/* *INDENT-ON* */ diff --git a/components/freertos/linker_common.lf b/components/freertos/linker_common.lf index 8a169dbcc1..0756332bbb 100644 --- a/components/freertos/linker_common.lf +++ b/components/freertos/linker_common.lf @@ -6,33 +6,35 @@ archive: libfreertos.a entries: # ------------------------------------------------------------------------------------------------------------------ # esp_additions/private_include/freertos_tasks_c_additions.h + # Placement Rules (FreeRTOS API Additions): + # - Default: Place all functions in internal RAM. + # - CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH: Place functions in flash if they are never called from an ISR + # context (directly or indirectly). # Placement Rules (Task Snapshot): # - Default: Place all functions in internal RAM. # - CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH: Place functions in flash # - vTaskGetSnapshot is omitted on purpose as it is used to by the Task Watchdog (TWDT) interrupt handler, we want # to always keep it in IRAM - # Placement Rules (FreeRTOS API Additions): - # - Default: Place all functions in internal RAM. - # - CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH: Place functions in flash if they are never called from an ISR - # context (directly or indirectly). # ------------------------------------------------------------------------------------------------------------------ + if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: + # Task Creation + if FREERTOS_SMP = y: + tasks:xTaskCreatePinnedToCore (default) + tasks:xTaskCreateStaticPinnedToCore (default) + # Task Utilities + tasks:xTaskGetCurrentTaskHandleForCPU (default) + tasks:xTaskGetIdleTaskHandleForCPU (default) + tasks:xTaskGetAffinity (default) + tasks:prvTaskPriorityRaise (default) + tasks:prvTaskPriorityRestore (default) + # TLSP Deletion Callbacks + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + tasks:vTaskSetThreadLocalStoragePointerAndDelCallback (default) # Task Snapshot if FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH = y: tasks:pxGetNextTaskList (default) tasks:pxTaskGetNext (default) tasks:uxTaskGetSnapshotAll (default) - # FreeRTOS API Additions - if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: - if FREERTOS_SMP = y: - tasks:xTaskCreatePinnedToCore (default) - tasks:xTaskCreateStaticPinnedToCore (default) - tasks:xTaskGetCurrentTaskHandleForCPU (default) - tasks:xTaskGetIdleTaskHandleForCPU (default) - tasks:xTaskGetAffinity (default) - if FREERTOS_TLSP_DELETION_CALLBACKS = y: - tasks:vTaskSetThreadLocalStoragePointerAndDelCallback (default) - tasks:prvTaskPriorityRaise (default) - tasks:prvTaskPriorityRestore (default) # ------------------------------------------------------------------------------------------------------------------ # idf_additions.c