一.消息队列的概念及应用
消息队列(queue):可以在任务与任务间、中断和任务间传递消息,实现任务接收来自其他任务或中断的不固定的消息

1.1任务需求
1、使用消息队列检测串口输入
2、通过串口发送字符串openled1,openled2,openled3,分别打开板载led1,led2,led3
3、通过串口发送字符串closeled1,closeled2,closeled3,分别关闭板载led1,led2,led3
1.2API
函数原型 |
#include “FreeRTOS.h” #include “queue.h” QueueHandle_t xQueueCreate( ①UBaseType_t uxQueueLength, ②UBaseType_t uxItemSize ); |
功能概述 |
创建一个消息队列,并返回消息队列句柄 |
参数 |
①:队列一次可容纳消息的最大长度 ②:队列中每个消息体大小 |
返回值 |
NULL:创建失败 Any other value :创建成功,返回消息队列句柄 |
注意事项 |
队列可以用于任务与任务通信,也是用于中断与任务通信 可在调度器开启之前,创建消息队列 |
函数原型 |
#include “FreeRTOS.h” #include “queue.h” BaseType_t xQueueSend/xQueueSendToFront/xQueueSendToBack( ① QueueHandle_t xQueue, ②const void * pvItemToQueue, ③ TickType_t xTicksToWait ); |
功能概述 |
在任务中往队列中传入消息 xQueueSend 等价于xQueueSendToBack 入到队尾 xQueueSendToFront 入到队头 |
参数 |
①:消息队列句柄 ②:要发送的消息的地址 ③:阻塞等待时间 |
返回值 |
pdPASS:发送成功 errQUEUE_FULL:队列已经满,发送失败 |
注意事项 |
None |
函数原型 |
#include “FreeRTOS.h” #include “queue.h” BaseType_t xQueueSendFromISR/xQueueSendToFrontFromISR/xQueueSendToBackFromISR ( ① QueueHandle_t xQueue, ②const void * pvItemToQueue, ③ BaseType_t *pxHigherPriorityTaskWoken); |
功能概述 |
在中断中往队列中传入消息 xQueueSendFromISR 等价于xQueueSendToBackFromISR 入到队尾 xQueueSendToFrontFromISR 入到队头 |
参数 |
①:消息队列句柄 ②:要发送的消息的地址 ③:NULL |
返回值 |
pdTRUE:发送成功 errQUEUE_FULL:队列已经满,发送失败 |
注意事项 |
调用此函数,会触发上下文切换(当前被中断的任务优先级低于解除阻塞的任务) 在启动调度器之前不能调用此函数 |
函数原型 |
#include “FreeRTOS.h” #include “queue.h” BaseType_t xQueueReceive( ①QueueHandle_t xQueue, ②void *pvBuffer, ③TickType_t xTicksToWait ); |
功能概述 |
在任务中读取消息队列消息 |
参数 |
①:消息队列句柄 ②:接收消息的缓冲区 ③:阻塞等待时间 |
返回值 |
pdPASS:创建失败 errQUEUE_EMPTY:消息队列为空 |
注意事项 |
None |
函数原型 |
#include “FreeRTOS.h” #include “queue.h” BaseType_t xQueueReceiveFromISR( ① QueueHandle_t xQueue, ② void *pvBuffer, ③BaseType_t *pxHigherPriorityTaskWoken ); |
功能概述 |
在中断中读取消息队列消息 |
参数 |
①:消息队列句柄 ②:接收消息的缓冲区 ③:NULL |
返回值 |
pdPASS:创建失败 pdFAIL:消息队列为空 |
注意事项 |
调用此函数,会触发上下文切换(当前被中断的任务优先级低于解除阻塞的任务) 在启动调度器之前不能调用此函数 |
二.函数应用
STM32CubeMX中FreeRTOS配置Queue消息队列

字符串类型char 所以unit8_t。
KEIL 消息队列接收和发送功能

HAL_UART_MspInit USART串口初始化
USART.C
开启中断_HAL_UART_EABLE_IT()
__HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__)
@arg USART_IT_CTS: CTS change interrupt
@arg USART_IT_LBD: LIN Break detection interrupt
@arg USART_IT_TXE: Transmit Data Register empty interrupt
TDR寄存器为空时产生的中断标志位
@arg USART_IT_TC: Transmission complete interrupt
DR寄存器发送完最后一个位时产生的中断标志位。
@arg USART_IT_RXNE: Receive Data register not empty interrupt
@arg USART_IT_IDLE: Idle line detection interrupt
@arg USART_IT_PE: Parity Error interrupt
@arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
//开启中断,中断为接收寄存器不为空
__HAL_UART_ENABLE_IT(uartHandle, UART_IT_RXNE);
/* USER CODE END USART1_MspDeInit 1 */
}
STM32f1xx_it.c
获取 SR 寄存器标志位状态,获取此时的串口状态
__HAL_UART_GET_FLAG (__HANDLE__, __FLAG__)
@arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
@arg UART_FLAG_LBD: LIN Break detection flag.
@arg UART_FLAG_TC: Transmission Complete flag.
@arg UART_FLAG_RXNE: Receive data register not empty flag
前文有对该函数说明
BaseType_t xQueueSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken );
extern osMessageQueueId_t CmdQueueHandle;
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
uint8_t Data;
//判断接收标志置位
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)==SET)
{
//读取接收寄存器
//当读取接收寄存器后,UART_FLAG_RXNE自动清除
Data = huart1.Instance ->DR;
//进行入队操作
xQueueSendFromISR(CmdQueueHandle,&Data,NULL);
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
freertos.c (实现消息队列的接收)
函数原型 |
#include “FreeRTOS.h” #include “queue.h” BaseType_t xQueueReceive( ①QueueHandle_t xQueue, :消息队列句柄 ②void *pvBuffer, 接收消息的缓冲区文章来源:https://www.toymoban.com/news/detail-404116.html ③TickType_t xTicksToWait );阻塞等待时间文章来源地址https://www.toymoban.com/news/detail-404116.html |
void Uart_Task(void const * argument)
{
/* USER CODE BEGIN Uart_Task */
/* 创建一个索引*/
uint8_t u8_index;
/* Infinite loop */
for(;;)
{
/*每次读取消息之前,把索引初始化为0;*/
u8_index = 0;
/* 一直等待接收消息,第一个消息应该放在消息缓冲区的第一个元素上 */
if(xQueueReceive(CmdQueueHandle,&CmdBuff[u8_index++],portMAX_DELAY) == pdPASS)
{
while(xQueueReceive(CmdQueueHandle,&CmdBuff[u8_index++],50));
/*保证完整一包的字符串信息*/
CmdBuff[u8_index] = '\0';
printf("%s/r/n",CmdBuff);
}
osDelay(1);
}
/* USER CODE END Uart_Task */
}
到了这里,关于FreeRTOS - 消息队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!