物联网操作系统学习笔记——消息队列1

tech2022-09-18  93

FreeRTOS消息队列

消息队列的概念及其意义

1、定义 消息队列(queue),可以在任务与任务间、中断和任务间传递消息 实现任务接收来自其他任务或中断的不固定长度的消息 2、FreeRTOS消息队列的介绍 任务和中断发送消息到消息队列,消息队列接收到消息之后按照尺寸大小存储消息,其他任务想从消息队列中获取数据。当队列中的消息是空时,挂起(pend)读取任务,用户还可以指定挂起的任务时间(timeout)。

3、FreeRTOS的工作原理 消息队列就是一段内存空间

FreeRTOS消息队列详细介绍

消息队列函数应用

实例操作: 功能需求 1、使用消息队列检测串口输入 2、通过串口发送字符串openled6,openled7,openled8,openled9,分别打开板载led6,led7,led8,led9 3、通过串口发送字符串closeled6,closeled7,closeled8,closeled9,分别关闭板载led6,led7,led8,led9

消息队列API xQueueCreate() 1:包含头文件。 2:动态创建。(什么是静态创建,什么是动态创建) xQueueSend()

xQueueSendFromISR() 第三个参数NULL;当你进行发送时,会去比较当时产生中断的任务是否有优先级高的任务进入就绪态。??? xQueueReceive() xQueueReceiveFromISR() STM32CubeMX功能配置 因为LED为拉低导通,所以初始设置为高电平 打开USART的中断

创建消息队列

osMessageQDef(CmdQueue, 20, uint8_t); CmdQueueHandle = osMessageCreate(osMessageQ(CmdQueue), NULL);

消息队列接收和发送功能开发 串口中断使能,在HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)函数中进行中断使能。

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART1 interrupt Init */ HAL_NVIC_SetPriority(USART1_IRQn, 5, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ //开启中断 中断源为接收寄存器不为空 __HAL_UART_ENABLE_IT(uartHandle,UART_IT_RXNE); /* USER CODE END USART1_MspInit 1 */ } }

串口接收任务代码

void Usart_Task(void const * argument) { /* USER CODE BEGIN Usart_Task */ uint8_t u8Index; /* Infinite loop */ for(;;) { //每次初始化之前,把索引初始化为0 u8Index = 0; //一直等待接收消息,第一个消息应该放在消息缓冲区的第一个元素上 if(xQueueReceive(CmdQueueHandle,&u8CmdBuff[u8Index++],portMAX_DELAY) == pdPASS) { while(xQueueReceive(CmdQueueHandle,&u8CmdBuff[u8Index++],50)){} //printf("%d\r\n",u8Index); //保证一包完整的字符串信息 u8CmdBuff[u8Index] = '\0'; printf("%s\r\n",u8CmdBuff); } } /* USER CODE END Usart_Task */ }

消息队列接收和发送功能开发 消息解析控制

# define LED_NUM 4 char *openstring[LED_NUM] = { "openled6", "openled7", "openled8", "openled9", }; char *closestring[LED_NUM] = { "closeled6", "closeled7", "closeled8", "closeled9", }; GPIO_TypeDef * LedPort[LED_NUM] = { LED6_GPIO_Port, LED7_GPIO_Port, LED8_GPIO_Port, LED9_GPIO_Port }; uint16_t LedPin[LED_NUM] ={ LED6_Pin, LED7_Pin, LED8_Pin, LED9_Pin }; void vParseString(uint8_t *buff) { int8_t i; for(i = 0;i<LED_NUM;i++) { if(strcmp((char*)buff,openstring[i]) == 0) { HAL_GPIO_WritePin(LedPort[i], LedPin[i], GPIO_PIN_RESET); printf("%s",openstring[i]); return; } } for(i = 0;i<LED_NUM;i++) { if(strcmp((char*)buff,closestring[i]) == 0) { HAL_GPIO_WritePin(LedPort[i], LedPin[i], GPIO_PIN_SET); printf("%s",closestring[i]); return; } } }

在实验的过程中,出现了一个问题,接受字符串消息的时候,u8Index会多读一位出来,导致返回值多一个问号。

导致,返回值不准确,但是用的课程例程里的相同代码,没有出现问题。我将自己的代码u8CmdBuff[u8Index] = '\0’换成u8CmdBuff[u8Index-1] = ‘\0’;把最后的垃圾字符换去掉就能正确返回。 原因是因为在创建消息队列的过程中 osMessageQDef(CmdQueue, 20, uint8_t);里的uInt8_t,写成了uint16_t,导致多出垃圾内存空间。

最新回复(0)