(后文有修改)
一、思路
USART+DMA空闲中断发生后,将接收到的DMA消息用消息队列发出去xQueueSendToFrontFromISR,FreeRTOS创建一个独立的任务一直等待接受消息队列。
DMA中断可以被FreeRTOS管理。
二、CubeMx配置驱动
2.1 USART+DMA
FreeRTOS设置的中断管理范围为5~15,USART中断应该在该范围内,此处设计为7。
2.2 FreeRTOS创建UsartRx 任务,创建消息队列Queue,生成代码。
三、修改代码
3.1 usart.c
(1)增加引用和定义
(2)编写中断处理函数
3.2 XXXit.c
3.3 FreeRTOS.c
修改CubeMx创建的usartRxMsgQueueHandle,指定为队列深度为3,单个Item大小为sizeof(USART_RECEIVETYPE)。
MX_FREERTOS_Init(void)执行结束后将isFreeRTOSSysOn设置为1,通知串口中断处理程序启用xQueueSendToFrontFromISR。
最后在usartRxFunc任务函数入口编写串口数据业务处理逻辑,调用xQueueReceive一直阻塞等待。
四、消息队列的使用方式
1、使用队列添加引用:#include "queue.h"2、初始化:osMessageQueueId_t usartRxMsgQueueHandle;
const osMessageQueueAttr_t usartRxMsgQueue_attributes = {.name = "usartRxMsgQueue"
};usartRxMsgQueueHandle = osMessageQueueNew (3, sizeof(USART_RECEIVETYPE), &usartRxMsgQueue_attributes);3、发送队列消息
(1)中断函数中发送队列消息
xQueueSendToFrontFromISR、xQueueSendToBackFromISR、xQueueOverwriteFromISR、xQueueSendFromISR、xQueueGenericSendFromISR等
e.g.
xxxISR(void)
{BaseType_t xHigherPriorityTaskWoken = pdFALSE;...xQueueSendToFrontFromISR(usartRxMsgQueueHandle,&Uart1Rx,&xHigherPriorityTaskWoken);...portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
(2)普通函数中发送队列消息
xQueueSendToFront、xQueueSendToBack、xQueueOverwrite、xQueueSend、xQueueGenericSend等4、等待、查询接受队列消息
(1)中断函数中查询队列消息
xQueuePeekFromISR等(2)普通函数中等待查询队列消息
xQueueReceive、uxQueueMessagesWaiting、xQueuePeek、uxQueueSpacesAvailable等
2021 09 22 补充:
以上实现队列使用方法是基于cmsis_os,对于cmsis_os2,已经不需要考虑接口是否是FromISR,直接使用osMessageQueuePut接口即可。如下: