kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'refactor/freertos_move_idf_specific_functions' into 'master'
refactor(freertos/idf): Move IDF FreeRTOS API additions to header files Closes IDF-7201, IDF-3873, and IDF-7907 See merge request espressif/esp-idf!25615pull/12212/head
commit
c60cbcee5c
|
@ -99,13 +99,9 @@ endif()
|
|||
|
||||
# Add ESP-additions source files
|
||||
list(APPEND srcs
|
||||
"esp_additions/freertos_compatibility.c"
|
||||
"esp_additions/idf_additions.c")
|
||||
|
||||
if(kernel_impl STREQUAL "FreeRTOS-Kernel")
|
||||
list(APPEND srcs
|
||||
"esp_additions/freertos_compatibility.c")
|
||||
endif()
|
||||
|
||||
if(arch STREQUAL "linux")
|
||||
# Check if we need to address the FreeRTOS EINTR coexistence with linux system calls if we're building without
|
||||
# lwIP, we need to use linux system select which will receive EINTR event on every FreeRTOS interrupt, we
|
||||
|
|
|
@ -1393,11 +1393,29 @@ typedef StaticStreamBuffer_t StaticMessageBuffer_t;
|
|||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* IDF API additions have been moved to idf_additions.h when building for
|
||||
* Amazon SMP FreeRTOS. However, the rest of ESP-IDF has not been updated to
|
||||
* include this header explicitly when calling this additional API. Thus, we
|
||||
* include this here as a workaround until the rest of ESP-IDF can be updated
|
||||
* to include idf_additions.h explicitly. */
|
||||
#include "freertos/idf_additions.h"
|
||||
/*-----------------------------------------------------------
|
||||
* 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 */
|
||||
|
|
|
@ -3306,25 +3306,6 @@ void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNC
|
|||
*/
|
||||
void vTaskYieldWithinAPI( void );
|
||||
|
||||
/* ------------------------------------------------ IDF Compatibility --------------------------------------------------
|
||||
*
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
/*
|
||||
Workaround for non-thread safe multi-core OS startup (see IDF-4524)
|
||||
This function must be called with interrupts disabled on all cores other than
|
||||
core 0 during startup.
|
||||
*/
|
||||
void vTaskStartSchedulerOtherCores( void );
|
||||
#endif // configNUM_CORES > 1
|
||||
|
||||
#include "freertos/idf_additions.h"
|
||||
|
||||
#endif //ESP_PLATFORM
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "xtensa/config/core.h"
|
||||
#include "xtensa/config/core-isa.h"
|
||||
#include "xtensa/xtruntime.h"
|
||||
#include "esp_private/freertos_idf_additions_priv.h"
|
||||
#include "esp_private/esp_int_wdt.h"
|
||||
#include "esp_private/systimer.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
|
@ -328,7 +329,7 @@ BaseType_t xPortStartScheduler( void )
|
|||
#if configNUM_CORES > 1
|
||||
// Workaround for non-thread safe multi-core OS startup (see IDF-4524)
|
||||
if (xPortGetCoreID() != 0) {
|
||||
vTaskStartSchedulerOtherCores();
|
||||
prvStartSchedulerOtherCores();
|
||||
}
|
||||
#endif // configNUM_CORES > 1
|
||||
|
||||
|
|
|
@ -6506,14 +6506,3 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
|
|||
#endif
|
||||
|
||||
#endif /* if ( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 ) */
|
||||
|
||||
#if ( ( ESP_PLATFORM == 1 ) && ( configNUM_CORES > 1 ) )
|
||||
/*
|
||||
Workaround for non-thread safe multi-core OS startup (see IDF-4524)
|
||||
*/
|
||||
void vTaskStartSchedulerOtherCores( void )
|
||||
{
|
||||
/* This function is always called with interrupts disabled*/
|
||||
xSchedulerRunning = pdTRUE;
|
||||
}
|
||||
#endif // ( ESP_PLATFORM == 1 ) && ( configNUM_CORES > 1
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -45,6 +45,8 @@
|
|||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "event_groups.h"
|
||||
/* Include private IDF API additions for critical thread safety macros */
|
||||
#include "esp_private/freertos_idf_additions_priv.h"
|
||||
|
||||
/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified
|
||||
* because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
|
||||
|
@ -566,8 +568,8 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
|||
#if ( configNUM_CORES > 1 )
|
||||
|
||||
/* We are about to traverse a task list which is a kernel data structure.
|
||||
* Thus we need to call vTaskTakeKernelLock() to take the kernel lock. */
|
||||
vTaskTakeKernelLock();
|
||||
* Thus we need to call prvTakeKernelLock() to take the kernel lock. */
|
||||
prvTakeKernelLock();
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
{
|
||||
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||
|
@ -642,7 +644,7 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
|||
}
|
||||
#if ( configNUM_CORES > 1 )
|
||||
/* Release the previously taken kernel lock. */
|
||||
vTaskReleaseKernelLock();
|
||||
prvReleaseKernelLock();
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
( void ) prvEXIT_CRITICAL_OR_RESUME_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
|
||||
|
@ -659,8 +661,8 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
|||
#if ( configNUM_CORES > 1 )
|
||||
|
||||
/* We are about to traverse a task list which is a kernel data structure.
|
||||
* Thus we need to call vTaskTakeKernelLock() to take the kernel lock. */
|
||||
vTaskTakeKernelLock();
|
||||
* Thus we need to call prvTakeKernelLock() to take the kernel lock. */
|
||||
prvTakeKernelLock();
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
{
|
||||
traceEVENT_GROUP_DELETE( xEventGroup );
|
||||
|
@ -675,7 +677,7 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
|||
}
|
||||
#if ( configNUM_CORES > 1 )
|
||||
/* Release the previously taken kernel lock. */
|
||||
vTaskReleaseKernelLock();
|
||||
prvReleaseKernelLock();
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
prvEXIT_CRITICAL_OR_RESUME_ALL( &( pxEventBits->xEventGroupLock ) );
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -1404,4 +1404,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 */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -285,204 +285,6 @@ typedef enum
|
|||
* TASK CREATION API
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Create a new task with a specified affinity and add it to the list of tasks
|
||||
* that are ready to run.
|
||||
*
|
||||
* This function is similar to xTaskCreate, but allows setting task affinity
|
||||
* in SMP system.
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function. Tasks
|
||||
* must be implemented to never return (i.e. continuous loop), or should be
|
||||
* terminated using vTaskDelete function.
|
||||
*
|
||||
* @param pcName A descriptive name for the task. This is mainly used to
|
||||
* 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
|
||||
* bytes. Note that this differs from vanilla FreeRTOS.
|
||||
*
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
*
|
||||
* @param uxPriority The priority at which the task should run. Systems that
|
||||
* include MPU support can optionally create tasks in a privileged (system)
|
||||
* mode by setting bit portPRIVILEGE_BIT of the priority parameter. For
|
||||
* example, to create a privileged task at priority 2 the uxPriority parameter
|
||||
* should be set to ( 2 | portPRIVILEGE_BIT ).
|
||||
*
|
||||
* @param[out] pvCreatedTask Used to pass back a handle by which the created task
|
||||
* can be referenced.
|
||||
*
|
||||
* @param xCoreID If the value is tskNO_AFFINITY, the created task is not
|
||||
* pinned to any CPU, and the scheduler can run it on any core available.
|
||||
* Values 0 or 1 indicate the index number of the CPU which the task should
|
||||
* be pinned to. Specifying values larger than (configNUM_CORES - 1) will
|
||||
* cause the function to fail.
|
||||
*
|
||||
* @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.
|
||||
* void vTaskCode( void * pvParameters )
|
||||
* {
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Task code goes here.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Function that creates a task.
|
||||
* void vOtherFunction( void )
|
||||
* {
|
||||
* static uint8_t ucParameterToPass;
|
||||
* TaskHandle_t xHandle = NULL;
|
||||
*
|
||||
* // Create the task pinned to core 0, storing the handle. Note that the passed parameter ucParameterToPass
|
||||
* // must exist for the lifetime of the task, so in this case is declared static. If it was just an
|
||||
* // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
|
||||
* // the new task attempts to access it.
|
||||
* xTaskCreatePinnedToCore( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle, 0 );
|
||||
* configASSERT( xHandle );
|
||||
*
|
||||
* // Use the handle to delete the task.
|
||||
* if( xHandle != NULL )
|
||||
* {
|
||||
* vTaskDelete( xHandle );
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @cond !DOC_SINGLE_GROUP
|
||||
* \defgroup xTaskCreatePinnedToCore xTaskCreatePinnedToCore
|
||||
* @endcond
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
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 );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Create a new task with a specified affinity and add it to the list of tasks
|
||||
* that are ready to run.
|
||||
*
|
||||
* This function is similar to xTaskCreateStatic, but allows specifying
|
||||
* task affinity in an SMP system.
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function. Tasks
|
||||
* must be implemented to never return (i.e. continuous loop), or should be
|
||||
* terminated using vTaskDelete function.
|
||||
*
|
||||
* @param pcName A descriptive name for the task. This is mainly used to
|
||||
* 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
|
||||
* bytes. Note that this differs from vanilla FreeRTOS.
|
||||
*
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
*
|
||||
* @param uxPriority The priority at which the task will run.
|
||||
*
|
||||
* @param pxStackBuffer Must point to a StackType_t array that has at least
|
||||
* ulStackDepth indexes - the array will then be used as the task's stack,
|
||||
* removing the need for the stack to be allocated dynamically.
|
||||
*
|
||||
* @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will
|
||||
* then be used to hold the task's data structures, removing the need for the
|
||||
* memory to be allocated dynamically.
|
||||
*
|
||||
* @param xCoreID If the value is tskNO_AFFINITY, the created task is not
|
||||
* pinned to any CPU, and the scheduler can run it on any core available.
|
||||
* Values 0 or 1 indicate the index number of the CPU which the task should
|
||||
* be pinned to. Specifying values larger than (configNUM_CORES - 1) will
|
||||
* cause the function to fail.
|
||||
*
|
||||
* @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will
|
||||
* be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer
|
||||
* are NULL then the task will not be created and
|
||||
* errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
*
|
||||
* // Dimensions the buffer that the task being created will use as its stack.
|
||||
* // NOTE: This is the number of words the stack will hold, not the number of
|
||||
* // bytes. For example, if each stack item is 32-bits, and this is set to 100,
|
||||
* // then 400 bytes (100 * 32-bits) will be allocated.
|
||||
* #define STACK_SIZE 200
|
||||
*
|
||||
* // Structure that will hold the TCB of the task being created.
|
||||
* StaticTask_t xTaskBuffer;
|
||||
*
|
||||
* // Buffer that the task being created will use as its stack. Note this is
|
||||
* // an array of StackType_t variables. The size of StackType_t is dependent on
|
||||
* // the RTOS port.
|
||||
* StackType_t xStack[ STACK_SIZE ];
|
||||
*
|
||||
* // Function that implements the task being created.
|
||||
* void vTaskCode( void * pvParameters )
|
||||
* {
|
||||
* // The parameter value is expected to be 1 as 1 is passed in the
|
||||
* // pvParameters value in the call to xTaskCreateStaticPinnedToCore().
|
||||
* configASSERT( ( uint32_t ) pvParameters == 1UL );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Task code goes here.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Function that creates a task.
|
||||
* void vOtherFunction( void )
|
||||
* {
|
||||
* TaskHandle_t xHandle = NULL;
|
||||
*
|
||||
* // Create the task pinned to core 0 without using any dynamic memory allocation.
|
||||
* xHandle = xTaskCreateStaticPinnedToCore(
|
||||
* vTaskCode, // Function that implements the task.
|
||||
* "NAME", // Text name for the task.
|
||||
* STACK_SIZE, // Stack size in bytes, not words.
|
||||
* ( void * ) 1, // Parameter passed into the task.
|
||||
* tskIDLE_PRIORITY,// Priority at which the task is created.
|
||||
* xStack, // Array to use as the task's stack.
|
||||
* &xTaskBuffer, // Variable to hold the task's data structure.
|
||||
* 0 ); // Specify the task's core affinity
|
||||
*
|
||||
* // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
|
||||
* // been created, and xHandle will be the task's handle. Use the handle
|
||||
* // to suspend the task.
|
||||
* vTaskSuspend( xHandle );
|
||||
* }
|
||||
* @endcode
|
||||
* @cond !DOC_SINGLE_GROUP
|
||||
* \defgroup xTaskCreateStaticPinnedToCore xTaskCreateStaticPinnedToCore
|
||||
* @endcond
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#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 pxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer,
|
||||
const BaseType_t xCoreID );
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/**
|
||||
* @cond !DOC_EXCLUDE_HEADER_SECTION
|
||||
* task. h
|
||||
|
@ -526,8 +328,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
|
||||
* bytes. Note that this differs from vanilla FreeRTOS.
|
||||
* @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.
|
||||
|
@ -584,6 +386,7 @@ 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. */
|
||||
|
@ -592,8 +395,31 @@ typedef enum
|
|||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION
|
||||
{
|
||||
return xTaskCreatePinnedToCore( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, tskNO_AFFINITY );
|
||||
/*
|
||||
* 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 /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
|
||||
|
||||
/**
|
||||
|
@ -630,8 +456,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
|
||||
* bytes. Note that this differs from vanilla FreeRTOS.
|
||||
* @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.
|
||||
|
@ -706,8 +532,8 @@ typedef enum
|
|||
* @endcode
|
||||
* \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. */
|
||||
|
@ -717,8 +543,32 @@ typedef enum
|
|||
StackType_t * const puxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION
|
||||
{
|
||||
return xTaskCreateStaticPinnedToCore( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, tskNO_AFFINITY );
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
/**
|
||||
|
@ -1950,21 +1800,6 @@ UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTIO
|
|||
*/
|
||||
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* Returns the start of the stack associated with xTask.
|
||||
*
|
||||
* INCLUDE_pxTaskGetStackStart must be set to 1 in FreeRTOSConfig.h for
|
||||
* this function to be available.
|
||||
*
|
||||
* Returns the lowest stack memory address, regardless of whether the stack grows up or down.
|
||||
*
|
||||
* @param xTask Handle of the task associated with the stack returned.
|
||||
* Set xTask to NULL to return the stack of the calling task.
|
||||
*
|
||||
* @return A pointer to the start of the stack.
|
||||
*/
|
||||
uint8_t * pxTaskGetStackStart( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/* When using trace macros it is sometimes necessary to include task.h before
|
||||
* FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined,
|
||||
* so the following two prototypes will cause a compilation error. This can be
|
||||
|
@ -2039,7 +1874,6 @@ uint8_t * pxTaskGetStackStart( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
|||
BaseType_t xIndex,
|
||||
void * pvValue ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
/**
|
||||
* Get local storage pointer specific to the given task.
|
||||
*
|
||||
|
@ -2056,39 +1890,6 @@ uint8_t * pxTaskGetStackStart( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
|||
void * pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
|
||||
BaseType_t xIndex ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 )
|
||||
|
||||
/**
|
||||
* Prototype of local storage pointer deletion callback.
|
||||
*/
|
||||
typedef void (*TlsDeleteCallbackFunction_t)( int, void * );
|
||||
|
||||
/**
|
||||
* Set local storage pointer and deletion callback.
|
||||
*
|
||||
* Each task contains an array of pointers that is dimensioned by the
|
||||
* configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h.
|
||||
* The kernel does not use the pointers itself, so the application writer
|
||||
* can use the pointers for any purpose they wish.
|
||||
*
|
||||
* Local storage pointers set for a task can reference dynamically
|
||||
* allocated resources. This function is similar to
|
||||
* vTaskSetThreadLocalStoragePointer, but provides a way to release
|
||||
* these resources when the task gets deleted. For each pointer,
|
||||
* a callback function can be set. This function will be called
|
||||
* when task is deleted, with the local storage pointer index
|
||||
* and value as arguments.
|
||||
*
|
||||
* @param xTaskToSet Task to set thread local storage pointer for
|
||||
* @param xIndex The index of the pointer to set, from 0 to
|
||||
* configNUM_THREAD_LOCAL_STORAGE_POINTERS - 1.
|
||||
* @param pvValue Pointer value to set.
|
||||
* @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
|
||||
|
||||
#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) */
|
||||
|
||||
#if ( configCHECK_FOR_STACK_OVERFLOW > 0 )
|
||||
|
@ -3439,58 +3240,6 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION;
|
|||
*----------------------------------------------------------*/
|
||||
/** @cond !DOC_EXCLUDE_HEADER_SECTION */
|
||||
|
||||
/*
|
||||
* Various convenience macros for critical sections and scheduler suspension
|
||||
* called by other FreeRTOS sources and not meant to be called by the
|
||||
* application. The behavior of each macro depends on whether FreeRTOS is
|
||||
* currently configured for SMP or single core.
|
||||
*/
|
||||
#if ( configNUM_CORES > 1 )
|
||||
#define prvENTER_CRITICAL_OR_SUSPEND_ALL( x ) taskENTER_CRITICAL( ( x ) )
|
||||
#define prvEXIT_CRITICAL_OR_RESUME_ALL( x ) ( { taskEXIT_CRITICAL( ( x ) ); pdFALSE; } )
|
||||
#define prvENTER_CRITICAL_OR_MASK_ISR( pxLock, uxInterruptStatus ) \
|
||||
taskENTER_CRITICAL_ISR( ( pxLock ) ); \
|
||||
( void ) ( uxInterruptStatus );
|
||||
#define prvEXIT_CRITICAL_OR_UNMASK_ISR( pxLock, uxInterruptStatus ) \
|
||||
taskEXIT_CRITICAL_ISR( ( pxLock ) ); \
|
||||
( void ) ( uxInterruptStatus );
|
||||
#else /* configNUM_CORES > 1 */
|
||||
#define prvENTER_CRITICAL_OR_SUSPEND_ALL( x ) ( { vTaskSuspendAll(); ( void ) ( x ); } )
|
||||
#define prvEXIT_CRITICAL_OR_RESUME_ALL( x ) xTaskResumeAll()
|
||||
#define prvENTER_CRITICAL_OR_MASK_ISR( pxLock, uxInterruptStatus ) \
|
||||
( uxInterruptStatus ) = portSET_INTERRUPT_MASK_FROM_ISR(); \
|
||||
( void ) ( pxLock );
|
||||
#define prvEXIT_CRITICAL_OR_UNMASK_ISR( pxLock, uxInterruptStatus ) \
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ( uxInterruptStatus ) ); \
|
||||
( void ) ( pxLock );
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
|
||||
/*
|
||||
* Return the handle of the task running on a certain CPU. Because of
|
||||
* the nature of SMP processing, there is no guarantee that this
|
||||
* value will still be valid on return and should only be used for
|
||||
* debugging purposes.
|
||||
*/
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t cpuid );
|
||||
|
||||
/**
|
||||
* Get the handle of idle task for the given CPU.
|
||||
*
|
||||
* xTaskGetIdleTaskHandleForCPU() is only available if
|
||||
* INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* @param cpuid The CPU to get the handle for
|
||||
*
|
||||
* @return Idle task handle of a given cpu. It is not valid to call
|
||||
* xTaskGetIdleTaskHandleForCPU() before the scheduler has been started.
|
||||
*/
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCPU( UBaseType_t cpuid );
|
||||
|
||||
/*
|
||||
* Get the current core affinity of a task
|
||||
*/
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
|
||||
* INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
|
||||
|
@ -3511,20 +3260,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
|||
*/
|
||||
BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
|
||||
* INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
|
||||
* AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
|
||||
*
|
||||
* Called from all other cores except core 0 when their tick interrupt
|
||||
* occurs. This function will check if the current core requires time slicing,
|
||||
* and also call the application tick hook.
|
||||
*/
|
||||
BaseType_t xTaskIncrementTickOtherCores( void ) PRIVILEGED_FUNCTION;
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
|
||||
* INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
|
||||
|
@ -3577,26 +3312,6 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList,
|
|||
TickType_t xTicksToWait,
|
||||
const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION;
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
|
||||
* INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
|
||||
*
|
||||
* This function is a wrapper to take the "xKernelLock" spinlock of tasks.c.
|
||||
* This lock is taken whenver any of the kernel's data structures are
|
||||
* accessed/modified, such as when adding/removing tasks to/from the delayed
|
||||
* task list or various event lists.
|
||||
*
|
||||
* This functions is meant to be called by xEventGroupSetBits() and
|
||||
* vEventGroupDelete() as both those functions will access event lists (instead
|
||||
* of delegating the entire responsibility to one of vTask...EventList()
|
||||
* functions).
|
||||
*/
|
||||
void vTaskTakeKernelLock( void );
|
||||
void vTaskReleaseKernelLock( void );
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
|
||||
/*
|
||||
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
|
||||
* INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
/* Include private IDF API additions for critical thread safety macros */
|
||||
#include "esp_private/freertos_idf_additions_priv.h"
|
||||
|
||||
#if ( configUSE_CO_ROUTINES == 1 )
|
||||
#include "croutine.h"
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "stream_buffer.h"
|
||||
/* Include private IDF API additions for critical thread safety macros */
|
||||
#include "esp_private/freertos_idf_additions_priv.h"
|
||||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS != 1 )
|
||||
#error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "stack_macros.h"
|
||||
/* Include private IDF API additions for critical thread safety macros */
|
||||
#include "esp_private/freertos_idf_additions_priv.h"
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#undef _REENT_INIT_PTR
|
||||
|
@ -502,28 +504,6 @@ PRIVILEGED_DATA static volatile BaseType_t xSwitchingContext[ configNUM_CORES ]
|
|||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Callback function prototypes. --------------------------*/
|
||||
#if ( configCHECK_FOR_STACK_OVERFLOW > 0 )
|
||||
|
||||
extern void vApplicationStackOverflowHook( TaskHandle_t xTask,
|
||||
char * pcTaskName );
|
||||
|
||||
#endif
|
||||
|
||||
#if ( configUSE_TICK_HOOK > 0 )
|
||||
|
||||
extern void vApplicationTickHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */
|
||||
|
||||
#endif
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
extern void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
|
||||
StackType_t ** ppxIdleTaskStackBuffer,
|
||||
uint32_t * pulIdleTaskStackSize ); /*lint !e526 Symbol not defined as it is an application callback. */
|
||||
|
||||
#endif
|
||||
|
||||
/* File private functions. --------------------------------*/
|
||||
|
||||
/**
|
||||
|
@ -728,64 +708,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#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 )
|
||||
{
|
||||
TCB_t * pxNewTCB;
|
||||
TaskHandle_t xReturn;
|
||||
|
||||
configASSERT( portVALID_STACK_MEM( puxStackBuffer ) );
|
||||
configASSERT( portVALID_TCB_MEM( pxTaskBuffer ) );
|
||||
configASSERT( ( ( xCoreID >= 0 ) && ( xCoreID < configNUM_CORES ) ) || ( xCoreID == tskNO_AFFINITY ) );
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
/* Sanity check that the size of the structure used to declare a
|
||||
* variable of type StaticTask_t equals the size of the real task
|
||||
* structure. */
|
||||
volatile size_t xSize = sizeof( StaticTask_t );
|
||||
configASSERT( xSize == sizeof( TCB_t ) );
|
||||
( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )
|
||||
{
|
||||
/* The memory used for the task's TCB and stack are passed into this
|
||||
* function - use them. */
|
||||
pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
|
||||
pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer;
|
||||
|
||||
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
* task was created statically in case the task is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL, xCoreID );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = NULL;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* SUPPORT_STATIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
|
||||
BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
|
||||
|
@ -885,100 +807,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
BaseType_t xTaskCreatePinnedToCore( 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,
|
||||
const BaseType_t xCoreID )
|
||||
{
|
||||
TCB_t * pxNewTCB;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* If the stack grows down then allocate the stack then the TCB so the stack
|
||||
* does not grow into the TCB. Likewise if the stack grows up then allocate
|
||||
* the TCB then the stack. */
|
||||
#if ( portSTACK_GROWTH > 0 )
|
||||
{
|
||||
/* Allocate space for the TCB. Where the memory comes from depends on
|
||||
* the implementation of the port malloc function and whether or not static
|
||||
* allocation is being used. */
|
||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
/* Allocate space for the stack used by the task being created.
|
||||
* The base of the stack memory stored in the TCB so the task can
|
||||
* be deleted later if required. */
|
||||
pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||
|
||||
if( pxNewTCB->pxStack == NULL )
|
||||
{
|
||||
/* Could not allocate the stack. Delete the allocated TCB. */
|
||||
vPortFree( pxNewTCB );
|
||||
pxNewTCB = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* portSTACK_GROWTH */
|
||||
{
|
||||
StackType_t * pxStack;
|
||||
|
||||
/* Allocate space for the stack used by the task being created. */
|
||||
pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */
|
||||
|
||||
if( pxStack != NULL )
|
||||
{
|
||||
/* Allocate space for the TCB. */
|
||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
/* Store the stack location in the TCB. */
|
||||
pxNewTCB->pxStack = pxStack;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The stack cannot be used as the TCB was not created. Free
|
||||
* it again. */
|
||||
vPortFree( pxStack );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pxNewTCB = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* portSTACK_GROWTH */
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
* task was created dynamically in case it is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, xCoreID );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const uint32_t ulStackDepth,
|
||||
|
@ -1528,15 +1356,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB )
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_xTaskDelayUntil == 1 )
|
||||
#ifdef ESP_PLATFORM
|
||||
/* backward binary compatibility - remove later */
|
||||
#undef vTaskDelayUntil
|
||||
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
||||
const TickType_t xTimeIncrement )
|
||||
{
|
||||
xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement );
|
||||
}
|
||||
#endif // ESP_PLATFORM
|
||||
|
||||
BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
||||
const TickType_t xTimeIncrement )
|
||||
|
@ -3014,12 +2833,6 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char
|
|||
return xIdleTaskHandle[ xPortGetCoreID() ];
|
||||
}
|
||||
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCPU( UBaseType_t cpuid )
|
||||
{
|
||||
configASSERT( cpuid < configNUM_CORES );
|
||||
configASSERT( ( xIdleTaskHandle[ cpuid ] != NULL ) );
|
||||
return xIdleTaskHandle[ cpuid ];
|
||||
}
|
||||
#endif /* INCLUDE_xTaskGetIdleTaskHandle */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
|
@ -3367,90 +3180,6 @@ BaseType_t xTaskIncrementTick( void )
|
|||
|
||||
return xSwitchRequired;
|
||||
}
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
BaseType_t xTaskIncrementTickOtherCores( void )
|
||||
{
|
||||
/* Minor optimization. This function can never switch cores mid
|
||||
* execution */
|
||||
BaseType_t xCoreID = xPortGetCoreID();
|
||||
BaseType_t xSwitchRequired = pdFALSE;
|
||||
|
||||
/* This function should never be called by Core 0. */
|
||||
configASSERT( xCoreID != 0 );
|
||||
|
||||
/* Called by the portable layer each time a tick interrupt occurs.
|
||||
* Increments the tick then checks to see if the new tick value will cause any
|
||||
* tasks to be unblocked. */
|
||||
traceTASK_INCREMENT_TICK( xTickCount );
|
||||
|
||||
if( uxSchedulerSuspended[ xCoreID ] == ( UBaseType_t ) 0U )
|
||||
{
|
||||
/* We need take the kernel lock here as we are about to access
|
||||
* kernel data structures. */
|
||||
taskENTER_CRITICAL_ISR( &xKernelLock );
|
||||
|
||||
/* A task being unblocked cannot cause an immediate context switch
|
||||
* if preemption is turned off. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
{
|
||||
/* Check if core 0 calling xTaskIncrementTick() has
|
||||
* unblocked a task that can be run. */
|
||||
if( uxTopReadyPriority > pxCurrentTCB[ xCoreID ]->uxPriority )
|
||||
{
|
||||
xSwitchRequired = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
|
||||
/* Tasks of equal priority to the currently running task will share
|
||||
* processing time (time slice) if preemption is on, and the application
|
||||
* writer has not explicitly turned time slicing off. */
|
||||
#if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) )
|
||||
{
|
||||
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB[ xCoreID ]->uxPriority ] ) ) > ( UBaseType_t ) 1 )
|
||||
{
|
||||
xSwitchRequired = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */
|
||||
|
||||
/* Release the previously taken kernel lock as we have finished
|
||||
* accessing the kernel data structures. */
|
||||
taskEXIT_CRITICAL_ISR( &xKernelLock );
|
||||
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
{
|
||||
if( xYieldPending[ xCoreID ] != pdFALSE )
|
||||
{
|
||||
xSwitchRequired = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* configUSE_PREEMPTION */
|
||||
}
|
||||
|
||||
#if ( configUSE_TICK_HOOK == 1 )
|
||||
{
|
||||
vApplicationTickHook();
|
||||
}
|
||||
#endif
|
||||
|
||||
return xSwitchRequired;
|
||||
}
|
||||
#endif /* ( configNUM_CORES > 1 ) */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
|
||||
|
@ -4008,20 +3737,6 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
void vTaskTakeKernelLock( void )
|
||||
{
|
||||
/* We call the tasks.c critical section macro to take xKernelLock */
|
||||
taskENTER_CRITICAL( &xKernelLock );
|
||||
}
|
||||
|
||||
void vTaskReleaseKernelLock( void )
|
||||
{
|
||||
/* We call the tasks.c critical section macro to release xKernelLock */
|
||||
taskEXIT_CRITICAL( &xKernelLock );
|
||||
}
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
|
||||
void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
|
||||
const TickType_t xItemValue )
|
||||
{
|
||||
|
@ -4032,7 +3747,7 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
|
|||
|
||||
/* THIS FUNCTION MUST BE CALLED WITH THE KERNEL LOCK ALREADY TAKEN.
|
||||
* It is used by the event flags implementation, thus those functions
|
||||
* should call vTaskTakeKernelLock() before calling this function. */
|
||||
* should call prvTakeKernelLock() before calling this function. */
|
||||
#else /* configNUM_CORES > 1 */
|
||||
|
||||
/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by
|
||||
|
@ -4442,79 +4157,42 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
|
|||
|
||||
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
|
||||
|
||||
#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 )
|
||||
|
||||
void vTaskSetThreadLocalStoragePointerAndDelCallback( TaskHandle_t xTaskToSet,
|
||||
BaseType_t xIndex,
|
||||
void * pvValue,
|
||||
TlsDeleteCallbackFunction_t xDelCallback )
|
||||
void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
|
||||
BaseType_t xIndex,
|
||||
void * pvValue )
|
||||
{
|
||||
#if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 )
|
||||
{
|
||||
/* TLSP Deletion Callbacks are enabled. Call the TLSPDC funciton
|
||||
* instead with a NULL callback. */
|
||||
vTaskSetThreadLocalStoragePointerAndDelCallback( xTaskToSet, xIndex, pvValue, NULL );
|
||||
}
|
||||
#else /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 */
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
|
||||
/* If TLSP deletion callbacks are enabled, then
|
||||
* configNUM_THREAD_LOCAL_STORAGE_POINTERS is doubled in size so
|
||||
* that the latter half of the pvThreadLocalStoragePointers stores
|
||||
* the deletion callbacks. */
|
||||
if( xIndex < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) )
|
||||
{
|
||||
#if ( configNUM_CORES > 1 )
|
||||
#if ( configNUM_CORES > 1 )
|
||||
|
||||
/* For SMP, we need to take the kernel lock here as we
|
||||
* another core could also update this task's TLSP at the
|
||||
* same time. */
|
||||
taskENTER_CRITICAL( &xKernelLock );
|
||||
#endif /* ( configNUM_CORES > 1 ) */
|
||||
|
||||
pxTCB = prvGetTCBFromHandle( xTaskToSet );
|
||||
/* Store the TLSP by indexing the first half of the array */
|
||||
pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue;
|
||||
/* Store the TLSP deletion callback by indexing the second half
|
||||
* of the array. */
|
||||
pxTCB->pvThreadLocalStoragePointers[ ( xIndex + ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ) ] = ( void * ) xDelCallback;
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
/* Release the previously taken kernel lock. */
|
||||
taskEXIT_CRITICAL( &xKernelLock );
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
|
||||
BaseType_t xIndex,
|
||||
void * pvValue )
|
||||
{
|
||||
vTaskSetThreadLocalStoragePointerAndDelCallback( xTaskToSet, xIndex, pvValue, ( TlsDeleteCallbackFunction_t ) NULL );
|
||||
}
|
||||
|
||||
|
||||
#else /* if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) */
|
||||
void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
|
||||
BaseType_t xIndex,
|
||||
void * pvValue )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
/* For SMP, we need to take the kernel lock here as we
|
||||
* another core could also update this task's TLSP at the
|
||||
* same time. */
|
||||
taskENTER_CRITICAL( &xKernelLock );
|
||||
#endif /* ( configNUM_CORES > 1 ) */
|
||||
|
||||
if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS )
|
||||
{
|
||||
#if ( configNUM_CORES > 1 )
|
||||
|
||||
/* For SMP, we need to take the kernel lock here as we
|
||||
* another core could also update this task's TLSP at the
|
||||
* same time. */
|
||||
taskENTER_CRITICAL( &xKernelLock );
|
||||
#endif /* ( configNUM_CORES > 1 ) */
|
||||
|
||||
pxTCB = prvGetTCBFromHandle( xTaskToSet );
|
||||
configASSERT( pxTCB != NULL );
|
||||
pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue;
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
/* Release the previously taken kernel lock. */
|
||||
taskEXIT_CRITICAL( &xKernelLock );
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
}
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
/* Release the previously taken kernel lock. */
|
||||
taskEXIT_CRITICAL( &xKernelLock );
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
}
|
||||
#endif /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 */
|
||||
#endif /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 */
|
||||
}
|
||||
|
||||
#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -4773,16 +4451,6 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
#endif /* configUSE_TRACE_FACILITY */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
|
||||
pxTCB = prvGetTCBFromHandle( xTask );
|
||||
|
||||
return pxTCB->xCoreID;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t * pxTaskStatusArray,
|
||||
|
@ -4905,20 +4573,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
|||
|
||||
#endif /* INCLUDE_uxTaskGetStackHighWaterMark */
|
||||
/*-----------------------------------------------------------*/
|
||||
#if ( INCLUDE_pxTaskGetStackStart == 1 )
|
||||
|
||||
uint8_t * pxTaskGetStackStart( TaskHandle_t xTask )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
uint8_t * uxReturn;
|
||||
|
||||
pxTCB = prvGetTCBFromHandle( xTask );
|
||||
uxReturn = ( uint8_t * ) pxTCB->pxStack;
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_pxTaskGetStackStart */
|
||||
|
||||
#if ( INCLUDE_vTaskDelete == 1 )
|
||||
|
||||
|
@ -5006,7 +4660,7 @@ static void prvResetNextTaskUnblockTime( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) || ( configNUM_CORES > 1 ) )
|
||||
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
|
||||
|
||||
TaskHandle_t xTaskGetCurrentTaskHandle( void )
|
||||
{
|
||||
|
@ -5020,19 +4674,6 @@ static void prvResetNextTaskUnblockTime( void )
|
|||
return xReturn;
|
||||
}
|
||||
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t cpuid )
|
||||
{
|
||||
TaskHandle_t xReturn = NULL;
|
||||
|
||||
/*Xtensa-specific: the pxCurrentPCB pointer is atomic so we shouldn't need a lock. */
|
||||
if( cpuid < configNUM_CORES )
|
||||
{
|
||||
xReturn = pxCurrentTCB[ cpuid ];
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -5772,16 +5413,6 @@ TickType_t uxTaskResetEventItemValue( void )
|
|||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
|
||||
#ifdef ESP_PLATFORM /* IDF-3851 */
|
||||
/* included here for backward binary compatibility */
|
||||
#undef ulTaskNotifyTake
|
||||
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit,
|
||||
TickType_t xTicksToWait )
|
||||
{
|
||||
return ulTaskGenericNotifyTake( tskDEFAULT_INDEX_TO_NOTIFY, xClearCountOnExit, xTicksToWait );
|
||||
}
|
||||
#endif // ESP-PLATFORM
|
||||
|
||||
uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWait,
|
||||
BaseType_t xClearCountOnExit,
|
||||
TickType_t xTicksToWait )
|
||||
|
@ -5854,18 +5485,6 @@ TickType_t uxTaskResetEventItemValue( void )
|
|||
|
||||
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
|
||||
#ifdef ESP_PLATFORM /* IDF-3851 */
|
||||
/* included for backward compatibility */
|
||||
#undef xTaskNotifyWait
|
||||
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry,
|
||||
uint32_t ulBitsToClearOnExit,
|
||||
uint32_t * pulNotificationValue,
|
||||
TickType_t xTicksToWait )
|
||||
{
|
||||
return xTaskGenericNotifyWait( tskDEFAULT_INDEX_TO_NOTIFY, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait );
|
||||
}
|
||||
#endif // ESP-PLATFORM
|
||||
|
||||
BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWait,
|
||||
uint32_t ulBitsToClearOnEntry,
|
||||
uint32_t ulBitsToClearOnExit,
|
||||
|
@ -6533,9 +6152,3 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
|
|||
#endif
|
||||
|
||||
#endif /* if ( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 ) */
|
||||
|
||||
/* If timers.c is not referenced anywhere, don't create the timer task to save RAM */
|
||||
BaseType_t __attribute__( ( weak ) ) xTimerCreateTimerTask( void )
|
||||
{
|
||||
return pdPASS;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "timers.h"
|
||||
/* Include private IDF API additions for critical thread safety macros */
|
||||
#include "esp_private/freertos_idf_additions_priv.h"
|
||||
|
||||
#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 )
|
||||
#error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.
|
||||
|
|
|
@ -198,8 +198,6 @@
|
|||
#define INCLUDE_xTaskResumeFromISR 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
/* Unlisted */
|
||||
#define INCLUDE_pxTaskGetStackStart 1
|
||||
|
||||
/* -------------------- Trace Macros ----------------------- */
|
||||
|
||||
|
|
|
@ -35,3 +35,45 @@ BaseType_t xQueueGenericReceive( QueueHandle_t xQueue,
|
|||
|
||||
return xQueueReceive( xQueue, pvBuffer, xTicksToWait );
|
||||
}
|
||||
|
||||
/*
|
||||
* vTaskDelayUntil() was deprecated into a macro and replaced by xTaskDelayUntil().
|
||||
* This is added for pre-compiled libraries that depend on ulTaskNotifyTake()
|
||||
* being a function.
|
||||
*
|
||||
* Todo: Remove this in v6.0 (IDF-3851)
|
||||
*/
|
||||
#undef vTaskDelayUntil
|
||||
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
||||
const TickType_t xTimeIncrement )
|
||||
{
|
||||
xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement );
|
||||
}
|
||||
|
||||
/*
|
||||
* ulTaskNotifyTake() was turned into a macro. This is added for pre-compiled
|
||||
* libraries that depend on ulTaskNotifyTake() being a function.
|
||||
*
|
||||
* Todo: Remove this in v6.0 (IDF-3851)
|
||||
*/
|
||||
#undef ulTaskNotifyTake
|
||||
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit,
|
||||
TickType_t xTicksToWait )
|
||||
{
|
||||
return ulTaskGenericNotifyTake( tskDEFAULT_INDEX_TO_NOTIFY, xClearCountOnExit, xTicksToWait );
|
||||
}
|
||||
|
||||
/*
|
||||
* xTaskNotifyWait() was turned into a macro. This is added for pre-compiled
|
||||
* libraries that depend on xTaskNotifyWait() being a function.
|
||||
*
|
||||
* Todo: Remove this in v6.0 (IDF-3851)
|
||||
*/
|
||||
#undef xTaskNotifyWait
|
||||
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry,
|
||||
uint32_t ulBitsToClearOnExit,
|
||||
uint32_t * pulNotificationValue,
|
||||
TickType_t xTicksToWait )
|
||||
{
|
||||
return xTaskGenericNotifyWait( tskDEFAULT_INDEX_TO_NOTIFY, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait );
|
||||
}
|
||||
|
|
|
@ -4,9 +4,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_assert.h"
|
||||
#include "freertos/idf_additions.h"
|
||||
#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT
|
||||
#include "freertos/task_snapshot.h"
|
||||
|
@ -23,7 +22,7 @@
|
|||
|
||||
/* ------------------------------------------------- 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.
|
||||
*/
|
||||
|
@ -33,9 +32,139 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
|||
_Static_assert( tskNO_AFFINITY == CONFIG_FREERTOS_NO_AFFINITY, "CONFIG_FREERTOS_NO_AFFINITY must be the same as tskNO_AFFINITY" );
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
|
||||
/* ------------------------------------------------- Kernel Control ------------------------------------------------- */
|
||||
|
||||
#if ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) )
|
||||
|
||||
/*
|
||||
* Wrapper function to take "xKerneLock"
|
||||
*/
|
||||
void prvTakeKernelLock( void )
|
||||
{
|
||||
/* We call the tasks.c critical section macro to take xKernelLock */
|
||||
taskENTER_CRITICAL( &xKernelLock );
|
||||
}
|
||||
|
||||
#endif /* ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) )
|
||||
|
||||
/*
|
||||
* Wrapper function to release "xKerneLock"
|
||||
*/
|
||||
void prvReleaseKernelLock( void )
|
||||
{
|
||||
/* We call the tasks.c critical section macro to release xKernelLock */
|
||||
taskEXIT_CRITICAL( &xKernelLock );
|
||||
}
|
||||
|
||||
#endif /* ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) )
|
||||
|
||||
/*
|
||||
* Workaround for non-thread safe multi-core OS startup (see IDF-4524)
|
||||
*/
|
||||
void prvStartSchedulerOtherCores( void )
|
||||
{
|
||||
/* This function is always called with interrupts disabled*/
|
||||
xSchedulerRunning = pdTRUE;
|
||||
}
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) )
|
||||
|
||||
BaseType_t xTaskIncrementTickOtherCores( void )
|
||||
{
|
||||
/* Minor optimization. This function can never switch cores mid
|
||||
* execution */
|
||||
BaseType_t xCoreID = xPortGetCoreID();
|
||||
BaseType_t xSwitchRequired = pdFALSE;
|
||||
|
||||
/* This function should never be called by Core 0. */
|
||||
configASSERT( xCoreID != 0 );
|
||||
|
||||
/* Called by the portable layer each time a tick interrupt occurs.
|
||||
* Increments the tick then checks to see if the new tick value will
|
||||
* cause any tasks to be unblocked. */
|
||||
traceTASK_INCREMENT_TICK( xTickCount );
|
||||
|
||||
if( uxSchedulerSuspended[ xCoreID ] == ( UBaseType_t ) 0U )
|
||||
{
|
||||
/* We need take the kernel lock here as we are about to access
|
||||
* kernel data structures. */
|
||||
taskENTER_CRITICAL_ISR( &xKernelLock );
|
||||
|
||||
/* A task being unblocked cannot cause an immediate context switch
|
||||
* if preemption is turned off. */
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
{
|
||||
/* Check if core 0 calling xTaskIncrementTick() has
|
||||
* unblocked a task that can be run. */
|
||||
if( uxTopReadyPriority > pxCurrentTCB[ xCoreID ]->uxPriority )
|
||||
{
|
||||
xSwitchRequired = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* if ( configUSE_PREEMPTION == 1 ) */
|
||||
|
||||
/* Tasks of equal priority to the currently running task will share
|
||||
* processing time (time slice) if preemption is on, and the application
|
||||
* writer has not explicitly turned time slicing off. */
|
||||
#if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) )
|
||||
{
|
||||
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB[ xCoreID ]->uxPriority ] ) ) > ( UBaseType_t ) 1 )
|
||||
{
|
||||
xSwitchRequired = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */
|
||||
|
||||
/* Release the previously taken kernel lock as we have finished
|
||||
* accessing the kernel data structures. */
|
||||
taskEXIT_CRITICAL_ISR( &xKernelLock );
|
||||
|
||||
#if ( configUSE_PREEMPTION == 1 )
|
||||
{
|
||||
if( xYieldPending[ xCoreID ] != pdFALSE )
|
||||
{
|
||||
xSwitchRequired = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
#endif /* configUSE_PREEMPTION */
|
||||
}
|
||||
|
||||
#if ( configUSE_TICK_HOOK == 1 )
|
||||
{
|
||||
vApplicationTickHook();
|
||||
}
|
||||
#endif
|
||||
|
||||
return xSwitchRequired;
|
||||
}
|
||||
|
||||
#endif /* ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
/* -------------------------------------------------- Task Creation ------------------------------------------------- */
|
||||
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
|
@ -45,36 +174,126 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
|||
TaskHandle_t * const pxCreatedTask,
|
||||
const BaseType_t xCoreID )
|
||||
{
|
||||
BaseType_t ret;
|
||||
BaseType_t xReturn;
|
||||
|
||||
#if ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) )
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
{
|
||||
/* Convert xCoreID into an affinity mask */
|
||||
UBaseType_t uxCoreAffinityMask;
|
||||
|
||||
if( xCoreID == tskNO_AFFINITY )
|
||||
/* If using Amazon SMP FreeRTOS. This function is just a wrapper around
|
||||
* xTaskCreate() or xTaskCreateAffinitySet(). */
|
||||
#if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
{
|
||||
uxCoreAffinityMask = tskNO_AFFINITY;
|
||||
/* Convert xCoreID into an affinity mask */
|
||||
UBaseType_t uxCoreAffinityMask;
|
||||
|
||||
/* Bit shifting << xCoreID is only valid if we have less than
|
||||
* 32 cores. */
|
||||
ESP_STATIC_ASSERT( configNUM_CORES < 32 );
|
||||
|
||||
if( xCoreID == tskNO_AFFINITY )
|
||||
{
|
||||
uxCoreAffinityMask = tskNO_AFFINITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
uxCoreAffinityMask = ( 1 << xCoreID );
|
||||
}
|
||||
|
||||
xReturn = xTaskCreateAffinitySet( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, uxCoreAffinityMask, pxCreatedTask );
|
||||
}
|
||||
#else /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */
|
||||
{
|
||||
xReturn = xTaskCreate( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask );
|
||||
}
|
||||
#endif /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
{
|
||||
TCB_t * pxNewTCB;
|
||||
|
||||
/* If the stack grows down then allocate the stack then the TCB so the
|
||||
* stack does not grow into the TCB. Likewise if the stack grows up
|
||||
* then allocate the TCB then the stack. */
|
||||
#if ( portSTACK_GROWTH > 0 )
|
||||
{
|
||||
/* Allocate space for the TCB. Where the memory comes from depends on
|
||||
* the implementation of the port malloc function and whether or not static
|
||||
* allocation is being used. */
|
||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
/* Allocate space for the stack used by the task being created.
|
||||
* The base of the stack memory stored in the TCB so the task can
|
||||
* be deleted later if required. */
|
||||
pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||
|
||||
if( pxNewTCB->pxStack == NULL )
|
||||
{
|
||||
/* Could not allocate the stack. Delete the allocated TCB. */
|
||||
vPortFree( pxNewTCB );
|
||||
pxNewTCB = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* portSTACK_GROWTH */
|
||||
{
|
||||
StackType_t * pxStack;
|
||||
|
||||
/* Allocate space for the stack used by the task being created. */
|
||||
pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */
|
||||
|
||||
if( pxStack != NULL )
|
||||
{
|
||||
/* Allocate space for the TCB. */
|
||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
/* Store the stack location in the TCB. */
|
||||
pxNewTCB->pxStack = pxStack;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The stack cannot be used as the TCB was not created. Free
|
||||
* it again. */
|
||||
vPortFree( pxStack );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pxNewTCB = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* portSTACK_GROWTH */
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
* task was created dynamically in case it is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, xCoreID );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
uxCoreAffinityMask = ( 1 << xCoreID );
|
||||
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
|
||||
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;
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
#endif /* ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
|
@ -85,95 +304,202 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
|||
StaticTask_t * const pxTaskBuffer,
|
||||
const BaseType_t xCoreID )
|
||||
{
|
||||
TaskHandle_t ret;
|
||||
TaskHandle_t xReturn;
|
||||
|
||||
#if ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) )
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
{
|
||||
/* Convert xCoreID into an affinity mask */
|
||||
UBaseType_t uxCoreAffinityMask;
|
||||
|
||||
if( xCoreID == tskNO_AFFINITY )
|
||||
/* If using Amazon SMP FreeRTOS. This function is just a wrapper around
|
||||
* xTaskCreateStatic() or xTaskCreateStaticAffinitySet(). */
|
||||
#if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
{
|
||||
uxCoreAffinityMask = tskNO_AFFINITY;
|
||||
/* Convert xCoreID into an affinity mask */
|
||||
UBaseType_t uxCoreAffinityMask;
|
||||
|
||||
if( xCoreID == tskNO_AFFINITY )
|
||||
{
|
||||
uxCoreAffinityMask = tskNO_AFFINITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
uxCoreAffinityMask = ( 1 << xCoreID );
|
||||
}
|
||||
|
||||
xReturn = xTaskCreateStaticAffinitySet( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, uxCoreAffinityMask );
|
||||
}
|
||||
#else /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */
|
||||
{
|
||||
xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer );
|
||||
}
|
||||
#endif /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
{
|
||||
TCB_t * pxNewTCB;
|
||||
|
||||
configASSERT( portVALID_STACK_MEM( puxStackBuffer ) );
|
||||
configASSERT( portVALID_TCB_MEM( pxTaskBuffer ) );
|
||||
configASSERT( ( ( xCoreID >= 0 ) && ( xCoreID < configNUM_CORES ) ) || ( xCoreID == tskNO_AFFINITY ) );
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
/* Sanity check that the size of the structure used to declare a
|
||||
* variable of type StaticTask_t equals the size of the real task
|
||||
* structure. */
|
||||
volatile size_t xSize = sizeof( StaticTask_t );
|
||||
configASSERT( xSize == sizeof( TCB_t ) );
|
||||
( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )
|
||||
{
|
||||
/* The memory used for the task's TCB and stack are passed into this
|
||||
* function - use them. */
|
||||
pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
|
||||
pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer;
|
||||
|
||||
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
* task was created statically in case the task is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL, xCoreID );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
uxCoreAffinityMask = ( 1 << xCoreID );
|
||||
xReturn = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
|
||||
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;
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
|
||||
/*
|
||||
* In ESP-IDF, configUSE_TIMERS is always defined as 1 (i.e., not user configurable).
|
||||
* However, tasks.c: vTaskStartScheduler() will always call xTimerCreateTimerTask()
|
||||
* if ( configUSE_TIMERS == 1 ), thus causing the linker to link timers.c and
|
||||
* wasting some memory (due to the timer task being created)/
|
||||
*
|
||||
* If we provide a weak version of xTimerCreateTimerTask(), this version will be
|
||||
* compiled if the application does not call any other FreeRTOS timer functions.
|
||||
* Thus we can save some text/RAM as timers.c will not be linked and the timer
|
||||
* task never created.
|
||||
*/
|
||||
BaseType_t __attribute__( ( weak ) ) xTimerCreateTimerTask( void )
|
||||
{
|
||||
return pdPASS;
|
||||
}
|
||||
|
||||
#endif /* configUSE_TIMERS */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------- 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
|
||||
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID )
|
||||
{
|
||||
assert( xCoreID >= 0 && xCoreID < configNUM_CORES );
|
||||
configASSERT( xCoreID >= 0 && xCoreID < configNUM_CORES );
|
||||
configASSERT( ( xIdleTaskHandle[ xCoreID ] != NULL ) );
|
||||
return ( TaskHandle_t ) xIdleTaskHandle[ xCoreID ];
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
#endif /* INCLUDE_xTaskGetIdleTaskHandle */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
|
||||
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID )
|
||||
{
|
||||
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;
|
||||
TaskHandle_t xReturn;
|
||||
|
||||
/* 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 */
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
{
|
||||
ret = tskNO_AFFINITY;
|
||||
xReturn = xTaskGetCurrentTaskHandleCPU( xCoreID );
|
||||
}
|
||||
else
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
{
|
||||
int index_plus_one = __builtin_ffs( uxCoreAffinityMask );
|
||||
assert( index_plus_one >= 1 );
|
||||
ret = index_plus_one - 1;
|
||||
if( xCoreID < configNUM_CORES )
|
||||
{
|
||||
xReturn = pxCurrentTCB[ xCoreID ];
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
|
||||
return ret;
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
{
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
UBaseType_t uxCoreAffinityMask;
|
||||
|
||||
/* Get the core affinity mask and covert it to an ID */
|
||||
uxCoreAffinityMask = vTaskCoreAffinityGet( xTask );
|
||||
|
||||
/* 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 */
|
||||
{
|
||||
xReturn = tskNO_AFFINITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
int iIndexPlusOne = __builtin_ffs( uxCoreAffinityMask );
|
||||
assert( iIndexPlusOne >= 1 );
|
||||
xReturn = iIndexPlusOne - 1;
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
TCB_t * pxTCB;
|
||||
|
||||
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 */
|
||||
{
|
||||
/* Single-core. Just return a core ID of 0 */
|
||||
xReturn = 0;
|
||||
}
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
uint8_t * pxTaskGetStackStart( TaskHandle_t xTask )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
uint8_t * uxReturn;
|
||||
|
||||
pxTCB = prvGetTCBFromHandle( xTask );
|
||||
uxReturn = ( uint8_t * ) pxTCB->pxStack;
|
||||
|
||||
return uxReturn;
|
||||
}
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_vTaskPrioritySet == 1 )
|
||||
|
@ -390,26 +716,61 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
|||
|
||||
/* --------------------------------------------- TLSP Deletion Callbacks -------------------------------------------- */
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
#if 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" );
|
||||
/* If TLSP deletion callbacks are enabled, then configNUM_THREAD_LOCAL_STORAGE_POINTERS
|
||||
* is doubled in size so that the latter half of the pvThreadLocalStoragePointers
|
||||
* stores the deletion callbacks. */
|
||||
if( xIndex < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) )
|
||||
{
|
||||
TCB_t * pxTCB;
|
||||
|
||||
/*Set the local storage pointer first */
|
||||
vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue );
|
||||
#if ( configNUM_CORES > 1 )
|
||||
{
|
||||
/* For SMP, we need a critical section as another core could also
|
||||
* update this task's TLSP at the same time. */
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
{
|
||||
taskENTER_CRITICAL( &xKernelLock );
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
}
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
|
||||
/*Set the deletion callback at an offset of configNUM_THREAD_LOCAL_STORAGE_POINTERS/2 */
|
||||
vTaskSetThreadLocalStoragePointer( xTaskToSet, ( xIndex + ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ), pvDelCallback );
|
||||
pxTCB = prvGetTCBFromHandle( xTaskToSet );
|
||||
/* Store the TLSP by indexing the first half of the array */
|
||||
pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue;
|
||||
|
||||
/* Store the TLSP deletion callback by indexing the second half
|
||||
* of the array. */
|
||||
pxTCB->pvThreadLocalStoragePointers[ ( xIndex + ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ) ] = ( void * ) pvDelCallback;
|
||||
|
||||
#if ( configNUM_CORES > 1 )
|
||||
{
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
{
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
{
|
||||
taskEXIT_CRITICAL( &xKernelLock );
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
}
|
||||
#endif /* configNUM_CORES > 1 */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
/* ----------------------------------------------------- Newlib ----------------------------------------------------- */
|
||||
|
|
|
@ -20,6 +20,111 @@
|
|||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* KERNEL CONTROL (PRIVATE)
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The following macros are convenience macros used to account for different
|
||||
* thread safety behavior between Vanilla FreeRTOS (i.e., single-core) and ESP-IDF
|
||||
* FreeRTOS (i.e., multi-core SMP).
|
||||
*
|
||||
* For thread saftey...
|
||||
*
|
||||
* - Vanilla FreeRTOS will use the following for thread safety (depending on situation)
|
||||
* - `vTaskSuspendAll()`/`xTaskResumeAll()` for non-deterministic operations
|
||||
* - Critical sections or disabling interrupts for deterministic operations
|
||||
* - ESP-IDF FreeRTOS will always use critical sections (determinism is not supported)
|
||||
*
|
||||
* [refactor-todo]: Define these locally in each kernel source file (IDF-8161)
|
||||
*/
|
||||
#if ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) )
|
||||
|
||||
#define prvENTER_CRITICAL_OR_SUSPEND_ALL( x ) taskENTER_CRITICAL( ( x ) )
|
||||
#define prvEXIT_CRITICAL_OR_RESUME_ALL( x ) ( { taskEXIT_CRITICAL( ( x ) ); pdFALSE; } )
|
||||
#define prvENTER_CRITICAL_OR_MASK_ISR( pxLock, uxInterruptStatus ) \
|
||||
{ \
|
||||
taskENTER_CRITICAL_ISR( ( pxLock ) ); \
|
||||
( void ) ( uxInterruptStatus ); \
|
||||
}
|
||||
#define prvEXIT_CRITICAL_OR_UNMASK_ISR( pxLock, uxInterruptStatus ) \
|
||||
{ \
|
||||
taskEXIT_CRITICAL_ISR( ( pxLock ) ); \
|
||||
( void ) ( uxInterruptStatus ); \
|
||||
}
|
||||
|
||||
#elif ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES == 1 ) )
|
||||
|
||||
#define prvENTER_CRITICAL_OR_SUSPEND_ALL( x ) ( { vTaskSuspendAll(); ( void ) ( x ); } )
|
||||
#define prvEXIT_CRITICAL_OR_RESUME_ALL( x ) xTaskResumeAll()
|
||||
#define prvENTER_CRITICAL_OR_MASK_ISR( pxLock, uxInterruptStatus ) \
|
||||
{ \
|
||||
( uxInterruptStatus ) = portSET_INTERRUPT_MASK_FROM_ISR(); \
|
||||
( void ) ( pxLock ); \
|
||||
}
|
||||
#define prvEXIT_CRITICAL_OR_UNMASK_ISR( pxLock, uxInterruptStatus ) \
|
||||
{ \
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ( uxInterruptStatus ) ); \
|
||||
( void ) ( pxLock ); \
|
||||
}
|
||||
|
||||
#endif /* ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES == 1 ) ) */
|
||||
|
||||
/*
|
||||
* In ESP-IDF FreeRTOS (i.e., multi-core SMP) uses spinlocks to protect different
|
||||
* groups of data. This function is a wrapper to take the "xKernelLock" spinlock
|
||||
* of tasks.c.
|
||||
*
|
||||
* This lock is taken whenever any of the kernel's data structures are
|
||||
* accessed/modified, such as when adding/removing tasks to/from the delayed
|
||||
* task list or various event lists.
|
||||
*
|
||||
* In more cases, kernel data structures are not accessed by functions outside
|
||||
* tasks.c. Thus, all accesses of the kernel data structures inside tasks.c will
|
||||
* handle the taking/releasing of the "xKerneLock".
|
||||
*
|
||||
* This functions is meant to be called by xEventGroupSetBits() and
|
||||
* vEventGroupDelete() as both those functions will directly access event lists
|
||||
* (which are kernel data structures). Thus, a wrapper function must be provided
|
||||
* to take/release the "xKernelLock" from outside tasks.c.
|
||||
*
|
||||
* [refactor-todo]: Extern this locally in event groups (IDF-8161)
|
||||
*/
|
||||
#if ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) )
|
||||
|
||||
void prvTakeKernelLock( void );
|
||||
void prvReleaseKernelLock( void );
|
||||
|
||||
#endif /* ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) ) */
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) )
|
||||
|
||||
/**
|
||||
* @brief Workaround for non-thread safe multi-core OS startup (see IDF-4524)
|
||||
*
|
||||
* This function must be called with interrupts disabled on all cores other than
|
||||
* core 0 during startup.
|
||||
*/
|
||||
void prvStartSchedulerOtherCores( void );
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) ) */
|
||||
|
||||
/*
|
||||
* In ESP-IDF FreeRTOS (i.e., multi-core SMP), core 0 manages the the FreeRTOS
|
||||
* tick count. Thus only core 0 calls xTaskIncrementTick().
|
||||
*
|
||||
* However, all other cores also receive a periodic tick interrupt. Thus all
|
||||
* other cores should call this function instead.
|
||||
*
|
||||
* This function will check if the current core requires time slicing, and also
|
||||
* call the application tick hook. However, the tick count will remain unchanged.
|
||||
*/
|
||||
#if ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) )
|
||||
|
||||
BaseType_t xTaskIncrementTickOtherCores( void );
|
||||
|
||||
#endif /* ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) ) */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* TASK UTILITIES (PRIVATE)
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -31,26 +31,23 @@
|
|||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* -------------------------------------------------- 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.
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* -------------------------------------------------- Task Creation ------------------------------------------------- */
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Create a new task that is pinned to a particular core
|
||||
*
|
||||
* Helper function to create a task that is pinned to a particular core, or has
|
||||
* no affinity. In other words, the created task will have an affinity mask of:
|
||||
* - (1 << xCoreID) if it is pinned to a particular core
|
||||
* - Set to tskNO_AFFINITY if it has no affinity
|
||||
* This function is similar to xTaskCreate(), but allows the creation of a pinned
|
||||
* task. The task's pinned core is specified by the xCoreID argument. If xCoreID
|
||||
* is set to tskNO_AFFINITY, then the task is unpinned and can run on any core.
|
||||
*
|
||||
* @note If ( configNUM_CORES == 1 ), xCoreID is ignored.
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function.
|
||||
* @param pcName A descriptive name for the task.
|
||||
* @param usStackDepth The size of the task stack.
|
||||
* @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.
|
||||
* @param uxPriority The priority at which the task should run.
|
||||
|
@ -63,24 +60,30 @@
|
|||
*/
|
||||
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
const BaseType_t xCoreID );
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_SMP && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Create a new static task that is pinned to a particular core
|
||||
*
|
||||
* This funciton is the static equivalent of xTaskCreatePinnedToCore().
|
||||
* This function is similar to xTaskCreateStatic(), but allows the creation of a
|
||||
* pinned task. The task's pinned core is specified by the xCoreID argument. If
|
||||
* xCoreID is set to tskNO_AFFINITY, then the task is unpinned and can run on any
|
||||
* core.
|
||||
*
|
||||
* @note If ( configNUM_CORES == 1 ), xCoreID is ignored.
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function.
|
||||
* @param pcName A descriptive name for the task.
|
||||
* @param ulStackDepth The size of the task stack.
|
||||
* @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.
|
||||
* @param uxPriority The priority at which the task should run.
|
||||
|
@ -101,47 +104,37 @@
|
|||
StaticTask_t * const pxTaskBuffer,
|
||||
const BaseType_t xCoreID );
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/* ------------------------------------------------- Task Utilities ----------------------------------------------------
|
||||
* Todo: Move IDF FreeRTOS SMP related additions to this header as well (see IDF-7201)
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
/* ------------------------------------------------- Task Utilities ------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Get the handle of the task running on a certain core
|
||||
* @brief Get the handle of idle task for the given core.
|
||||
*
|
||||
* [refactor-todo] See if this needs to be deprecated (IDF-8145)
|
||||
*
|
||||
* @note If CONFIG_FREERTOS_SMP is enabled, please call xTaskGetIdleTaskHandle()
|
||||
* instead.
|
||||
* @param xCoreID The core to query
|
||||
* @return Handle of the idle task for the queried core
|
||||
*/
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID );
|
||||
|
||||
/**
|
||||
* @brief Get the handle of the task currently running on a certain core
|
||||
*
|
||||
* Because of the nature of SMP processing, there is no guarantee that this
|
||||
* value will still be valid on return and should only be used for debugging
|
||||
* purposes.
|
||||
*
|
||||
* [refactor-todo] Mark this function as deprecated, call
|
||||
* xTaskGetCurrentTaskHandleCPU() instead
|
||||
* [refactor-todo] See if this needs to be deprecated (IDF-8145)
|
||||
*
|
||||
* @note If CONFIG_FREERTOS_SMP is enabled, please call xTaskGetCurrentTaskHandleCPU()
|
||||
* instead.
|
||||
* @param xCoreID The core to query
|
||||
* @return Handle of the current task running on the queried core
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* [refactor-todo] Mark this function as deprecated, call
|
||||
* xTaskGetIdleTaskHandle() instead
|
||||
*
|
||||
* @param xCoreID The core to query
|
||||
* @return Handle of the idle task for the queried core
|
||||
*/
|
||||
TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID );
|
||||
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID );
|
||||
|
||||
/**
|
||||
* @brief Get the current core affinity of a particular task
|
||||
|
@ -150,35 +143,44 @@
|
|||
* pinned to a particular core, the core ID is returned. If the task is not
|
||||
* pinned to a particular core, tskNO_AFFINITY is returned.
|
||||
*
|
||||
* [refactor-todo] Mark this function as deprecated, call vTaskCoreAffinityGet()
|
||||
* instead
|
||||
* 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
|
||||
*/
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask );
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask );
|
||||
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
|
||||
/* --------------------------------------------- TLSP Deletion Callbacks -----------------------------------------------
|
||||
* TLSP Deletion Callback API Additions
|
||||
/**
|
||||
* Returns the start of the stack associated with xTask.
|
||||
*
|
||||
* 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.
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
* Returns the lowest stack memory address, regardless of whether the stack
|
||||
* grows up or down.
|
||||
*
|
||||
* [refactor-todo] Change return type to StackType_t (IDF-8158)
|
||||
*
|
||||
* @param xTask Handle of the task associated with the stack returned.
|
||||
* Set xTask to NULL to return the stack of the calling task.
|
||||
*
|
||||
* @return A pointer to the start of the stack.
|
||||
*/
|
||||
uint8_t * pxTaskGetStackStart( TaskHandle_t xTask );
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
/* --------------------------------------------- TLSP Deletion Callbacks -------------------------------------------- */
|
||||
|
||||
#if CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
|
||||
|
||||
/**
|
||||
* Prototype of local storage pointer deletion callback.
|
||||
*/
|
||||
typedef void (* TlsDeleteCallbackFunction_t)( int,
|
||||
void * );
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) */
|
||||
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
#if CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
|
||||
|
||||
/**
|
||||
* Set local storage pointer and deletion callback.
|
||||
|
@ -207,7 +209,7 @@
|
|||
void * pvValue,
|
||||
TlsDeleteCallbackFunction_t pvDelCallback );
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_SMP && CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS ) */
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
|
||||
/* -------------------------------------------- Creation With Memory Caps ----------------------------------------------
|
||||
* Helper functions to create various FreeRTOS objects (e.g., queues, semaphores) with specific memory capabilities
|
||||
|
|
|
@ -109,12 +109,9 @@ entries:
|
|||
# - "xTaskGetSchedulerState"
|
||||
# - "xTaskGetTickCount"
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
tasks:xTaskCreateStaticPinnedToCore (default)
|
||||
tasks:xTaskCreatePinnedToCore (default)
|
||||
tasks:prvInitialiseNewTask (default)
|
||||
tasks:prvAddNewTaskToReadyList (default)
|
||||
tasks:vTaskDelete (default)
|
||||
tasks:vTaskDelayUntil (default)
|
||||
tasks:xTaskDelayUntil (default)
|
||||
tasks:vTaskDelay (default)
|
||||
tasks:eTaskGetState (default)
|
||||
|
@ -133,7 +130,6 @@ entries:
|
|||
tasks:prvSearchForNameWithinSingleList (default)
|
||||
tasks:xTaskGetHandle (default)
|
||||
tasks:xTaskGetIdleTaskHandle (default)
|
||||
tasks:xTaskGetIdleTaskHandleForCPU (default)
|
||||
tasks:xTaskAbortDelay (default)
|
||||
# IDF-6410 Application tags not supported yet
|
||||
#tasks:vTaskSetApplicationTaskTag (default)
|
||||
|
@ -142,30 +138,22 @@ entries:
|
|||
tasks:vTaskPlaceOnEventList (default)
|
||||
tasks:vTaskPlaceOnUnorderedEventList (default)
|
||||
tasks:vTaskPlaceOnEventListRestricted (default)
|
||||
if FREERTOS_UNICORE = n:
|
||||
tasks:vTaskTakeKernelLock (default)
|
||||
tasks:vTaskReleaseKernelLock (default)
|
||||
tasks:vTaskRemoveFromUnorderedEventList (default)
|
||||
tasks:vTaskSetTimeOutState (default)
|
||||
tasks:vTaskInternalSetTimeOutState (default)
|
||||
tasks:xTaskCheckForTimeOut (default)
|
||||
tasks:vTaskMissedYield (default)
|
||||
tasks:prvIdleTask (default)
|
||||
if FREERTOS_TLSP_DELETION_CALLBACKS = y:
|
||||
tasks:vTaskSetThreadLocalStoragePointerAndDelCallback (default)
|
||||
if FREERTOS_THREAD_LOCAL_STORAGE_POINTERS != 0:
|
||||
tasks:vTaskSetThreadLocalStoragePointer (default)
|
||||
tasks:pvTaskGetThreadLocalStoragePointer (default)
|
||||
tasks:prvInitialiseTaskLists (default)
|
||||
tasks:prvCheckTasksWaitingTermination (default)
|
||||
tasks:xTaskGetAffinity (default)
|
||||
tasks:prvTaskCheckFreeStackSpace (default)
|
||||
tasks:uxTaskGetStackHighWaterMark2 (default)
|
||||
tasks:uxTaskGetStackHighWaterMark (default)
|
||||
tasks:pxTaskGetStackStart (default)
|
||||
tasks:prvDeleteTCB (default)
|
||||
tasks:xTaskGetCurrentTaskHandle (default)
|
||||
tasks:xTaskGetCurrentTaskHandleForCPU (default)
|
||||
tasks:xTaskPriorityInherit (default)
|
||||
tasks:xTaskPriorityDisinherit (default)
|
||||
tasks:vTaskPriorityDisinheritAfterTimeout (default)
|
||||
|
@ -176,9 +164,7 @@ entries:
|
|||
tasks:vTaskGetRunTimeStats (default)
|
||||
tasks:uxTaskResetEventItemValue (default)
|
||||
tasks:pvTaskIncrementMutexHeldCount (default)
|
||||
tasks:ulTaskNotifyTake (default)
|
||||
tasks:ulTaskGenericNotifyTake (default)
|
||||
tasks:xTaskNotifyWait (default)
|
||||
tasks:xTaskGenericNotifyWait (default)
|
||||
tasks:xTaskGenericNotify (default)
|
||||
tasks:xTaskGenericNotifyStateClear (default)
|
||||
|
|
|
@ -17,14 +17,19 @@ entries:
|
|||
# to always keep it in IRAM
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y:
|
||||
# Kernel Control
|
||||
if FREERTOS_SMP = n && FREERTOS_UNICORE = n:
|
||||
tasks:prvTakeKernelLock (default)
|
||||
tasks:prvReleaseKernelLock (default)
|
||||
# Task Creation
|
||||
if FREERTOS_SMP = y:
|
||||
tasks:xTaskCreatePinnedToCore (default)
|
||||
tasks:xTaskCreateStaticPinnedToCore (default)
|
||||
tasks:xTaskCreatePinnedToCore (default)
|
||||
tasks:xTaskCreateStaticPinnedToCore (default)
|
||||
# Task Utilities
|
||||
tasks:xTaskGetCurrentTaskHandleForCPU (default)
|
||||
tasks:xTaskGetIdleTaskHandleForCPU (default)
|
||||
tasks:xTaskGetCurrentTaskHandleForCPU (default)
|
||||
tasks:xTaskGetAffinity (default)
|
||||
tasks:pxTaskGetStackStart (default)
|
||||
tasks:prvTaskPriorityRaise (default)
|
||||
tasks:prvTaskPriorityRestore (default)
|
||||
# TLSP Deletion Callbacks
|
||||
|
@ -36,6 +41,12 @@ entries:
|
|||
tasks:pxTaskGetNext (default)
|
||||
tasks:uxTaskGetSnapshotAll (default)
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
# freertos_compatibility.c
|
||||
# Placement Rules: Functions always in flash as they are never called from an ISR
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
freertos_compatibility (default)
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
# idf_additions.c
|
||||
# Placement Rules: Functions always in flash as they are never called from an ISR
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
#include <stdlib.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#if ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) )
|
||||
/* Required for xTaskIncrementTickOtherCores() */
|
||||
#include "esp_private/freertos_idf_additions_priv.h"
|
||||
#endif /* ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES > 1 ) ) */
|
||||
|
||||
#if CONFIG_FREERTOS_SYSTICK_USES_CCOUNT
|
||||
#if CONFIG_FREERTOS_CORETIMER_0
|
||||
|
|
|
@ -115,11 +115,13 @@ static void unpinned_task(void *arg)
|
|||
vTaskSuspendAll();
|
||||
#endif
|
||||
// Check that the task is unpinned
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
TEST_ASSERT_EQUAL(tskNO_AFFINITY, vTaskCoreAffinityGet(NULL));
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(tskNO_AFFINITY, xTaskGetAffinity(NULL));
|
||||
#endif
|
||||
#endif // !CONFIG_FREERTOS_UNICORE
|
||||
|
||||
// Allocate an ISR to use the FPU
|
||||
intr_handle_t isr_handle;
|
||||
|
@ -130,11 +132,13 @@ static void unpinned_task(void *arg)
|
|||
esp_intr_free(isr_handle);
|
||||
|
||||
// Task should remain unpinned after the ISR uses the FPU
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
TEST_ASSERT_EQUAL(tskNO_AFFINITY, vTaskCoreAffinityGet(NULL));
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(tskNO_AFFINITY, xTaskGetAffinity(NULL));
|
||||
#endif
|
||||
#endif // !CONFIG_FREERTOS_UNICORE
|
||||
// Reenable scheduling/preemption
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
vTaskPreemptionEnable(NULL);
|
||||
|
|
|
@ -137,11 +137,13 @@ static void unpinned_task(void *arg)
|
|||
#endif
|
||||
BaseType_t cur_core_num = xPortGetCoreID();
|
||||
// Check that the task is unpinned
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
TEST_ASSERT_EQUAL(tskNO_AFFINITY, vTaskCoreAffinityGet(NULL));
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(tskNO_AFFINITY, xTaskGetAffinity(NULL));
|
||||
#endif
|
||||
#endif // !CONFIG_FREERTOS_UNICORE
|
||||
|
||||
/*
|
||||
Use the FPU
|
||||
|
@ -156,11 +158,13 @@ static void unpinned_task(void *arg)
|
|||
// We allow a 0.1% delta on the final result in case of any loss of precision from floating point calculations
|
||||
TEST_ASSERT_FLOAT_WITHIN(0.00256f, 2.56f, test_float);
|
||||
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
TEST_ASSERT_EQUAL(1 << cur_core_num, vTaskCoreAffinityGet(NULL));
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(cur_core_num, xTaskGetAffinity(NULL));
|
||||
#endif
|
||||
#endif // !CONFIG_FREERTOS_UNICORE
|
||||
// Reenable scheduling/preemption
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
vTaskPreemptionEnable(NULL);
|
||||
|
|
|
@ -12,6 +12,8 @@ set(include_dirs
|
|||
"${original_freertos_dir}/config/include/freertos" # For "FreeRTOSConfig.h"
|
||||
"${original_freertos_dir}/config/linux/include" # For "freertos/FreeRTOSConfig_arch.h"
|
||||
"${original_freertos_dir}/esp_additions/include"
|
||||
# Required because CMock tries to include "idf_additions.h" instead of "freertos/idf_additions.h"
|
||||
"${original_freertos_dir}/esp_additions/include/freertos"
|
||||
"${kernel_dir}/portable/linux/include" # For "freertos/portmacro.h"
|
||||
"${kernel_dir}/include/freertos" # this is due to the way includes are generated in CMock (without freertos prefix)
|
||||
)
|
||||
|
@ -19,6 +21,7 @@ set(include_dirs
|
|||
idf_component_mock(INCLUDE_DIRS ${include_dirs}
|
||||
REQUIRES esp_common
|
||||
MOCK_HEADER_FILES
|
||||
${original_freertos_dir}/esp_additions/include/freertos/idf_additions.h
|
||||
${original_freertos_dir}/FreeRTOS-Kernel/include/freertos/task.h
|
||||
${original_freertos_dir}/FreeRTOS-Kernel/include/freertos/event_groups.h
|
||||
${original_freertos_dir}/FreeRTOS-Kernel/include/freertos/queue.h)
|
||||
|
|
Ładowanie…
Reference in New Issue