【STM32】FreeRTOS 任务消息队列 和 中断消息队列的区别(六)
FreeRTOS 中的消息队列(Queue)是任务之间、任务与中断之间进行通信的核心机制之一。而当我们说:1、任务消息队列;2、中断消息队列; 其实我们说的是:谁在使用这个队列(任务 or 中断)进行发送或接收操作,以及使用的 API 函数是否安全、稳定、合适。
任务消息队列:
[Task A] --xQueueSend()--> [Queue] --xQueueReceive()--> [Task B]中断消息队列:
[ISR Handler] --xQueueSendFromISR()--> [Queue] --xQueueReceive()--> [Task]
那为什么要区分任务和中断队列使用?
这是因为 中断中不能使用阻塞函数,也不能调用导致上下文切换的函数,因此 FreeRTOS 专门提供了 FromISR()
后缀的函数做中断安全的队列操作。
对比项 | 任务消息队列 | 中断消息队列 |
---|---|---|
使用场景 | 任务 → 队列 → 任务 | 中断 → 队列 → 任务 |
入队函数 | xQueueSend() xQueueSendToBack() xQueueSendToFront() | xQueueSendFromISR() xQueueSendToBackFromISR() xQueueSendToFrontFromISR() |
出队函数 | xQueueReceive() xQueuePeek() | xQueueReceiveFromISR() xQueuePeekFromISR() (极少数情况使用) |
是否允许阻塞 | ✅ 可以设置阻塞时间(如 portMAX_DELAY ) | ❌ 中断中禁止阻塞,必须立即返回 |
是否触发任务切换 | ✅ 自动调度(按优先级) | ✅ 需手动触发:使用 portYIELD_FROM_ISR() |
常见用途 | 任务间异步通信 / 消息传递 | 中断事件通知任务(如按键、串口等) |
调用限制 | 无特殊限制 | 只能使用 FromISR 版本的 API 函数 |
任务消息队列
// 任务 A 发送
xQueueSend(MyQueue, &data, 100); // 最多等待 100 tick// 任务 B 接收
xQueueReceive(MyQueue, &recvData, portMAX_DELAY); // 永久等待直到有数据
RTOS 任务通信流程图:
中断消息队列
// ISR 中断发送
void EXTI0_IRQHandler(void)
{uint8_t key = 1;BaseType_t xHigherPriorityTaskWoken = pdFALSE;xQueueSendFromISR(MyQueue, &key, &xHigherPriorityTaskWoken);portYIELD_FROM_ISR(xHigherPriorityTaskWoken); // 必须添加
}
任务消息队列适用于任务间通信,可以使用阻塞等待;中断消息队列用于中断向任务发送事件,必须使用 FromISR()
函数,且不能有阻塞行为。
以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!