ESP32-FreeRtos任务-1

1 篇文章 0 订阅
1 篇文章 0 订阅

头文件

task. h

函数说明

创建任务

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

创建一个新任务并将其添加到准备运行的任务列表中。 configSUPPORT_DYNAMIC_ALLOCATION 必须在 FreeRTOSConfig.h 中被设置为 1,或保留未定义状态(此时,它默认 默认为 1) ,才能使用此 RTOS API 函数。

每个任务都需要 RAM 来保存任务状态,并由任务用作其 堆栈。 如果使用 xTaskCreate() 创建任务,则所需的 RAM 将自动 从 FreeRTOS 堆中分配。 如果创建任务 使用了 xTaskCreateStatic(),则 RAM 由应用程序编写者提供,因此可以在编译时进行静态分配。 请参阅 静态分配 Vs 动态分配 页面,了解更多信息。

如果您使用的是 FreeRTOS-MPU,则 我们建议您使用 xTaskCreateRestricted() 而不是 xTaskCreate()

参数:

pvTaskCode  指向任务入口函数的指针(即 实现任务的函数名称,请参阅如下示例)。

任务通常 以 无限循环的形式实现;实现任务的函数决不能试图返回 或退出。 但是,任务可以 自我删除

pcName  任务的描述性名称。主要是为了方便 调试,但也可用于 获取任务句柄

任务名称的最大长度由 FreeRTOSConfig.h 中的 configMAX_TASK_NAME_LEN 定义。

uxStackDepth  分配用于 任务堆栈的 堆栈。例如,如果堆栈的宽度为 16 位,uxStackDepth 为 100,则将分配 200 字节用作该任务的堆栈。 再举一例,如果堆栈的宽度为 32 位,uxStackDepth 为 400,则将分配 1600 字节用作该任务的堆栈。

堆栈深度与堆栈宽度的乘积不得超过 size_t 类型变量所能包含的最大值。

请参阅常见问题:堆栈应有多大?

pvParameters  作为参数传递给创建的任务的一个值。

如果 pvParameters 设置为变量的地址, 则在执行创建的任务时该变量必须仍然存在——因此 传递堆栈变量的地址是无效的。

uxPriority  创建任务执行的优先级 。

包含 MPU 支持的系统可在特权(系统)模式下选择性地创建任务, 方法是在 uxPriority 中设置 portPRIVILEGE_BIT 位。 例如,要创建一个优先级为 2 的特权任务,可将 uxPriority 设置为 ( 2 | portPRIVILEGE_BIT )。

断言优先级低于 configMAX_priority。 如果未定义 configASSERT,则优先级会被静默限制为 ( configMAX_priority - 1)。

pxCreatedTask  用于将句柄传递至由 xTaskCreate() 函数创建的任务 。 pxCreatedTask 是可选的,可设置为 NULL

删除任务

void vTaskDelete( TaskHandle_t xTask );

INCLUDE_vTaskDelete 必须定义为 1 才能使用此函数。详情请参阅 RTOS 配置文档。

此函数的作用为从 RTOS 内核管理中移除任务。被删除的任务将从所有的就绪、阻塞、挂起和事件的列表中移除。

请注意,空闲任务负责从已删除任务中释放 RTOS 内核分配的内存。因此,重要的是,如果您的应用程序调用了 vTaskDelete (),空闲任务不会失去微控制器处理时间。任务代码分配的内存不会自动释放,并且应在删除任务之前释放。

请参阅演示应用程序文件 death. c,获取使用 vTaskDelete () 的代码示例。

参数:

xTask 待删除的任务的句柄。传递 NULL 将导致调用任务被删除。

任务延时

void vTaskDelay( const TickType_t xTicksToDelay );

必须将 INCLUDE_vTaskDelay 定义为 1,此函数才可用。 请参阅 RTOS 配置文档,了解更多信息,

按给定的 tick 数延迟任务。任务保持阻塞的实际时间取决于 tick 频率。 常量 portTICK_PERIOD_MS 配合 tick 周期分辨率可用于从 tick 频率计算实际时间。

vTaskDelay() 会指定任务想要取消阻塞的时间,该时间是相对于 vTaskDelay() 被调用的时间。 例如,如果指定 时间块为 100 个 tick,那么在调用 vTaskDelay() 100 个 tick 后任务会取消阻塞。 vTaskDelay() 并不会因此提供一种 控制周期性任务频率的好办法,因为途径代码的路径以及其他任务和中断活动将影响 vTaskDelay() 被调用的频率,进而会影响下一个任务执行的时间。 请参阅 vTaskDelayUntil(),了解为 便于任务以固定频率执行而设计的替代 API 函数。 它通过指定调用任务应取消阻塞的绝对时间(而非相对时间)来实现这一点。

