当前位置: 首页 > ai >正文

FreeRTOS任务管理与通信机制详解

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配置参数说明

宏定义含义
configMAX_PRIORITIES最大优先级数(通常为5或更高)
configMINIMAL_STACK_SIZE任务最小栈大小(128即为512字节)
configMAX_TASK_NAME_LEN任务名最大长度(常为16)
configTICK_RATE_HZ

下面是一个完整、结构清晰的 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)
{// 创建任务1xTaskCreate(Task1,                   // 任务函数"Task1",                 // 任务名(调试用)128,                     // 堆栈大小(单位为字,128 x 4 = 512字节)NULL,                    // 参数2,                       // 优先级(范围:0 ~ configMAX_PRIORITIES-1)&Task1Handle             // 任务句柄);// 创建任务2xTaskCreate(Task2,"Task2",128,NULL,1,                       // 优先级低于Task1&Task2Handle);// 启动任务调度器vTaskStartScheduler();// 永远不会运行到这里,除非堆栈不足或调度器启动失败while (1);
}

🔍 说明

  • xTaskCreate():注册任务并准备调度,必须在 vTaskStartScheduler() 前调用。

  • vTaskDelay():实现任务延时,使用 pdMS_TO_TICKS() 宏可避免硬编码。

  • vTaskStartScheduler():启动调度器,之后 FreeRTOS 会自动管理任务切换。

http://www.xdnf.cn/news/3372.html

相关文章:

  • IPD研学:76页页基于IPD思想-华为需求管理培训方案【附全文阅读】
  • 初学python的我开始Leetcode题8-3
  • 第T10周:数据增强
  • python类私有变量
  • 【LeetCode 热题 100】3.无重复字符的最长子串:详解滑动窗口解法
  • 第3篇:请求参数处理与数据校验
  • [vscode]全局配置nim缩进
  • synchronized与Lock深度对比
  • 新能源行业供应链规划及集成计划报告(95页PPT)(文末有下载方式)
  • 2025五一杯数学建模C题:社交媒体平台用户分析问题;思路分析+模型代码
  • 嵌入式C语言的运算符与输入输出
  • 方案精读:58页华为:全面预算管理与实践【附全文阅读】
  • 补4月30日
  • python310 安装 tensorflow-gpu2.10
  • 内网穿透系列二:使用cpolar公开一个本地Web站点到公网
  • 补题:K - Magic Tree (Gym - 105231K)
  • Java 期中考试试题考点剖析
  • jupyter notebook汉化教程
  • 打包 Python 项目为 Windows 可执行文件:高效部署指南
  • 题解:CF1398D Colored Rectangles
  • 【一】 基本概念与应用领域【数字图像处理】
  • Python基本语法(控制语句)
  • Spring IoC容器的设计与实现
  • ERP系统(技术面)知识积累
  • Transformer架构的解耦重组现象
  • SpringTas定时任务使用详解
  • GPU虚拟化实现(七)
  • MySQL基础关键_003_DQL(二)
  • 动态规划简单题
  • 【验证技能】验证质量活动及其执行注意事项