freeRTOS任务创建和删除

Posted WangLanguager

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了freeRTOS任务创建和删除相关的知识,希望对你有一定的参考价值。

FreeRTOS 中任务的创建和删除使用 xTaskCreate 和 vTaskDelete 函数。

一、创建任务

xTaskCreate 函数用于创建一个新任务。它的原型如下:

BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,
                        const char * const pcName,
                        configSTACK_DEPTH_TYPE usStackDepth,
                        void *pvParameters,
                        UBaseType_t uxPriority,
                        TaskHandle_t *pxCreatedTask);

参数说明:

  • pvTaskCode:指向任务函数的指针。

  • pcName:任务的名称(字符串)。

  • usStackDepth:任务堆栈的大小(以字节为单位)。

  • pvParameters:传递给任务函数的参数,可以是任何类型的指针。

  • uxPriority:任务的优先级。数字越大,优先级越高。

  • pxCreatedTask:指向任务句柄的指针。如果该参数不为NULL,则在任务创建时将填充该值。

例如,以下代码将创建一个名为 task1 的任务,其优先级为1,堆栈大小为128字节:

void task1(void *pvParameters) 
  // 任务的代码


void setup() 
  // ...

  TaskHandle_t task1handle = NULL; // 任务句柄
  xTaskCreate(task1, "task1", 128, NULL, 1, &task1handle);

  // ...

二、删除任务

vTaskDelete 函数用于删除一个任务。它的原型如下:

void vTaskDelete(TaskHandle_t xTaskToDelete);

参数说明:

  • xTaskToDelete:要删除的任务句柄。

例如,以下代码将删除名为 task1 的任务:

TaskHandle_t task1handle = NULL; // 任务句柄
xTaskCreate(task1, "task1", 128, NULL, 1, &task1handle);

// 等待一段时间...

vTaskDelete(task1handle);

三、以下是一个使用FreeRTOS创建和删除任务的例子:

#include <Arduino_FreeRTOS.h>

void task1(void *pvParameters) 
  while(true) 
    Serial.println("Task 1 is running...");
    vTaskDelay(1000 / portTICK_PERIOD_MS); // 暂停1秒
  


void setup() 
  // 初始化串口
  Serial.begin(9600);
  
  // 创建任务1
  TaskHandle_t task1handle = NULL; // 任务句柄
  xTaskCreate(task1, "Task 1", 128, NULL, 1, &task1handle);

  // 等待5秒钟
  vTaskDelay(5000 / portTICK_PERIOD_MS);

  // 删除任务1
  vTaskDelete(task1handle);

  // 启动调度器
  vTaskStartScheduler();


void loop() 
  // 主循环中不需要任何代码

在这个例子中,我们首先定义了一个任务函数 task1。接着在 setup 函数中,我们初始化串口、创建任务1,并获取到任务1的句柄。

接下来,我们暂停5秒钟,然后使用 vTaskDelete 函数删除任务1。

最后,在 setup 函数中启动 FreeRTOS 调度器。当程序运行时,FreeRTOS 将会轮流执行任务1。在5秒钟之后,任务1将被删除。

值得注意的是,一旦任务被删除,它就不能再次运行。因此,在删除任务前一定要确保该任务已经完成了所有的操作。

004_FreeRTOS创建与删除任务

(一)创建与删除任务函数

技术分享图片

 

(二)上面的四个函数目前只用动态创建任务和删除任务

(三)动态创建任务 函数 xTaxkCreate()

1. 宏 configSUPPORT_DYNAMIC_ALLOCATION 必须为 1

2. 新创建的任务默认就是就绪态的,如果当前没有比它更高优先级的任务运行那么此任务就会立即进入运行态开始运行,不管在任务调度器启动前还是启动后,都可以创建任务

3. 函数原型

BaseType_t xTaskCreate(  TaskFunction_t pxTaskCode,
               const char * const pcName,
               const uint16_t usStackDepth,
               void * const pvParameters,
               UBaseType_t uxPriority,
               TaskHandle_t * const pxCreatedTask )

 

参数:

pxTaskCode: 任务函数。
pcName: 任务名字,一般用于追踪和调试,任务名字长度不能超过。configMAX_TASK_NAME_LEN。
usStackDepth : 任务堆栈大小,注意实际申请到的堆栈是 usStackDepth 的 4 倍。其中空闲任务的任务堆栈大小为 configMINIMAL_STACK_SIZE。
pvParameters: 传递给任务函数的参数。
uxPriotiry: 任务优先级,范围 0~ configMAX_PRIORITIES-1。
pxCreatedTask: 任务句柄,任务创建成功以后会返回此任务的任务句柄,这个句柄其实就是任务的任务堆栈。此参数就用来保存这个任务句柄。其他 API 函数可能会使用到这个句柄。

返回值:
pdPASS: 任务创建成功。
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY: 任务创建失败,因为堆内存不足!

 

(四)删除任务数 函数 vTaskDelete()

删除一个用函数 xTaskCreate()或者 xTaskCreateStatic()创建的任务,被删除了的任务不再存
在,也就是说再也不会进入运行态。任务被删除以后就不能再使用此任务的句柄!如果此任务
是使用动态方法创建的,也就是使用函数 xTaskCreate()创建的,那么在此任务被删除以后此任
务之前申请的堆栈和控制块内存会在空闲任务中被释放掉,因此当调用函数 vTaskDelete()删除
任务以后必须给空闲任务一定的运行时间。


只有那些由内核分配给任务的内存才会在任务被删除以后自动的释放掉,用户分配给任务
的内存需要用户自行释放掉,比如某个任务中用户调用函数 pvPortMalloc()分配了 500 字节的内
存,那么在此任务被删除以后用户也必须调用函数 vPortFree()将这 500 字节的内存释放掉,否
则会导致内存泄露。此函数原型如下:

vTaskDelete( TaskHandle_t xTaskToDelete )

 

(五)任务创建和删除实验(动态方法)

● 任务设置

#define START_TASK_PRIO  1            //任务优先级    (1)
#define START_STK_SIZE 128           //任务堆栈大小   (2)
TaskHandle_t StartTask_Handler;        //任务句柄      (3)
void start_task(void *pvParameters);     //任务函数      (4)

 ● main()函数

int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4     
    delay_init();                        //延时函数初始化     
    uart_init(115200);                    //初始化串口

//创建开始任务 xTaskCreate((TaskFunction_t )start_task, //任务函数 (const char* )"start_task", //任务名称 (uint16_t )START_STK_SIZE, //任务堆栈大小 (void* )NULL, //传递给任务函数的参数 (UBaseType_t )START_TASK_PRIO, //任务优先级 (TaskHandle_t* )&StartTask_Handler); //任务句柄 vTaskStartScheduler(); //开启任务调度 }

● 开始任务函数,用来创建其他的任务

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建中断测试任务
    xTaskCreate((TaskFunction_t )interrupt_task,              //任务函数
                (const char*    )"interrupt_task",             //任务名称
                (uint16_t       )INTERRUPT_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                        //传递给任务函数的参数
                (UBaseType_t    )INTERRUPT_TASK_PRIO,        //任务优先级
                (TaskHandle_t*  )&INTERRUPTTask_Handler);     //任务句柄
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

 




















以上是关于freeRTOS任务创建和删除的主要内容,如果未能解决你的问题,请参考以下文章

freeRTOS任务创建和删除

004_FreeRTOS创建与删除任务

FreeRTOS——任务管理

2FreeRTOS任务相关API函数

FreeRTOS任务创建删除

FreeRtos——单任务