FreeRTOS - 消息队列

一.消息队列的概念及应用

消息队列(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:消息队列为空

注意事项

调用此函数,会触发上下文切换(当前被中断的任务优先级低于解除阻塞的任务)

在启动调度器之前不能调用此函数

二.函数应用

  1. STM32CubeMX中FreeRTOS配置Queue消息队列

  • 字符串类型char 所以unit8_t。

  1. 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, 接收消息的缓冲区

③TickType_t xTicksToWait );阻塞等待时间

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 */
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值