forked from espressif/esp-idf
feat(freertos): Add SMP kernel changes to FreeRTOS v10.5.1
This commit adds the key kernel changes to the v10.5.1 kernel to support dual-core SMP. These changes are temporarily documented in the `idf_changes.md` document. This commit... - Added changes to kernel data structures to support multiple cores - Changes to scheduling algorithm support SMP scheduling. - Changes to each FreeRTOS function to support multiple cores and SMP scheduling algorithm.
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
This document is used to track all changes made the to FreeRTOS V10.5.1 source code when adding dual core SMP support or IDF additional features.
|
||||
|
||||
Todo: Add these to ESP-IDF docs once v10.5.1 becomes default kernel (IDF-8203)
|
||||
|
||||
## License Headers
|
||||
|
||||
- Added `SPDX-FileCopyrightText` and `SPDX-FileContributor` tags to all files to pass ESP-IDF pre-commit checks.
|
||||
@@ -13,4 +15,116 @@ This document is used to track all changes made the to FreeRTOS V10.5.1 source c
|
||||
|
||||
## Changes from Upstream Main Branch not Included in v10.5.1
|
||||
|
||||
- Added ...GetStaticBuffers functions that were upstreamed but not included in v10.5.1
|
||||
- Added ...GetStaticBuffers functions that were upstreamed but not included in v10.5.1
|
||||
|
||||
## Kernel SMP Changes
|
||||
|
||||
List of changes to the Vanilla FreeRTOS V10.5.1 kernel in order to support dual-core SMP
|
||||
|
||||
### Scheduling Behavior Changes
|
||||
|
||||
- The kernel now executes two tasks concurrently
|
||||
- The kernel now creates two IDLE tasks (pinned to each core)
|
||||
- Tasks can be pinned to either core, or have no affinity (can run on both cores)
|
||||
- Each core receives a tick interrupt, but only core 0 increments the tick count and unblocks timed out tasks
|
||||
- Core 0 calls `xTaskIncrementTick()`
|
||||
- Core 1 calls `xTaskIncrementTickOtherCores()`
|
||||
- Each core independently calls `vTaskSwitchContext()` to pick the highest priority task it can currently run
|
||||
- In single-core scheduling algorithm `taskSELECT_HIGHEST_PRIORITY_TASK()` unchanged
|
||||
- In SMP, `prvSelectHighestPriorityTaskSMP()` is called. This will select the highest priority ready state task that...
|
||||
- Has a compatible core affinity
|
||||
- Is not being run by another core
|
||||
- Each core can suspend scheduling independently (i.e., `vTaskSuspendAll()`)
|
||||
|
||||
### Configuration
|
||||
|
||||
Following configurations have been added
|
||||
|
||||
- Added `configNUMBER_OF_CORES` to specify the number of cores to build. Can be `1` for vanilla, or `2` for SMP, error otherwise
|
||||
- Disable `configUSE_PORT_OPTIMISED_TASK_SELECTION` for SMP
|
||||
|
||||
### Data Structure Changes (`tasks.c`)
|
||||
|
||||
The following data fields have been expanded to have `configNUMBER_OF_CORES` copies:
|
||||
|
||||
- `pxCurrentTCBs`: Each core now has its own currently running task
|
||||
- `xPendingReadyList`: Each core has its own list to pend ready tasks if the scheduler is suspended on the core
|
||||
- `xYieldPending`: Each core has its own flag to track whether it has a pending yield
|
||||
- `xIdleTaskHandle`: Each core now has its own idle task
|
||||
- `uxSchedulerSuspended`: Each core can independently suspend scheduling on its core
|
||||
- `ulTaskSwitchedInTime`: Each core tracks its own "task switched in" time
|
||||
|
||||
Their access is now indexed by a `xCoreID` if in SMP, or set to `0` in single core.
|
||||
|
||||
The following data structures have been added:
|
||||
|
||||
- `TCB_t.xCoreID`: All tasks now store their core affinity in a TCB member. Always set to 0 in single-core
|
||||
|
||||
### API Additions
|
||||
|
||||
The following APIs have been added to support SMP
|
||||
|
||||
- `xTaskCreatePinnedToCore()` and `xTaskCreateStaticPinnedToCore()` to create tasks with a core affinity
|
||||
- In single-core, core affinity is ignored. Same behavior as `xTaskCreate()`
|
||||
- `xTaskGetCoreID()` to get a task's affinity
|
||||
- Add `ForCore()` versions of the following API
|
||||
- `xTaskGetIdleTaskHandleForCore()`
|
||||
- `xTaskGetCurrentTaskHandleForCore()`
|
||||
- `ulTaskGetIdleRunTimeCounterForCore()`
|
||||
|
||||
### API Modifications
|
||||
|
||||
#### SMP Modifications
|
||||
|
||||
Added the following macros that abstract away single-core and SMP differences:
|
||||
|
||||
- `taskYIELD_CORE()` triggers a particular core to yield
|
||||
- `taskIS_YIELD_REQUIRED()`/`taskIS_YIELD_REQUIRED_USING_PRIORITY()` check if current core requires a yield after a task is unblocked
|
||||
- `taskIS_AFFINITY_COMPATIBLE()` check if a task has compatible affinity
|
||||
- `taskIS_CURRENTLY_RUNNING()`/`taskIS_CURRENTLY_RUNNING_ON_CORE()` checks if a task is running on either core
|
||||
- `taskCAN_BE_SCHEDULED()` checks if an unblocked task can be scheduled on any core
|
||||
- `taskIS_SCHEDULER_SUSPENDED()` checks if the scheduler on the current core is suspended
|
||||
- `taskSELECT_HIGHEST_PRIORITY_TASK()` selects the highest priority task to execute for the current core
|
||||
- `prvGetTCBFromHandle()` updated in SMP to call `xTaskGetCurrentTaskHandle()` when the handle is `NULL`. Done so for thread safety (in case the current task switches cores at the same time).
|
||||
|
||||
The following functions were modified to accommodate SMP behavior:
|
||||
|
||||
- `prvInitialiseNewTask()`
|
||||
- Added `xCoreID` argument to pin task on creation
|
||||
- For single-core, `xCoreID` is hard coded to `0`
|
||||
- `prvAddNewTaskToReadyList()`
|
||||
- Checks if new task can be scheduled on core 1
|
||||
- `vTaskDelete()`
|
||||
- Checks if the deleted task is currently running on the other core.
|
||||
- If so, sends a yield to the other core.
|
||||
- `vTaskPrioritySet()`
|
||||
- Checks if the task is currently running on the both cores, and yields the appropriate core if so
|
||||
- `vTaskSuspend()`
|
||||
- Checks if the task is currently running on the other core, and yields the other core if so.
|
||||
- `prvTaskIsTaskSuspended()`
|
||||
- Checks the `xPendingReadyList` of both cores to see if a task is suspended
|
||||
- `xTaskResumeAll()`
|
||||
- Limit catching up of tick counts to core 0 (given only core 0 calls `xTaskIncrementTick()`)
|
||||
- `xTaskIncrementTick()`
|
||||
- Limited to core 0
|
||||
- `vTaskSwitchContext()`
|
||||
- Switches context for current core
|
||||
- `xTaskRemoveFromEventList()`
|
||||
- Created SMP copy of the function
|
||||
- Checks if `pxEventList` has already been emptied by the other core before removing
|
||||
- Checks if task can be scheduled on both cores, adds it to the appropriate core's pending list if it can't be scheduled.
|
||||
- `vTaskRemoveFromUnorderedEventList()`
|
||||
- In SMP, check if the task can be scheduled before adding it to the appropriate list. Whereas in single-core, the scheduler is always suspended thus the unblocked task always goes onto the pending ready list.
|
||||
- `eTaskConfirmSleepModeStatus()`
|
||||
- Updated logic to determine whether sleep is possible in SMP by checking the status of both cores.
|
||||
- `prvCheckTasksWaitingTermination()`
|
||||
- Updated logic so that we don't delete tasks on `xTasksWaitingTermination` which are still currently running on the other core.
|
||||
- `prvAddCurrentTaskToDelayedList()`
|
||||
- Added extra check to see if current blocking task has already been deleted by the other core.
|
||||
|
||||
#### Single-Core Modifications
|
||||
|
||||
|
||||
## Single Core Differences
|
||||
|
||||
List of differences between Vanilla FreeRTOS V10.5.1 and building the dual-core SMP kernel with `congigNUMBER_OF_CORES == 1`.
|
@@ -135,6 +135,24 @@
|
||||
* within FreeRTOSConfig.h.
|
||||
*/
|
||||
|
||||
#ifndef configNUMBER_OF_CORES
|
||||
#error Missing definition: configNUMBER_OF_CORES must be defined in FreeRTOSConfig.h
|
||||
#endif
|
||||
|
||||
#if ( configNUMBER_OF_CORES > 1 )
|
||||
#ifndef portGET_CORE_ID
|
||||
#error "Missing definition: portGET_CORE_ID() must be defined if in portmacro.h if configNUMBER_OF_CORES > 1"
|
||||
#endif
|
||||
#ifndef portYIELD_CORE
|
||||
#error "Missing definition: portYIELD_CORE() must be defined if in portmacro.h if configNUMBER_OF_CORES > 1"
|
||||
#endif
|
||||
#elif ( configNUMBER_OF_CORES == 1 )
|
||||
#undef portGET_CORE_ID
|
||||
#define portGET_CORE_ID() 0
|
||||
#else
|
||||
#error configNUMBER_OF_CORES must be defined to either 1 or > 1.
|
||||
#endif /* if ( configNUMBER_OF_CORES > 1 ) */
|
||||
|
||||
#ifndef configMINIMAL_STACK_SIZE
|
||||
#error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value.
|
||||
#endif
|
||||
@@ -1007,6 +1025,10 @@
|
||||
#error configUSE_MUTEXES must be set to 1 to use recursive mutexes
|
||||
#endif
|
||||
|
||||
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_PORT_OPTIMISED_TASK_SELECTION != 0 ) )
|
||||
#error configUSE_PORT_OPTIMISED_TASK_SELECTION is not supported in SMP
|
||||
#endif
|
||||
|
||||
#ifndef configINITIAL_TICK_COUNT
|
||||
#define configINITIAL_TICK_COUNT 0
|
||||
#endif
|
||||
@@ -1267,6 +1289,8 @@ typedef struct xSTATIC_TCB
|
||||
UBaseType_t uxDummy5;
|
||||
void * pxDummy6;
|
||||
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
|
||||
/* Todo: Remove xCoreID for single core builds (IDF-7894) */
|
||||
BaseType_t xDummyCoreID;
|
||||
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
|
||||
void * pxDummy8;
|
||||
#endif
|
||||
@@ -1441,4 +1465,29 @@ typedef StaticStreamBuffer_t StaticMessageBuffer_t;
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* IDF Compatibility
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
/*
|
||||
* Include ESP-IDF API additions implicitly for compatibility reasons.
|
||||
*
|
||||
* ESP-IDF API additions were previously added directly to FreeRTOS headers
|
||||
* (e.g., task.h, queue.h). These APIs have now been moved to
|
||||
* idf_additions.h.
|
||||
*
|
||||
* To ensure there are no breaking changes, we include idf_additions.h
|
||||
* implicitly here so that those API additions are still accessible. Given
|
||||
* that FreeRTOS.h must be included first before calling any FreeRTOS API,
|
||||
* any existing source code can continue using these relocated APIs without
|
||||
* any additional header inclusions via this implicit inclusion.
|
||||
*
|
||||
* Todo: Deprecate this implicit inclusion by ESP-IDF v6.0 (IDF-8126)
|
||||
*/
|
||||
#include "freertos/idf_additions.h"
|
||||
|
||||
#endif /* ESP_PLATFORM */
|
||||
|
||||
#endif /* INC_FREERTOS_H */
|
||||
|
@@ -60,13 +60,13 @@
|
||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||
|
||||
/* Only the current stack state is to be checked. */
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW( xCurCoreID ) \
|
||||
{ \
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCBs[ xCurCoreID ]->pxTopOfStack <= pxCurrentTCBs[ xCurCoreID ]->pxStack + portSTACK_LIMIT_PADDING ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCBs[ xCurCoreID ], pxCurrentTCBs[ xCurCoreID ]->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||
@@ -75,14 +75,14 @@
|
||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||
|
||||
/* Only the current stack state is to be checked. */
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
\
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW( xCurCoreID ) \
|
||||
{ \
|
||||
\
|
||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||
if( pxCurrentTCBs[ xCurCoreID ]->pxTopOfStack >= pxCurrentTCBs[ xCurCoreID ]->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCBs[ xCurCoreID ], pxCurrentTCBs[ xCurCoreID ]->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||
@@ -90,18 +90,18 @@
|
||||
|
||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
{ \
|
||||
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
|
||||
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
|
||||
\
|
||||
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
||||
( pulStack[ 1 ] != ulCheckValue ) || \
|
||||
( pulStack[ 2 ] != ulCheckValue ) || \
|
||||
( pulStack[ 3 ] != ulCheckValue ) ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
} \
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW( xCurCoreID ) \
|
||||
{ \
|
||||
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCBs[ xCurCoreID ]->pxStack; \
|
||||
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \
|
||||
\
|
||||
if( ( pulStack[ 0 ] != ulCheckValue ) || \
|
||||
( pulStack[ 1 ] != ulCheckValue ) || \
|
||||
( pulStack[ 2 ] != ulCheckValue ) || \
|
||||
( pulStack[ 3 ] != ulCheckValue ) ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCBs[ xCurCoreID ], pxCurrentTCBs[ xCurCoreID ]->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||
@@ -109,9 +109,9 @@
|
||||
|
||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW() \
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW( xCurCoreID ) \
|
||||
{ \
|
||||
int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||
int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCBs[ xCurCoreID ]->pxEndOfStack; \
|
||||
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||
@@ -124,7 +124,7 @@
|
||||
/* Has the extremity of the task stack ever been written over? */ \
|
||||
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||
{ \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCBs[ xCurCoreID ], pxCurrentTCBs[ xCurCoreID ]->pcTaskName ); \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
|
||||
/* Remove stack overflow macro if not being used. */
|
||||
#ifndef taskCHECK_FOR_STACK_OVERFLOW
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW()
|
||||
#define taskCHECK_FOR_STACK_OVERFLOW( xCurCoreID )
|
||||
#endif
|
||||
|
||||
|
||||
|
@@ -170,6 +170,7 @@ typedef struct xTASK_STATUS
|
||||
StackType_t * pxEndOfStack; /* Points to the end address of the task's stack area. */
|
||||
#endif
|
||||
configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
|
||||
BaseType_t xCoreID; /*!< Core this task is pinned to (0, 1, or tskNO_AFFINITY). If configNUMBER_OF_CORES == 1, this will always be 0. */
|
||||
} TaskStatus_t;
|
||||
|
||||
/* Possible return values for eTaskConfirmSleepModeStatus(). */
|
||||
@@ -189,6 +190,14 @@ typedef enum
|
||||
*/
|
||||
#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U )
|
||||
|
||||
/**
|
||||
* Macro representing and unpinned (i.e., "no affinity") task in xCoreID parameters
|
||||
*
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#define tskNO_AFFINITY ( ( BaseType_t ) 0x7FFFFFFF )
|
||||
/* Todo: Update tskNO_AFFINITY value to -1 (IDF-7908) */
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
@@ -294,6 +303,9 @@ typedef enum
|
||||
* support can alternatively create an MPU constrained task using
|
||||
* xTaskCreateRestricted().
|
||||
*
|
||||
* @note If configNUMBER_OF_CORES > 1, this function will create an unpinned
|
||||
* task (see tskNO_AFFINITY for more details).
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function. Tasks
|
||||
* must be implemented to never return (i.e. continuous loop).
|
||||
*
|
||||
@@ -301,10 +313,8 @@ typedef enum
|
||||
* facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default
|
||||
* is 16.
|
||||
*
|
||||
* @param usStackDepth The size of the task stack specified as the number of
|
||||
* variables the stack can hold - not the number of bytes. For example, if
|
||||
* the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes
|
||||
* will be allocated for stack storage.
|
||||
* @param usStackDepth The size of the task stack specified as the NUMBER OF
|
||||
* BYTES. Note that this differs from vanilla FreeRTOS.
|
||||
*
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
@@ -321,6 +331,9 @@ typedef enum
|
||||
* @return pdPASS if the task was successfully created and added to a ready
|
||||
* list, otherwise an error code defined in the file projdefs.h
|
||||
*
|
||||
* @note If program uses thread local variables (ones specified with "__thread"
|
||||
* keyword) then storage for them will be allocated on the task's stack.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // Task to be created.
|
||||
@@ -356,13 +369,39 @@ typedef enum
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
static inline __attribute__( ( always_inline ) )
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION
|
||||
{
|
||||
/*
|
||||
* The idf_additions.h has not been included here yet due to inclusion
|
||||
* order. Thus we manually declare the function here.
|
||||
*/
|
||||
extern BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask,
|
||||
const BaseType_t xCoreID );
|
||||
|
||||
/*
|
||||
* Call the "PinnedToCore" version with tskNO_AFFINITY to create
|
||||
* an unpinned task.
|
||||
*/
|
||||
return xTaskCreatePinnedToCore( pxTaskCode,
|
||||
pcName,
|
||||
usStackDepth,
|
||||
pvParameters,
|
||||
uxPriority,
|
||||
pxCreatedTask,
|
||||
tskNO_AFFINITY );
|
||||
}
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION == 1 */
|
||||
|
||||
/**
|
||||
* task. h
|
||||
@@ -388,6 +427,9 @@ typedef enum
|
||||
* memory. xTaskCreateStatic() therefore allows a task to be created without
|
||||
* using any dynamic memory allocation.
|
||||
*
|
||||
* @note If configNUMBER_OF_CORES > 1, this function will create an unpinned
|
||||
* task (see tskNO_AFFINITY for more details).
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function. Tasks
|
||||
* must be implemented to never return (i.e. continuous loop).
|
||||
*
|
||||
@@ -395,10 +437,8 @@ typedef enum
|
||||
* facilitate debugging. The maximum length of the string is defined by
|
||||
* configMAX_TASK_NAME_LEN in FreeRTOSConfig.h.
|
||||
*
|
||||
* @param ulStackDepth The size of the task stack specified as the number of
|
||||
* variables the stack can hold - not the number of bytes. For example, if
|
||||
* the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes
|
||||
* will be allocated for stack storage.
|
||||
* @param ulStackDepth The size of the task stack specified as the NUMBER OF
|
||||
* BYTES. Note that this differs from vanilla FreeRTOS.
|
||||
*
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
@@ -418,6 +458,9 @@ typedef enum
|
||||
* puxStackBuffer or pxTaskBuffer are NULL then the task will not be created and
|
||||
* NULL is returned.
|
||||
*
|
||||
* @note If program uses thread local variables (ones specified with "__thread"
|
||||
* keyword) then storage for them will be allocated on the task's stack.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
*
|
||||
@@ -473,13 +516,41 @@ typedef enum
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
static inline __attribute__( ( always_inline ) )
|
||||
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const puxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION;
|
||||
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION
|
||||
{
|
||||
/*
|
||||
* The idf_additions.h has not been included here yet due to inclusion
|
||||
* order. Thus we manually declare the function here.
|
||||
*/
|
||||
extern TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const pxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer,
|
||||
const BaseType_t xCoreID );
|
||||
|
||||
/*
|
||||
* Call the "PinnedToCore" version with tskNO_AFFINITY to create
|
||||
* an unpinned task.
|
||||
*/
|
||||
return xTaskCreateStaticPinnedToCore( pxTaskCode,
|
||||
pcName,
|
||||
ulStackDepth,
|
||||
pvParameters,
|
||||
uxPriority,
|
||||
puxStackBuffer,
|
||||
pxTaskBuffer,
|
||||
tskNO_AFFINITY );
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/**
|
||||
@@ -1737,8 +1808,8 @@ BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask,
|
||||
* xTaskGetIdleTaskHandle() is only available if
|
||||
* INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* Simply returns the handle of the idle task. It is not valid to call
|
||||
* xTaskGetIdleTaskHandle() before the scheduler has been started.
|
||||
* Simply returns the handle of the idle task of the current core. It is not
|
||||
* valid to call xTaskGetIdleTaskHandle() before the scheduler has been started.
|
||||
*/
|
||||
TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
@@ -1979,6 +2050,9 @@ void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e
|
||||
* system if there are no other tasks executing at the idle priority, tickless
|
||||
* idle is not used, and configIDLE_SHOULD_YIELD is set to 0.
|
||||
*
|
||||
* @note If configNUMBER_OF_CORES > 1, calling this function will query the idle
|
||||
* task of the current core.
|
||||
*
|
||||
* @return The total run time of the idle task or the percentage of the total
|
||||
* run time consumed by the idle task. This is the amount of time the
|
||||
* idle task has actually been executing. The unit of time is dependent on the
|
||||
@@ -2954,6 +3028,9 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION;
|
||||
* or
|
||||
* + Time slicing is in use and there is a task of equal priority to the
|
||||
* currently running task.
|
||||
*
|
||||
* Note: If configNUMBER_OF_CORES > 1, this function must only be called by
|
||||
* core 0. Other cores should call xTaskIncrementTickOtherCores() instead.
|
||||
*/
|
||||
BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -252,14 +252,16 @@
|
||||
StackType_t * pxTimerTaskStackBuffer = NULL;
|
||||
uint32_t ulTimerTaskStackSize;
|
||||
|
||||
/* Timer tasks is always pinned to core 0. Todo: IDF-7906 */
|
||||
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
|
||||
xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
|
||||
configTIMER_SERVICE_TASK_NAME,
|
||||
ulTimerTaskStackSize,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
pxTimerTaskStackBuffer,
|
||||
pxTimerTaskTCBBuffer );
|
||||
xTimerTaskHandle = xTaskCreateStaticPinnedToCore( prvTimerTask,
|
||||
configTIMER_SERVICE_TASK_NAME,
|
||||
ulTimerTaskStackSize,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
pxTimerTaskStackBuffer,
|
||||
pxTimerTaskTCBBuffer,
|
||||
0 );
|
||||
|
||||
if( xTimerTaskHandle != NULL )
|
||||
{
|
||||
@@ -268,12 +270,14 @@
|
||||
}
|
||||
#else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
{
|
||||
xReturn = xTaskCreate( prvTimerTask,
|
||||
configTIMER_SERVICE_TASK_NAME,
|
||||
configTIMER_TASK_STACK_DEPTH,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
&xTimerTaskHandle );
|
||||
/* Timer tasks is always pinned to core 0. Todo: IDF-7906 */
|
||||
xReturn = xTaskCreatePinnedToCore( prvTimerTask,
|
||||
configTIMER_SERVICE_TASK_NAME,
|
||||
configTIMER_TASK_STACK_DEPTH,
|
||||
NULL,
|
||||
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
|
||||
&xTimerTaskHandle,
|
||||
0 );
|
||||
}
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@
|
||||
|
||||
/* ----------------------- System -------------------------- */
|
||||
|
||||
#define configMAX_TASK_NAME_LEN CONFIG_FREERTOS_MAX_TASK_NAME_LEN
|
||||
#define configMAX_TASK_NAME_LEN CONFIG_FREERTOS_MAX_TASK_NAME_LEN
|
||||
|
||||
/* If deletion callbacks are enabled, the number of TLSP's are doubled (i.e.,
|
||||
* the length of the TCB's pvThreadLocalStoragePointersThis array). This allows
|
||||
@@ -257,10 +257,12 @@
|
||||
|
||||
#if !CONFIG_FREERTOS_SMP
|
||||
#ifdef CONFIG_FREERTOS_UNICORE
|
||||
#define configNUM_CORES 1
|
||||
#define configNUMBER_OF_CORES 1
|
||||
#else
|
||||
#define configNUM_CORES 2
|
||||
#define configNUMBER_OF_CORES 2
|
||||
#endif /* CONFIG_FREERTOS_UNICORE */
|
||||
/* For compatibility */
|
||||
#define configNUM_CORES configNUMBER_OF_CORES
|
||||
#ifdef CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID
|
||||
#define configTASKLIST_INCLUDE_COREID 1
|
||||
#endif /* CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID */
|
||||
|
@@ -405,48 +405,7 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
||||
|
||||
/* ------------------------------------------------- Task Utilities ------------------------------------------------- */
|
||||
|
||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID )
|
||||
{
|
||||
configASSERT( xCoreID >= 0 && xCoreID < configNUM_CORES );
|
||||
configASSERT( ( xIdleTaskHandle[ xCoreID ] != NULL ) );
|
||||
return ( TaskHandle_t ) xIdleTaskHandle[ xCoreID ];
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_xTaskGetIdleTaskHandle */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
|
||||
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID )
|
||||
{
|
||||
TaskHandle_t xReturn;
|
||||
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
{
|
||||
xReturn = xTaskGetCurrentTaskHandleCPU( xCoreID );
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
{
|
||||
if( xCoreID < configNUM_CORES )
|
||||
{
|
||||
xReturn = pxCurrentTCB[ xCoreID ];
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
||||
BaseType_t xTaskGetCoreID( TaskHandle_t xTask )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
@@ -472,11 +431,10 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
TCB_t * pxTCB;
|
||||
|
||||
/* Todo: Remove xCoreID for single core builds (IDF-7894) */
|
||||
pxTCB = prvGetTCBFromHandle( xTask );
|
||||
/* Simply read the xCoreID member of the TCB */
|
||||
taskENTER_CRITICAL( &xKernelLock );
|
||||
|
||||
xReturn = pxTCB->xCoreID;
|
||||
taskEXIT_CRITICAL_ISR( &xKernelLock );
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
}
|
||||
#else /* configNUM_CORES > 1 */
|
||||
@@ -490,6 +448,140 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
||||
}
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCore( BaseType_t xCoreID )
|
||||
{
|
||||
#if CONFIG_FREERTOS_USE_KERNEL_10_5_1
|
||||
{
|
||||
/* If xTaskGetIdleTaskHandle() is called before the scheduler has been
|
||||
* started, then xIdleTaskHandle will be NULL. */
|
||||
configASSERT( ( xCoreID < configNUMBER_OF_CORES ) && ( xCoreID != tskNO_AFFINITY ) );
|
||||
configASSERT( ( xIdleTaskHandle[ xCoreID ] != NULL ) );
|
||||
return xIdleTaskHandle[ xCoreID ];
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_USE_KERNEL_10_5_1 */
|
||||
{
|
||||
configASSERT( xCoreID >= 0 && xCoreID < configNUM_CORES );
|
||||
configASSERT( ( xIdleTaskHandle[ xCoreID ] != NULL ) );
|
||||
return ( TaskHandle_t ) xIdleTaskHandle[ xCoreID ];
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_USE_KERNEL_10_5_1 */
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_xTaskGetIdleTaskHandle */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
|
||||
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCore( BaseType_t xCoreID )
|
||||
{
|
||||
TaskHandle_t xReturn;
|
||||
|
||||
#if CONFIG_FREERTOS_USE_KERNEL_10_5_1
|
||||
{
|
||||
configASSERT( xCoreID < configNUMBER_OF_CORES );
|
||||
configASSERT( xCoreID != tskNO_AFFINITY );
|
||||
|
||||
/* For SMP, we need to take the kernel lock here as we are about to
|
||||
* access kernel data structures. For single core, a critical section is
|
||||
* not required as this is not called from an interrupt and the current
|
||||
* TCB will always be the same for any individual execution thread. */
|
||||
taskENTER_CRITICAL_SMP_ONLY();
|
||||
{
|
||||
xReturn = pxCurrentTCBs[ xCoreID ];
|
||||
}
|
||||
/* Release the previously taken kernel lock. */
|
||||
taskEXIT_CRITICAL_SMP_ONLY();
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_USE_KERNEL_10_5_1 */
|
||||
{
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
{
|
||||
xReturn = xTaskGetCurrentTaskHandleCPU( xCoreID );
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
{
|
||||
if( xCoreID < configNUM_CORES )
|
||||
{
|
||||
xReturn = pxCurrentTCB[ xCoreID ];
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_USE_KERNEL_10_5_1 */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( CONFIG_FREERTOS_USE_KERNEL_10_5_1 && ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )
|
||||
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounterForCore( BaseType_t xCoreID )
|
||||
{
|
||||
uint32_t ulRunTimeCounter;
|
||||
|
||||
configASSERT( xCoreID < configNUMBER_OF_CORES );
|
||||
configASSERT( xCoreID != tskNO_AFFINITY );
|
||||
|
||||
/* For SMP, we need to take the kernel lock here as we are about to
|
||||
* access kernel data structures. */
|
||||
taskENTER_CRITICAL_SMP_ONLY();
|
||||
{
|
||||
ulRunTimeCounter = xIdleTaskHandle[ xCoreID ]->ulRunTimeCounter;
|
||||
}
|
||||
/* Release the previously taken kernel lock. */
|
||||
taskEXIT_CRITICAL_SMP_ONLY();
|
||||
|
||||
return ulRunTimeCounter;
|
||||
}
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_USE_KERNEL_10_5_1 && ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( CONFIG_FREERTOS_USE_KERNEL_10_5_1 && ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )
|
||||
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercentForCore( BaseType_t xCoreID )
|
||||
{
|
||||
configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn;
|
||||
|
||||
configASSERT( xCoreID < configNUMBER_OF_CORES );
|
||||
configASSERT( xCoreID != tskNO_AFFINITY );
|
||||
|
||||
ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE();
|
||||
|
||||
/* For percentage calculations. */
|
||||
ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100;
|
||||
|
||||
/* Avoid divide by zero errors. */
|
||||
if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 )
|
||||
{
|
||||
/* For SMP, we need to take the kernel lock here as we are about
|
||||
* to access kernel data structures. */
|
||||
taskENTER_CRITICAL_SMP_ONLY();
|
||||
{
|
||||
ulReturn = xIdleTaskHandle[ xCoreID ]->ulRunTimeCounter / ulTotalTime;
|
||||
}
|
||||
/* Release the previously taken kernel lock. */
|
||||
taskEXIT_CRITICAL_SMP_ONLY();
|
||||
}
|
||||
else
|
||||
{
|
||||
ulReturn = 0;
|
||||
}
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_USE_KERNEL_10_5_1 && ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint8_t * pxTaskGetStackStart( TaskHandle_t xTask )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
||||
/* -------------------------------------------------- Task Creation ------------------------------------------------- */
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
@@ -108,6 +109,35 @@
|
||||
|
||||
/* ------------------------------------------------- Task Utilities ------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Get the current core ID of a particular task
|
||||
*
|
||||
* Helper function to get the core ID of a particular task. If the task is
|
||||
* pinned to a particular core, the core ID is returned. If the task is not
|
||||
* pinned to a particular core, tskNO_AFFINITY is returned.
|
||||
*
|
||||
* If CONFIG_FREERTOS_UNICORE is enabled, this function simply returns 0.
|
||||
*
|
||||
* [refactor-todo] See if this needs to be deprecated (IDF-8145)(IDF-8164)
|
||||
*
|
||||
* @note If CONFIG_FREERTOS_SMP is enabled, please call vTaskCoreAffinityGet()
|
||||
* instead.
|
||||
* @note In IDF FreerTOS when configNUMBER_OF_CORES == 1, this function will
|
||||
* always return 0,
|
||||
* @param xTask The task to query
|
||||
* @return The task's core ID or tskNO_AFFINITY
|
||||
*/
|
||||
BaseType_t xTaskGetCoreID( TaskHandle_t xTask );
|
||||
|
||||
/** @cond */
|
||||
/* Todo: Deprecate this API in favor of xTaskGetIdleTaskHandleForCore (IDF-8163) */
|
||||
static inline __attribute__( ( always_inline ) )
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
||||
{
|
||||
return xTaskGetCoreID( xTask );
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @brief Get the handle of idle task for the given core.
|
||||
*
|
||||
@@ -118,7 +148,16 @@
|
||||
* @param xCoreID The core to query
|
||||
* @return Handle of the idle task for the queried core
|
||||
*/
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID );
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCore( BaseType_t xCoreID );
|
||||
|
||||
/** @cond */
|
||||
/* Todo: Deprecate this API in favor of xTaskGetIdleTaskHandleForCore (IDF-8163) */
|
||||
static inline __attribute__( ( always_inline ) )
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID )
|
||||
{
|
||||
return xTaskGetIdleTaskHandleForCore( xCoreID );
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @brief Get the handle of the task currently running on a certain core
|
||||
@@ -134,25 +173,42 @@ TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID );
|
||||
* @param xCoreID The core to query
|
||||
* @return Handle of the current task running on the queried core
|
||||
*/
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID );
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCore( BaseType_t xCoreID );
|
||||
|
||||
/** @cond */
|
||||
/* Todo: Deprecate this API in favor of xTaskGetCurrentTaskHandleForCore (IDF-8163) */
|
||||
static inline __attribute__( ( always_inline ) )
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID )
|
||||
{
|
||||
return xTaskGetCurrentTaskHandleForCore( xCoreID );
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
#if CONFIG_FREERTOS_USE_KERNEL_10_5_1
|
||||
|
||||
/**
|
||||
* @brief Get the current core affinity of a particular task
|
||||
* @brief Get the total execution of a particular core's idle task
|
||||
*
|
||||
* Helper function to get the core affinity of a particular task. If the task is
|
||||
* pinned to a particular core, the core ID is returned. If the task is not
|
||||
* pinned to a particular core, tskNO_AFFINITY is returned.
|
||||
* This function is equivalent to ulTaskGetIdleRunTimeCounter() but queries the
|
||||
* idle task of a particular core.
|
||||
*
|
||||
* If CONFIG_FREERTOS_UNICORE is enabled, this function simply returns 0.
|
||||
*
|
||||
* [refactor-todo] See if this needs to be deprecated (IDF-8145)(IDF-8164)
|
||||
*
|
||||
* @note If CONFIG_FREERTOS_SMP is enabled, please call vTaskCoreAffinityGet()
|
||||
* instead.
|
||||
* @param xTask The task to query
|
||||
* @return The tasks coreID or tskNO_AFFINITY
|
||||
* @param xCoreID Core ID of the idle task to query
|
||||
* @return The total run time of the idle task
|
||||
*/
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask );
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounterForCore( BaseType_t xCoreID );
|
||||
|
||||
/**
|
||||
* @brief Get the percentage run time of a particular core's idle task
|
||||
*
|
||||
* This function is equivalent to ulTaskGetIdleRunTimePercent() but queries the
|
||||
* idle task of a particular core.
|
||||
*
|
||||
* @param xCoreID Core ID of the idle task to query
|
||||
* @return The percentage run time of the idle task
|
||||
*/
|
||||
configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercentForCore( BaseType_t xCoreID );
|
||||
|
||||
#endif /* CONFIG_FREERTOS_USE_KERNEL_10_5_1 */
|
||||
|
||||
/**
|
||||
* Returns the start of the stack associated with xTask.
|
||||
|
@@ -171,6 +171,8 @@ entries:
|
||||
tasks:ulTaskGenericNotifyValueClear (default)
|
||||
if FREERTOS_GENERATE_RUN_TIME_STATS = y:
|
||||
tasks:ulTaskGetIdleRunTimeCounter (default)
|
||||
if FREERTOS_USE_KERNEL_10_5_1 = y:
|
||||
tasks:ulTaskGetIdleRunTimePercent (default)
|
||||
tasks:prvAddCurrentTaskToDelayedList (default)
|
||||
if FREERTOS_USE_TRACE_FACILITY = y:
|
||||
tasks:uxTaskGetSystemState (default)
|
||||
@@ -193,6 +195,8 @@ entries:
|
||||
timers:uxTimerGetReloadMode (default)
|
||||
timers:xTimerGetExpiryTime (default)
|
||||
timers:pcTimerGetName (default)
|
||||
if FREERTOS_USE_KERNEL_10_5_1 = y:
|
||||
timers:prvReloadTimer (default)
|
||||
timers:prvProcessExpiredTimer (default)
|
||||
timers:prvTimerTask (default)
|
||||
timers:prvProcessTimerOrBlockTask (default)
|
||||
|
@@ -25,10 +25,12 @@ entries:
|
||||
tasks:xTaskCreatePinnedToCore (default)
|
||||
tasks:xTaskCreateStaticPinnedToCore (default)
|
||||
# Task Utilities
|
||||
tasks:xTaskGetCurrentTaskHandleForCPU (default)
|
||||
tasks:xTaskGetIdleTaskHandleForCPU (default)
|
||||
tasks:xTaskGetCurrentTaskHandleForCPU (default)
|
||||
tasks:xTaskGetAffinity (default)
|
||||
tasks:xTaskGetCoreID (default)
|
||||
tasks:xTaskGetIdleTaskHandleForCore (default)
|
||||
tasks:xTaskGetCurrentTaskHandleForCore (default)
|
||||
if FREERTOS_USE_KERNEL_10_5_1 = y && FREERTOS_GENERATE_RUN_TIME_STATS = y:
|
||||
tasks:ulTaskGetIdleRunTimeCounterForCore (default)
|
||||
tasks:ulTaskGetIdleRunTimePercentForCore (default)
|
||||
tasks:pxTaskGetStackStart (default)
|
||||
tasks:prvTaskPriorityRaise (default)
|
||||
tasks:prvTaskPriorityRestore (default)
|
||||
|
Reference in New Issue
Block a user