[经验分享] FreeRTOS任务管理与通信机制详解

[复制链接]
155|0
荣陶陶 发表于 2025-10-11 07:47 | 显示全部楼层 |阅读模式
1 任务的创建与管理
任务创建
使用 xTaskCreate() 创建任务:


BaseType_t xTaskCreate(
    TaskFunction_t pxTaskCode,     // 任务函数(入口)
    const char * const pcName,     // 任务名称(调试用)
    configSTACK_DEPTH_TYPE usStackDepth, // 堆栈大小(单位为字)
    void * const pvParameters,     // 任务参数
    UBaseType_t uxPriority,        // 优先级(0~configMAX_PRIORITIES-1)
    TaskHandle_t * const pxCreatedTask // 任务句柄(可为NULL)
);


注意:任务函数必须符合 void (*TaskFunction_t)(void *) 的原型。

任务删除

vTaskDelete(TaskHandle_t xTaskToDelete);

可删除任意任务,包括自身(传入 NULL)。

任务挂起与唤醒
挂起任务:vTaskSuspend(TaskHandle_t xTask);

唤醒任务:vTaskResume(TaskHandle_t xTask);

用于控制任务的执行时机,但需要避免任务永久挂起导致系统资源浪费。

2 队列(Queue)
定义
队列是典型的FIFO(先进先出)数据结构,用于任务间或中断与任务之间的数据通信。

创建队列

QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize);

uxQueueLength:队列能容纳的最大项目数

uxItemSize:每个项目的大小(字节)

发送数据到队列

xQueueSend(xQueue, pvItemToQueue, xTicksToWait);

xTicksToWait = 0:非阻塞发送

portMAX_DELAY:阻塞直到成功(需要开启阻塞API支持)

从队列接收数据

xQueueReceive(xQueue, pvBuffer, xTicksToWait);

3 信号量(Semaphore)
信号量用于任务之间的同步与资源访问控制。FreeRTOS 提供多种类型的信号量:

1. 二值信号量
用于同步事件或中断信号(如“电话亭”模型)。

创建:xSemaphoreCreateBinary();

获取:xSemaphoreTake(xSemaphore, xBlockTime);

释放:xSemaphoreGive(xSemaphore);

特点:同一任务在未释放时无法再次获取。

2. 互斥信号量(Mutex)
适用于保护共享资源的访问(如外设、内存等),防止资源冲突。

创建:xSemaphoreCreateMutex();

特性:只有获得互斥锁的任务才能释放,错误释放会引发死锁。

3. 计数型信号量
用于资源计数或控制并发数量(如“停车位”模型)。

创建:xSemaphoreCreateCounting(uxMaxCount, uxInitialCount);

当前剩余资源数:uxSemaphoreGetCount(xSemaphore);

4. 递归互斥信号量
允许任务在同一段逻辑中多次获取锁,每次获取必须匹配对应释放。

创建:xSemaphoreCreateRecursiveMutex();

获取:xSemaphoreTakeRecursive(xMutex, xBlockTime);

释放:xSemaphoreGiveRecursive(xMutex);

1.4.4 软件定时器(Software Timer)
软件定时器用于延迟或周期性执行某些任务函数,非阻塞式。

创建软件定时器

TimerHandle_t xTimerCreate(
    const char * const pcTimerName,
    TickType_t xTimerPeriodInTicks,
    UBaseType_t uxAutoReload,           // pdTRUE: 周期性;pdFALSE: 单次
    void * const pvTimerID,
    TimerCallbackFunction_t pxCallbackFunction // 定时器回调
);


定时器启动需要调用 xTimerStart()。系统时间片通过 configTICK_RATE_HZ 定义(常设为 1000,即1ms一tick)。

5 事件标志组(Event Group)
事件标志组提供位操作机制,适用于多事件同步(例如 KEY1 & KEY2 -> LED1_ON)。

创建与设置
创建:xEventGroupCreate();

设置标志位:xEventGroupSetBits(xEventGroup, uxBitsToSet);

等待事件位满足

xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, // 是否在退出时清除标志位 xWaitForAllBits, // 全部满足 vs 任一满足 xTicksToWait );

1.4.6 任务通知(Task Notification)
任务通知是一种轻量级的通信机制,比队列和信号量更高效(最多支持32位通知值)。

发送通知(中断中)

xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken);

ulValue:通知值

eAction:通知模式(如覆盖、累加)

pxHigherPriorityTaskWoken:用于中断上下文切换判断

等待通知

xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait );

使用任务通知可高效地替代传统信号量、事件等机制。

附:常用FreeRTOS配置参数说明



下面是一个完整、结构清晰的 FreeRTOS Demo 示例代码,包含了任务创建、启动任务调度的基本流程,适合初学者参考:

示例:FreeRTOS任务创建与调度启动(主函数中)
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>

// 任务句柄(可选)
TaskHandle_t Task1Handle = NULL;
TaskHandle_t Task2Handle = NULL;

// 任务函数定义
void Task1(void *pvParameters)
{
    while (1)
    {
        printf("Task 1 is running...\n");
        vTaskDelay(pdMS_TO_TICKS(1000));  // 延时1000ms
    }
}

void Task2(void *pvParameters)
{
    while (1)
    {
        printf("Task 2 is running...\n");
        vTaskDelay(pdMS_TO_TICKS(500));  // 延时500ms
    }
}

// 主函数
int main(void)
{
    // 创建任务1
    xTaskCreate(
        Task1,                   // 任务函数
        "Task1",                 // 任务名(调试用)
        128,                     // 堆栈大小(单位为字,128 x 4 = 512字节)
        NULL,                    // 参数
        2,                       // 优先级(范围:0 ~ configMAX_PRIORITIES-1)
        &Task1Handle             // 任务句柄
    );

    // 创建任务2
    xTaskCreate(
        Task2,
        "Task2",
        128,
        NULL,
        1,                       // 优先级低于Task1
        &Task2Handle
    );

    // 启动任务调度器
    vTaskStartScheduler();

    // ***不会运行到这里,除非堆栈不足或调度器启动失败
    while (1);
}

————————————————
版权声明:本文为CSDN博主「平凡灵感码头」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Cha3043445754/article/details/147653192

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

66

主题

266

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部