提示:好记性不如烂笔头。本博客作为学习笔记,有错误的地方希望指正
文章目录
- 前言:
- 一、任务的创建
- 1.1、使用FreeRTOS标准的创建任务API
- 1.1.1、TaskHandle_t 任务句柄
- 1.1.2、xTaskCreate创建任务
- 1.1.3、xTaskCreateStatic 创建任务
- 1.1.4、xTaskCreateRestrictedStatic创建任务
- 1.2、使用ESP32的 xTaskCreatePinnedToCore API创建任务
- 二、任务的删除
- 三、实验源码
前言:
参考资料:FreeRTOS API参考 现在开始对FreeRTOS全面的学习,之前也看过许多的文档,使用的正点的文档学习的,但是都是没有记录的学习,不会就去找文档查看资料,但是没有系统体系的对FreeRTOS全面的学习。
第一篇我们先开始从创建任务开始,对于ESP32而言,本身Demo就已经只带了FreeRTOS操作系统,省去繁琐复杂的移植,FreeRTOS是一个开源的操作系统,可以方便我们移植到许多的单片机上,之前学习stm32的时候,哪个时候st还没有出cubemax,需要手动去移植FreeRTOS,哪个对刚开始学习操作系统确实比较头大,还有许多汇编的知识,对刚开始学习不太友好,所以想要学习操作系统的话,最起码是先能跑起来先玩起来,至于最后深层的移植工作也是看需求和个人爱好是否继续深入研究。
首先我们先从创建任务开始学习,ESP32的话创建任务有两套方法,一个是使用FreeRTOS默认是那套API来创建任务,另外可以使用ESP32它本身的API来创建,使用ESP32自己的API来创建任务的话可以指定在哪个核中创建任务,其中ESP32的双核使用的是SMP构架,SMP构架的系统中所有CPU共享系统内存和外设资源,由操作系统负责处理器间协作,并保持数据结构的一致性.两个核使用互斥信号量的保护,使得任务运行一些外设例如串口之类的不会发生冲突。
在原码中我找到xTaskCreate的函数定义,可以看出xTaskCreate创建的时候是调用xTaskCreatePinnedToCoreAPI来实现的。
static inline IRAM_ATTR BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode,
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint32_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask) PRIVILEGED_FUNCTION
{
return xTaskCreatePinnedToCore( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, tskNO_AFFINITY );
}
一、任务的创建
创建任务这里分为使用FreeRTOS中的API来创建和使用ESP32带指定核API来创建。
1.1、使用FreeRTOS标准的创建任务API
1.1.1、TaskHandle_t 任务句柄
引用任务的类型。例如,对xTaskCreate的调用(通过指针参数)返回一个TaskHandle_t变量,然后可以将它用作vTaskDelete的参数来删除任务。其中TaskHandle_t 是一个 void* 类型的数据,使用TaskHandle_t定义的变量是空指针类型。
TaskHandle_t的定义:
#ifdef ESP_PLATFORM // IDF-3769
typedef void* TaskHandle_t;
#else
typedef struct tskTaskControlBlock* TaskHandle_t;
#endif // ESP_PLATFORM
1.1.2、xTaskCreate创建任务
xTaskCreate API原型:
BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
const char * const pcName,
configSTACK_DEPTH_TYPE usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pxCreatedTask
);
创建一个新任务,并将其添加到准备运行的任务列表中。configSUPPORT_DYNAMIC_ALLOCATION必须在FreeRTOSConfig.h中设置为1,或者不设置为undefined(在这种情况下,它将默认为1),以便这个RTOS API函数可用。
每个任务都需要用于保存任务状态的RAM,并被任务用作其堆栈。如果使用xTaskCreate()创建任务,则从FreeRTOS堆自动分配所需的RAM。如果使用xTaskCreateStatic()创建任务,那么RAM是由应用程序编写器提供的,因此可以在编译时静态分配它。有关更多信息,请参阅静态与动态分配页面。
如果你正在使用FreeRTOS-MPU,那么我们建议你使用xTaskCreateRestricted()而不是xTaskCreate()。
xTaskCreate 函数参数:
- pvTaskCode:指向任务入口函数的指针(只是实现任务的函数的名称,参见下面的示例)。任务通常以无限循环的形式实现;实现任务的函数决不能尝试返回或退出。但是,任务可以删除自己。
- pcName:任务的描述性名称。这主要用于方便调试,但也可用于获取任务句柄。任务名称的最大长度由FreeRTOSConfig.h中的configMAX_TASK_NAME_LEN定义。
- usStackDepth:分配的用作任务堆栈的字数(不是字节!)例如,如果堆栈是16位宽的,usStackDepth是100,那么将分配200字节作为任务的堆栈。另一个例子是,如果堆栈是32位宽的,usStackDepth是400,那么将分配1600字节作为任务的堆栈。堆栈深度乘以堆栈宽度不能超过size_t类型变量所能包含的最大值。参见常见问题解答堆栈应该有多大?
- pvParameters:作为参数传递给创建的任务的值。如果pvParameters被设置为一个变量的地址,那么当创建的任务执行时,该变量必须仍然存在,所以传递堆栈变量的地址是无效的。
- uxPriority:创建的任务执行的优先级。包含MPU支持的系统可以通过在uxPriority中设置位portPRIVILEGE_BIT来选择以特权(系统)模式创建任务。例如,要创建优先级为2的特权任务,将uxPriority设置为(2 | portPRIVILEGE_BIT)。优先级被断言小于configMAX_PRIORITIES。如果configASSERT未定义,优先级将静默地封顶为(configMAX_PRIORITIES - 1)。
-pxCreatedTask:用于从xTaskCreate()函数向创建的任务传递句柄。pxCreatedTask是可选的,可以设置为NULL。
返回:
如果任务被成功创建,则返回pdPASS。否则返回errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY。
示例code:
/* Task to be 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 xTaskCreate() below.
configASSERT( ( ( uint32_t ) pvParameters ) == 1 );*/
for( ;; )
{
/* Task code goes here. */
}
}
/* Function that creates a task. */
void vOtherFunction( void )
{
BaseType_t xReturned;
TaskHandle_t xHandle = NULL;
/* Create the task, storing the handle. */
xReturned = xTaskCreate(
vTaskCode, /* Function that implements the task. */
"NAME", /* Text name for the task. */
STACK_SIZE, /* Stack size in words, not bytes. */
( void * ) 1, /* Parameter passed into the task. */
tskIDLE_PRIORITY,/* Priority at which the task is created. */
&xHandle ); /* Used to pass out the created task's handle. */
if( xReturned == pdPASS )
{
/* The task was created. Use the task's handle to delete the task. */
vTaskDelete( xHandle );
}
}
1.1.3、xTaskCreateStatic 创建任务
xTaskCreateStatic API原型:
TaskHandle_t xTaskCreateStatic( 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 );
创建一个新的任务,并将其添加到准备运行的任务列表中。 configSUPPORT_STATIC_ALLOCATION必须在FreeRTOSConfig.h中被设置为1,这个RTOS API函数才可用。
每个任务都需要RAM,用来保存任务状态,并由任务作为其堆栈使用。如果一个任务是用xTaskCreate()创建的,那么所需的RAM会自动从FreeRTOS的堆中分配。如果一个任务是用xTaskCreateStatic()创建的,那么RAM是由应用程序编写者提供的,这将导致更多的参数,但允许RAM在编译时被静态分配。更多信息请参见静态与动态分配页面。
如果你使用FreeRTOS-MPU,那么我们建议你使用xTaskCreateRestricted()而不是xTaskCreateStatic()。
xTaskCreateStatic 函数参数:
- pxTaskCode :指向任务入口函数的指针(只是实现任务的函数名称,见下面的例子)。任务通常被实现为一个无限循环;实现任务的函数决不能试图返回或退出。然而,任务可以自我删除。
- pcName :任务的描述性名称。这主要是为了方便调试,但也可以用来获得一个任务句柄。一个任务名称的最大长度由FreeRTOSConfig.h中的configMAX_TASK_NAME_LEN定义。
- ulStackDepth: puxStackBuffer参数用于向xTaskCreateStatic()传递一个StackType_t变量的数组,ulStackDepth必须被设置为数组中的索引数。参见FAQ 堆栈应该有多大?
- pvParameters: 作为参数传递给创建的任务的值。如果pvParameters被设置为一个变量的地址,那么当创建的任务执行时,该变量必须仍然存在,所以传递堆栈变量的地址是无效的。
- uxPriority: 创建的任务将以何种优先级执行。包含MPU支持的系统可以通过设置uxPriority中的portPRIVILEGE_BIT位,选择性地在特权(系统)模式下创建任务。例如,为了创建一个优先级为2的特权任务,将uxPriority设置为( 2 |portPRIVILEGE_BIT )。优先级被断言为小于 configMAX_PRIORITIES。如果configASSERT是未定义的,优先级就会默默地以(configMAX_PRIORITIES - 1)为上限。
- puxStackBuffer: 必须指向一个StackType_t数组,该数组至少有ulStackDepth索引(见上面的ulStackDepth参数)–该数组将被用作任务的堆栈,所以它必须是持久的(不是在一个函数的堆栈中声明)。
- pxTaskBuffer: 必须指向一个StaticTask_t类型的变量。这个变量将被用来保存新任务的数据结构(TCB),所以它必须是持久的(不是在函数的堆栈中声明)。
返回:
如果puxStackBuffer和pxTaskBuffer都是NULL,那么任务将被创建,并返回任务的句柄。如果puxStackBuffer或pxTaskBuffer是NULL,那么任务将不会被创建,并返回NULL。
示例code:
/* Dimensions of 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 xTaskCreateStatic(). */
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 without using any dynamic memory allocation. */
xHandle = xTaskCreateStatic(
vTaskCode, /* Function that implements the task. */
"NAME", /* Text name for the task. */
STACK_SIZE, /* Number of indexes in the xStack array. */
( 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. */
/* 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 );
}
1.1.4、xTaskCreateRestrictedStatic创建任务
xTaskCreateRestrictedStatic API原型:
BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition,
TaskHandle_t *pxCreatedTask );
创建一个新的内存保护单元(MPU)限制的任务,并将其添加到准备运行的任务列表中。 configSUPPORT_STATIC_ALLOCATION必须在FreeRTOSConfig.h中被设置为1,这个RTOS API函数才可用。
在FreeRTOS的内部,每个任务需要两个内存块。第一个区块用来存放任务的数据结构。第二个区块被用作任务的堆栈。如果一个任务是用xTaskCreateRestricted()创建的,那么任务的堆栈的内存是由应用程序编写者提供的,而任务的数据结构的内存是自动从FreeRTOS堆中分配的。如果一个任务是用xTaskCreateRestrictedStatic()创建的,那么应用程序编写者也必须为任务的数据结构提供内存。因此,xTaskCreateRestrictedStatic()允许在不使用任何动态内存分配的情况下创建一个内存保护任务。
xTaskCreateRestrictedStatic()是为了与FreeRTOS-MPU一起使用,该演示程序包含了如何使用类似函数xTaskCreateRestricted()的全面和记录的例子。
xTaskCreateRestrictedStatic 函数参数:
- pxTaskDefinition: 指向定义任务的结构的指针。该结构在本页面有描述。
- pxCreatedTask: 用于传回一个句柄,通过它可以引用所创建的任务。
返回:
如果任务被成功创建并添加到准备好的列表中,则返回pdPASS,否则返回projdefs.h文件中定义的错误代码。
包含MPU支持的任务比不包含MPU的任务需要更多的参数来创建。将每个参数单独传递给xTaskCreateRestrictedStatic()会很不方便,因此使用了TaskParameters_t结构来允许在编译时静态配置参数。该结构在task.h中定义如下。
typedef struct xTASK_PARAMETERS
{
TaskFunction_t pvTaskCode;
const signed char * const pcName;
unsigned short usStackDepth;
void *pvParameters;
UBaseType_t uxPriority;
portSTACK_TYPE *puxStackBuffer;
MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
StaticTask_t * const pxTaskBuffer;
#endif
} TaskParameters_t;
// 其中MemoryRegion_t定义为:
typedef struct xMEMORY_REGION
{
void *pvBaseAddress;
unsigned long ulLengthInBytes;
unsigned long ulParameters;
} MemoryRegion_t;
以下是每个结构成员的描述:
- pvTaskCode 到 uxPriority:这些成员与发送给xTaskCreate()的同名参数完全相同。特别是uxPriority用于设置任务的优先级和任务的执行模式。例如,要创建一个优先级为2的用户模式任务,只需将uxPriority设置为2,要创建一个优先级为2的特权模式任务,则将uxPriority设置为( 2 | portPRIVILEGE_BIT )。
- puxStackBuffer:每次任务被切换进来时,MPU都会被动态地重新配置,以定义一个区域,为任务提供对其自身堆栈的读写权限。MPU区域必须满足一些约束条件–特别是,所有这些区域的大小和对齐方式必须等于2的同次方值。标准的FreeRTOS端口在每次创建任务时使用pvPortMalloc()来分配一个新的堆栈。提供一个pvPortMalloc()的实现来照顾MPU的数据对齐要求是可能的,但在RAM的使用上也会很复杂和低效。为了消除这种复杂性,FreeRTOS-MPU允许在编译时静态地声明堆栈。这允许使用编译器扩展来管理对齐,并由链接器来管理RAM的使用效率。例如,如果使用GCC,可以用下面的代码声明一个堆栈并正确对齐。 char cTaskStack[ 1024 ] attribute((aligned(1024))。puxStackBuffer通常会被设置为静态声明的堆栈的地址。作为一种选择,puxStackBuffer可以被设置为NULL–在这种情况下,pvPortMallocAligned()将被调用以分配任务栈,应用程序编写者有责任提供一个满足MPU对齐要求的pvPortMallocAligned()的实现。
- xRegions:xRegions是一个MemoryRegion_t结构的数组,每个结构都定义了一个用户可定义的内存区域,供正在创建的任务使用。ARM Cortex-M3 FreeRTOS-MPU端口定义了portNUM_CONFIGURABLE_REGIONS为3。pvBaseAddress和ulLengthInBytes成员分别是内存区域的起始点和内存区域的长度,这是不言自明的。 ulParameters定义了允许任务访问内存区域的方式,可以采用以下值的位数OR。
portMPU_REGION_READ_WRITE
portMPU_REGION_PRIVILEGED_READ_ONLY
portMPU_REGION_READ_ONLY
portMPU_REGION_PRIVILEGED_READ_WRITE
portMPU_REGION_CACHEABLE_BUFFERABLE
portMPU_REGION_EXECUTE_NEVER
- pxTaskBuffer:必须指向一个 StaticTask_t 类型的变量。这个变量将被用来保存新任务的数据结构,所以它必须是持久的(不是在函数的堆栈中声明)。
示例code
static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
static const TaskParameters_t xCheckTaskParameters =
{
vATask, /* pvTaskCode - the function that implements the task. */
"ATask", /* pcName - just a text name for the task to assist debugging. */
100, /* usStackDepth - the stack size DEFINED IN WORDS. */
NULL, /* pvParameters - passed into the task function as the function parameters. */
( 1UL | portPRIVILEGE_BIT ),/* uxPriority - task priority, set the portPRIVILEGE_BIT
if the task should run in a privileged state. */
cStackBuffer,/* puxStackBuffer - the buffer to be used as the task stack. */
/* xRegions - Allocate up to three separate memory regions for access by
* the task, with appropriate access permissions. Different processors have
* different memory alignment requirements - refer to the FreeRTOS documentation
* for full information. */
{
/* Base address Length Parameters */
{ cReadWriteArray, 32, portMPU_REGION_READ_WRITE },
{ cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },
{ cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }
}
&xTaskBuffer; /* Holds the task's data structure. */
};
int main( void )
{
TaskHandle_t xHandle;
/* Create a task from the const structure defined above. The task handle
* is requested (the second parameter is not NULL) but in this case just for
* demonstration purposes as its not actually used. */
xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
/* Start the scheduler. */
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
* and/or timer task. */
for( ;; );
}
1.2、使用ESP32的 xTaskCreatePinnedToCore API创建任务
xTaskCreatePinnedToCore API原型:
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode, //任务名 这里直接是函数名
const char * const pcName, //任务名字 字符串 最大长度在FreeRTOSConfig.h中有限制,ESP32中最大16个字符
const uint32_t usStackDepth, //任务堆栈大小,总体的大小是要乘以 4 单位 byte usStackDepth 单位是字word
void * const pvParameters, //给任务传入参数,这个参数可以是任意类型的
UBaseType_t uxPriority, //任务优先级别 空闲优先级是0 0最低,往上就越高 最大值在FreeRTOSConfig.h 中设置
TaskHandle_t * const pvCreatedTask, //任务句柄 方便对任务的一些操作,例如删除、挂起传入任务句柄作为参数的
const BaseType_t xCoreID); //任务创建在哪个核
创建一个具有指定亲和力的新任务。这个函数类似于xTaskCreate,但允许在SMP系统中设置任务亲和力。在SMP系统中。
xTaskCreatePinnedToCore 函数参数:
- pvTaskCode: 指向任务输入函数的指针。 任务必须实现永不返回(即连续循环),或者应该使用vTaskDelete函数终止。
- pcName 任务的描述性名称。 这主要是为了方便调试。 最大长度由configMAX_TASK_NAME_LEN定义 - 默认是16。
- usStackDepth: 任务栈的大小,以字节数表示。字节数。注意,这与vanilla FreeRTOS不同。
- pvParameters: 指针将被用作任务的参数。正在创建。
- uxPriority: 任务运行的优先级。 系统包括MPU支持的系统可以选择在特权(系统)下创建任务。通过设置优先级参数的位portPRIVILEGE_BIT来创建任务。 例如例如,要创建一个优先级为2的特权任务,uxPriority参数应该被设置为 ( 2 | portPRIVILEGE_BIT )。
- pvCreatedTask: 用于传回一个句柄,创建的任务可以通过它来引用。可以被引用。
- xCoreID: 如果该值为tskNO_AFFINITY,则创建的任务不被钉在任何CPU上。钉在任何CPU上,调度器可以在任何可用的核心上运行它。值为0或1时,表示该任务应该被钉在CPU上的索引号。被钉住。指定大于(portNUM_PROCESSORS - 1)的值将导致函数失败。导致该函数失败。
如果任务被成功创建并添加到准备好的列表中,返回pdPASS。列表中,否则会有一个错误代码,该代码在文件projdefs.h中定义。
二、任务的删除
vTaskDelete API原型:
void vTaskDelete( TaskHandle_t xTask );
INCLUDE_vTaskDelete必须被定义为1,这个函数才可用。更多信息请参见RTOS配置文档。
从RTOS内核管理中删除一个任务。被删除的任务将从所有就绪、阻塞、暂停和事件列表中删除。
注意:空闲任务负责释放RTOS内核分配给被删除的任务的内存。因此,如果你的应用程序对vTaskDelete()进行了任何调用,空闲任务不会被剥夺微控制器的处理时间,这一点很重要。任务代码分配的内存不会被自动释放,应该在任务被删除前释放。
请参阅演示程序文件death.c中利用vTaskDelete()的示例代码。
参数
xTask 要删除的任务的句柄。传递NULL将导致调用的任务被删除。
对于删除任务可以使用两种方法,一种是在任务外删除另一个任务,另外就是在本任务中删除自己。
示例code
void vOtherFunction( void )
{
TaskHandle_t xHandle = NULL;
// Create the task, storing the handle.
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
// Use the handle to delete the task.
if( xHandle != NULL )
{
vTaskDelete( xHandle );
}
}
三、实验源码
这里我主要测试使用xTaskCreate、xTaskCreateStatic、xTaskCreatePinnedToCore、vTaskDelete来作为实验测试,没有使用xTaskCreateRestrictedStatic来创建任务,xTaskCreateRestrictedStatic创建任务需要开启MPU,这里不做深入了解,需要了解的自行查阅相关资料。
/**
* @file 1_CreateTask.c
* @author WSP
* @brief 任务创建
* @version 0.1
* @date 2022-10-05
*
* @copyright Copyright (c) 2022
*
*/
#include "System_Include.h"
const static char * TAG = "CreateTask";
// Create_common_task 任务的一些变量
TaskHandle_t Create_common_task_handle = NULL;;
// Create_common_task 任务的一些变量
#define CREATE_STATIC_TASK_STACK_SIZE 2048
TaskHandle_t CreateStaticTask_Handle = NULL;
StaticTask_t CreateStaticTask_Buffer;
StackType_t CreateStaticTask_xStack[ CREATE_STATIC_TASK_STACK_SIZE ];
// Create_with_core_task 任务的一些变量
TaskHandle_t Create_with_core_task_handle = NULL;
/**
* @brief Create_common_task
* @param arg 任务传入的参数
* @return NULL
*/
void Create_common_task(void * arg)
{
while (1){
vTaskDelay(1000/portTICK_PERIOD_MS);
ESP_LOGI(TAG,"Create_common_task");
}
}
/**
* @brief CreateStatic_Task
* @param arg 任务传入的参数
* @return NULL
*/
void CreateStatic_Task(void *arg)
{
while (1){
vTaskDelay(1000/portTICK_PERIOD_MS);
ESP_LOGI(TAG,"CreateStatic_Task");
}
}
/**
* @brief CreateRestricted_Task
* @param arg 任务传入的参数
* @return NULL
*/
void CreateRestricted_Task(void * arg)
{
while (1){
vTaskDelay(1000/portTICK_PERIOD_MS);
ESP_LOGI(TAG,"CreateRestricted_Task");
}
}
/**
* @brief Create_with_core_task
* @param arg 任务传入的参数
* @return NULL
*/
void Create_with_core_task(void *arg)
{
// char loop_value = 5;
while (1){
vTaskDelay(1000/portTICK_PERIOD_MS);
ESP_LOGI(TAG,"Create_with_core_task");
// 第二种删除函数打方法: 在自己的任务中删除自己
// if(!loop_value)
// vTaskDelete(NULL);
// loop_value --;
}
}
/**
* @brief 创建函数初始化
* @param NULL
* @return NULL
*/
void CreateTask_Init(void)
{
BaseType_t Create_with_core_task_return;
// 使用 freeREOS的标准API创建任务
xTaskCreate(Create_common_task, // 创建任务
"Create_common_task", // 创建任务名
2048, // 任务堆栈
NULL, // 传入任务参数
2, // 任务优先级
&Create_common_task_handle); // 任务句柄
// 使用xTaskCreateStatic 创建任务
CreateStaticTask_Handle = xTaskCreateStatic(CreateStatic_Task, // 创建任务
"CreateStatic_Task", // 创建任务名
CREATE_STATIC_TASK_STACK_SIZE, // 任务堆栈
NULL, // 传入任务参数
2, // 任务优先级
CreateStaticTask_xStack, // 任务的堆栈数组
&CreateStaticTask_Buffer); // 新任务的数据结构
// 指定在哪个核创建任务
Create_with_core_task_return = xTaskCreatePinnedToCore( Create_with_core_task, // 创建任务
"CreateCore_Task", // 创建任务名
2048, // 任务堆栈
NULL, // 传入任务参数
2, // 任务优先级
&Create_with_core_task_handle, // 任务句柄
1); // 创建在哪个核
vTaskDelay(3000/portTICK_PERIOD_MS);
// 第一种删除函数打方法: 在其他函数中删除Create_with_core_task 任务 Create_with_core_task需要在死循环中,不然会一直复位提示
// FreeRTOS: FreeRTOS Task "Create_with_cor" should not return, Aborting now! 就是说我们的Create_with_core_task 函数没有死循环
// 值的注意的是复位提示的数据Create_with_cor字符串是我们创建任务中const char * const pcName 这个参数,但是我们创建的时候传入的是Create_with_core_task
// 怎么他打印就不全了呢,这个字符串的长度在FreeRTOSConfig.h中configMAX_TASK_NAME_LEN参数设定了 ESP32默认16个长度,所以就是输出Create_with_cor,其中字符串结束\0站一个byte
if(Create_with_core_task_return == pdPASS) // pdPASS = 1
vTaskDelete(Create_with_core_task_handle);
}