FreeRTOS操作系统(详细速通篇)——— 第四章

         本专栏将对FreeRTOS进行快速讲解,带你了解并使用FreeRTOS的各部分内容。适用于快速了解FreeRTOS并进行开发、突击面试、对新手小白非常友好。期待您的后续关注和订阅!

目录

任务创建和删除

1 任务创建方式

1.1 动态任务创建

1.2 静态任务创建

2 任务删除函数


任务创建和删除

1 任务创建方式

        任务创建方式分为两种,一种为动态创建,另一种为静态创建方式。区别就是一个系统自行分配,另外一个由用户自己进行分配。

  • 动态创建任务:任务的任务控制块和任务的栈空间所需的内存,均由 FreeRTOS 从 FreeRTOS 管理的堆中分配。
  • 静态创建任务:任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供。

任务创建和删除主要用到以下三个API函数:

API函数

描述

xTaskCreate()

动态方式创建任务

xTaskCreateStatic()

静态方式创建任务

vTaskDelete()

删除任务

1.1 动态任务创建

(1)函数简介

        动态任务创建函数详解如下所示,动态任务创建完成后会有一个返回值,当返回值为pdPASS的时候说明任务创建成功,若为其他值时说明任务创建失败!任务函数详解如下:

返回值

描述

pdPASS

任务创建成功

errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY

任务创建失败

(2)任务创建流程

静态任务创建需要以下三部进行:

  1. 将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1
  2. 定义函数入口参数
  3. 编写任务函数

(3)程序举例

         函数创建举例如下,在这个例子中,我们创建了一个简单的任务,并启动了调度器。注意,实际任务代码可能会更复杂,并且需要根据应用的具体需求进行调整。

#include "FreeRTOS.h"
#include "task.h"

// 任务函数声明
void vTaskFunction(void *pvParameters);

// 主函数
void main(void) {
    // 任务句柄声明
    TaskHandle_t xHandle = NULL;

    // 任务名字声明
    const char *pcTaskName = "TaskName";

    // 堆栈大小声明
    const configSTACK_DEPTH_TYPE usStackDepth = configMINIMAL_STACK_SIZE;

    // 参数声明
    void *pvParameters = NULL;

    // 优先级声明
    UBaseType_t uxPriority = tskIDLE_PRIORITY + 1;

    // 创建任务
    BaseType_t xReturned = xTaskCreate(
        vTaskFunction,     // 任务函数
        pcTaskName,        // 任务名字
        usStackDepth,      // 堆栈大小
        pvParameters,      // 传递给任务函数的参数
        uxPriority,        // 任务优先级
        &xHandle           // 任务句柄
    );

    // 检查任务创建是否成功
    if (xReturned == pdPASS) {
        // 任务创建成功
    } else {
        // 任务创建失败
    }

    // 启动调度器
    vTaskStartScheduler();

    // 程序不应到达这里
    for (;;) {}
}

// 任务函数定义
void vTaskFunction(void *pvParameters) {
    for (;;) {
        // 任务代码
    }
}

1.2 静态任务创建

        静态任务创建函数很少使用,绝大部分都是动态任务创建函数。等大家技术精炼了之后,可以使用静态任务创建函数进行榨干内存试一试。

(1)函数简介

        静态任务创建函数详解如下所示,动态任务创建完成后也会会有一个返回值,其返回值与动态任务创建函数不同,当返回值不等于NULL时任务创建成功,若为其他值时说明任务创建失败!任务函数详解如下:

返回值

描述

NULL

用户没有提供相应的内存,任务创建失败

其他值

任务句柄,任务创建成功

(2)任务创建流程

静态任务创建需要以下5部进行:

  1. 将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1
  2. 定义空闲任务&定时器任务的任务堆栈及TCB
  3. 实现两个接口函数
  4. 定义函数入口参数
  5. 编写任务函数

