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
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
×
|