参数:

xTicksToDelay 调用任务应阻塞的 tick 周期数。

官方提供很多种任务延迟函数,请参考官方帮助文档,vTaskDelay为最常用的一种

测试Demo代码

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"

void task1FunctionBody(void *pvParameters)
{
    for (;;)
    {
        printf("--------Task1-------\n");

        // 子任务自我阻塞
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void task2FunctionBody(void *pvParameters)
{
    TickType_t xLastWakeTime;
    const TickType_t xFrequency = 10;
    xLastWakeTime = xTaskGetTickCount();
    for (;;)
    {
        // 从这个vTaskDelayUntil函数的调用开始
        vTaskDelayUntil(&xLastWakeTime, xFrequency);
        printf("--------Task2-------\n");

    }
}

void task3FunctionBody(void *pvParameters)
{
    TickType_t xLastWakeTime;
    const TickType_t xFrequency = 100;
    xLastWakeTime = xTaskGetTickCount();
    xLastWakeTime = xLastWakeTime + 10000;
    for (;;)
    {
        // 从这个时间:xLastWakeTime 开始
        // 宏 pdMS_TO_TICKS() 可以用来计算以毫秒为单位的时间的 tick 数, 分辨率为一个 tick 周期
        xTaskDelayUntil(&xLastWakeTime, xFrequency);
        printf("--------Task3-------\n");
    }
}

void app_main(void)
{
    printf("Hello world!\n");

    // 定义创建任务返回对象
    BaseType_t xReturned;
    // 定义创建任务后的句柄
    TaskHandle_t taskHandle1, taskHandle2,taskHandle3;

    // 创建任务---优先级值越大,权力就越大
    xReturned = xTaskCreate(task1FunctionBody, "HelloName1", 1024 * 5, (void *)0, 0, &taskHandle1);  // 优先级0
    xTaskCreate(task2FunctionBody, "HelloName2", 1024 * 5, (void *)0, 1, &taskHandle2);  // 优先级1
    xTaskCreate(task3FunctionBody, "HelloName3", 1024 * 5, (void *)0, 2, &taskHandle3);  // 优先级2

    // 阻塞任务10秒钟
    vTaskDelay(10000 / portTICK_PERIOD_MS);


}

我公司承接各类技术服务,主要聚焦于:stm32、单片机、嵌入式、QT应用开发、Web+Python+Django应用开发。欢迎合作。

  • 57
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
FreeRTOS是一个开源的实时操作系统内核,被广泛应用于嵌入式系统中。ESP32是一款具有双核处理器和Wi-Fi功能的芯片,通过使用ESP-IDF开发框架可以进行软件开发。在ESP32-IDF开发中,使用FreeRTOS的消息队列可以实现不同任务之间的通信。 在ESP32开发中,可以通过中断服务程序(Interrupt Service Routine,ISR)来发送消息到消息队列,并在任务中通过接收方法响应。 首先,我们需要创建一个全局的消息队列句柄,可以使用xQueueCreate函数来创建一个消息队列。例如,可以使用以下代码创建一个大小为10的消息队列: xQueueHandle messageQueue = xQueueCreate(10, sizeof(int)); 然后,在中断服务程序中,可以使用xQueueSendFromISR方法将消息发送到消息队列中。例如,可以使用以下代码将一个整数值发送到消息队列中: int value = 100; xQueueSendFromISR(messageQueue, &value, NULL); 在任务中,可以使用xQueueReceive方法从消息队列中接收消息并进行响应。例如,可以使用以下代码从消息队列中接收一个整数值并打印出来: int receivedValue; xQueueReceive(messageQueue, &receivedValue, portMAX_DELAY); printf("Received value: %d\n", receivedValue); 需要注意的是,在接收消息时,可以通过指定第三个参数来设置等待时间。例如,使用portMAX_DELAY表示无限等待,即直到接收到消息为止。 通过以上步骤,我们可以实现在ESP32开发中使用FreeRTOS消息队列进行中断服务消息发送与响应。这种方式可以实现不同任务之间的通信和同步,提高系统的并发性和实时性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汉森教育

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值