FREERTOS学习笔记三-消息队列

FREERTOS学习笔记三-消息队列

1.实验内容

​ 实验二内容:创建两个动态任务,任务一控制LED的闪烁,任务二用于检测按键。当按键KEY0按下时,任务一被挂起;当按键KEY1被按下时,任务一被取消挂起。

​ 实验三是在实验二的基础上进行修改,增加一个消息队列和两个任务进程;任务二按键检测,当按键被按下时,会发生消息;任务三和任务四负责接收消息。

2.CubeMX的配置

1.1添加两个优先级相同的任务

请添加图片描述

1.2添加消息队列

消息大小为16,消息格式为无符号的16位

请添加图片描述

1.3添加调试串口

请添加图片描述

2.程序编写

2.1printf函数重定向

2.1.1添加头文件

请添加图片描述

#include "stdio.h"

2.1.2添加重定义函数

请添加图片描述

int fputc(int ch,FILE *f)
{
   HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);//hurat1为串口号,根据自己情况进行选择
   return ch;
}

2.1.3勾选use microlib

请添加图片描述

2.2按键任务编写

void StartKEY_Task(void const * argument)
{
  /* USER CODE BEGIN StartKEY_Task */
  /* Infinite loop */
	uint16_t ProducerValue = 1;
  for(;;)
  {
		if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)
		{
			osDelay(10);//消抖
			if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)
			{
				if(osMessagePut(myQueue01Handle,ProducerValue,0) != osOK)//0表示发送完等待时间
				{
					osThreadSuspendAll();
					printf("发送失败\r\n");
					osThreadResumeAll();
				}
				else
				{
					osThreadSuspendAll();
					printf("发送成功\r\n");
					ProducerValue++;
					osThreadResumeAll();
				}
			}
		}
		while(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin) == 0)//等待按键释放,防止连续发送
		{
			osDelay(10);
		}
    osDelay(1);
  }
  /* USER CODE END StartKEY_Task */
}

2.3任务3编写

void StartTask03(void const * argument)
{
  /* USER CODE BEGIN StartTask03 */
  /* Infinite loop */
	osEvent event;
  for(;;)
  {
		event = osMessageGet(myQueue01Handle,osWaitForever);//一直等待消息
		if(event.status == osEventMessage)
		{
			printf("任务3数据:%d\r\n",event.value.v);
		}
    osDelay(1);
  }
  /* USER CODE END StartTask03 */
}

2.4任务4编写

void StartTask04(void const * argument)
{
  /* USER CODE BEGIN StartTask04 */
  /* Infinite loop */
	osEvent event;
  for(;;)
  {
		event = osMessageGet(myQueue01Handle,osWaitForever);//一直等待消息
		if(event.status == osEventMessage)
		{
			printf("任务4数据:%d\r\n",event.value.v);
		}
    osDelay(1);
    osDelay(1);
  }
  /* USER CODE END StartTask04 */
}

3.运行结果1

​ 任务3和任务4争抢时间片接收消息

请添加图片描述

4.提高任务三的优先级

请添加图片描述

5.调试结果2

​ 因为任务3的优先级较高,当任务3是采用osMessageGet()函数接收消息,在其接到之后会删除消息内容,然后任务4不会接收到消息。

请添加图片描述

6.更改接收函数

​ 将任务3的osMessageGet()更换为osMessagePeek()接收函数

请添加图片描述

​ 同时在库函数中添加

event.value.v = 0;

因为这个函数是处理32位的数据,而本次实验采用的数据为16位,该函数处理数据时会将这16位数据存在在32位数据的低16位,而将高的十六位用1补充,这会导致输出结果错误(输出-65535),所以添加这句能够使该函数在处理16位数据时,将32位的高16位置为0.

请添加图片描述

7.调试结果3

​ 由于osMessagePeek()函数接收消息后,不会删除消息,那么任务4就可以接收到消息。

请添加图片描述

8.关键函数

发送消息

osMessagePut(myQueue01Handle,ProducerValue,0)

删除消息的接收消息

event = osMessageGet(myQueue01Handle,osWaitForever);

不删除消息的接收消息

event = osMessagePeek(myQueue01Handle,osWaitForever);

版权声明:本文为CSDN博主「ViTO_2001」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_46384359/article/details/122775860

生成海报
点赞 0

ViTO_2001

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

FREERTOS学习笔记七-定时器

FREERTOS学习笔记七-定时器 1.实验内容 ​ 本次实验内容是在实验三的基础上增加定时器功能,并在定时器的回调函数中进行串口打印。 2.CubeMX的配置 2.1使能定时器 并配置定时器中断优先级、队列消息长度和深

Error:..\FreeRTOS\queue.c,1088

1. 在一次 FreeRTOS 项目中,STM32串口输出了如下错误: 2. 排查后我发现在一个任务里面添加了新的函数,但是此任务被分配的任务堆栈很小(32),