(3)程序举例

    函数创建举例如下,在这个例子中,我们创建了一个简单的任务,也启动了调度器。注意,实际任务代码可能会更复杂,并且需要根据应用的具体需求进行调整。

#include "FreeRTOS.h"
#include "task.h"

// 任务函数声明
void vTaskFunction(void *pvParameters);

// 静态任务相关变量声明
#define TASK_STACK_SIZE 100  // 定义堆栈大小
#define TASK_PRIORITY tskIDLE_PRIORITY + 1  // 定义任务优先级

// 任务堆栈和任务控制块
static StackType_t xStack[TASK_STACK_SIZE];
static StaticTask_t xTaskBuffer;

void main(void) {
    // 任务名字声明
    const char *pcTaskName = "StaticTask";

    // 参数声明
    void *pvParameters = NULL;

    // 创建静态任务
    TaskHandle_t xHandle = xTaskCreateStatic(
        vTaskFunction,       // 任务函数
        pcTaskName,          // 任务名字
        TASK_STACK_SIZE,     // 堆栈大小
        pvParameters,        // 传递给任务函数的参数
        TASK_PRIORITY,       // 任务优先级
        xStack,              // 任务堆栈
        &xTaskBuffer         // 任务控制块
    );

    // 启动调度器
    vTaskStartScheduler();

    // 程序不应到达这里
    for (;;) {}
}

// 任务函数定义
void vTaskFunction(void *pvParameters) {
    for (;;) {
        // 任务代码
    }
}

2 任务删除函数

(1)函数简介

        任务删除函数非常简单,用于删除已被创建的任务。被删除的任务将从就绪态任务列表、阻塞态任务列表、挂起态任务列表和事件列表中全部移除。

        需要注意的是以下两点:

  1. 传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)
  2. 空闲任务会负责释放被删除任务中由系统分配的内存,但由用户在任务删除前申请的内存, 则需要由用户在任务被删除前提前释放,否则将会导致内存泄露

形参

描述

xTaskToDelete

待删除任务的任务句柄

(2)任务创建流程

静态任务创建需要以下2部进行:

  1. 使用删除任务函数,需将宏INCLUDE_vTaskDelete 配置为 1
  2. 入口参数输入需要删除的任务句柄(NULL代表删除本身)

(3)程序举例

        任务删除函数非常简单,该函数我们在以下程序创建了一个任务,然后删除。

#include "FreeRTOS.h"
#include "task.h"

// 任务函数声明
void vTaskFunction(void *pvParameters);

void main(void) {
    // 任务句柄声明
    TaskHandle_t xHandle = NULL;

    // 创建任务
    BaseType_t xReturned = xTaskCreate(
        vTaskFunction,              // 任务函数
        "TaskName",                 // 任务名字
        configMINIMAL_STACK_SIZE,   // 堆栈大小
        NULL,                       // 传递给任务函数的参数
        tskIDLE_PRIORITY + 1,       // 任务优先级
        &xHandle                    // 任务句柄
    );

    // 检查任务创建是否成功
    if (xReturned == pdPASS) {
        // 任务创建成功,启动调度器
        vTaskStartScheduler();
    } else {
        // 任务创建失败,处理错误
        for (;;) {}
    }
}

// 任务函数定义
void vTaskFunction(void *pvParameters) {
    for (int i = 0; i < 10; i++) {
        // 模拟任务代码
        vTaskDelay(pdMS_TO_TICKS(1000)); // 延时1秒
    }

    // 删除任务
    vTaskDelete(NULL); // 删除自身任务
}

小结

  1. 在实际应用中,动态方式创建任务是最常用的,一般都会使用动态方式创建任务
  2. 动态创建非常简单,并且更为常用
  3. 静态创建:将任务堆栈放置在特定的内存位置,并且不需要关心对内存分配失败的处理

       本专栏将对FreeRTOS进行快速讲解,带你了解并使用FreeRTOS的各部分内容。期待诸君的订阅和关注!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值