FreeRTOS 消息队列 详解

这篇具有很好参考价值的文章主要介绍了FreeRTOS 消息队列 详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

什么是队列?

消息队列特点

1. 数据入队出队方式

2. 数据传递方式

3. 多任务访问

4. 出队、入队阻塞

消息队列相关 API 函数

1. 创建队列

2. 写队列

3. 读队列

消息队列实操


什么是队列?

队列又称消息队列,是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任 务间传递信息。

为什么不使用全局变量?

如果使用全局变量,任务1修改了变量 a ,等待任务3处理,但任务3处理速度很慢,在处理数据的过程中,任务2有可能又修改了变量 a ,导致任务3有可能得到的不是正确的数据。

在这种情况下,就可以使用队列。任务1和任务2产生的数据放在流水线上,任务3可以慢慢一个个依次处理。

关于队列的几个名词:

队列项目:队列中的每一个数据;

队列长度:队列能够存储队列项目的最大数量;

创建队列时,需要指定队列长度及队列项目大小。

消息队列特点

1. 数据入队出队方式

通常采用先进先出(FIFO)的数据存储缓冲机制,即先入队的数据会先从队列中被读取。

也可以配置为后进先出(LIFO)方式,但用得比较少。

2. 数据传递方式

采用实际值传递,即将数据拷贝到队列中进行传递,也可以传递指针,在传递较大的数据的时候 采用指针传递。

3. 多任务访问

队列不属于某个任务,任何任务和中断都可以向队列发送/读取消息

4. 出队、入队阻塞

当任务向一个队列发送消息时,可以指定一个阻塞时间,假设此时当队列已满无法入队。

阻塞时间如果设置为:

  • 0:直接返回不会等待;
  • 0~port_MAX_DELAY:等待设定的阻塞时间,若在该时间内还无法入队,超时后直接返回不再等待;
  • port_MAX_DELAY:死等,一直等到可以入队为止。出队阻塞与入队阻塞类似;

消息队列相关 API 函数

1. 创建队列

QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength,
                            UBaseType_t uxItemSize );

参数:

  • uxQueueLength:队列可同时容纳的最大项目数 。
  • uxItemSize:存储队列中的每个数据项所需的大小(以字节为单位)。

返回值: 如果队列创建成功,则返回所创建队列的句柄 。 如果创建队列所需的内存无法分配 , 则返回 NULL。

2. 写队列

写队列总共有以下几个函数:

                                函数                                 描述
xQueueSend() 往队列的尾部写入消息
xQueueSendToBack() 同 xQueueSend()
xQueueSendToFront() 往队列的头部写入消息
xQueueOverwrite() 覆写队列消息(只用于队列长度为 1 的情况)
xQueueSendFromISR() 在中断中往队列的尾部写入消息
xQueueSendToBackFromISR() 同 xQueueSendFromISR()
xQueueSendToFrontFromISR() 在中断中往队列的头部写入消息
xQueueOverwriteFromISR() 在中断中覆写队列消息(只用于队列长度为 1 的情况)
BaseType_t xQueueSend(
                        QueueHandle_t xQueue,
                        const void * pvItemToQueue,
                        TickType_t xTicksToWait
                    );

参数:

  • xQueue:队列的句柄,数据项将发送到此队列。
  • pvItemToQueue:待写入数据
  • xTicksToWait:阻塞超时时间

返回值:

如果成功写入数据,返回 pdTRUE,否则返回 errQUEUE_FULL。

3. 读队列

读队列总共有以下几个函数:

                               函数                             描述
xQueueReceive() 从队列头部读取消息,并删除消息
xQueuePeek() 从队列头部读取消息,但是不删除消息
xQueueReceiveFromISR() 在中断中从队列头部读取消息,并删除消息
xQueuePeekFromISR() 在中断中从队列头部读取消息
BaseType_t xQueueReceive(
                            QueueHandle_t xQueue,
                            void *pvBuffer,
                            TickType_t xTicksToWait
                    );

参数:

  • xQueue:待读取的队列
  • pvItemToQueue:数据读取缓冲区
  • xTicksToWait:阻塞超时时间

返回值:

  • 成功返回 pdTRUE
  • 否则返回 pdFALSE

消息队列实操

要求:

创建一个队列,按下 KEY1 向队列发送数据,按下 KEY2 向队列读取数据。

打开CubeMX

1.将FreeRTOS移植到STM32F103C8T6,具体看我之前写过的文章

将FreeRTOS移植到STM32F103C8T6

2.然后创建两个任务和一个队列

FreeRTOS 消息队列 详解,FreeRTOS,FreeRTOS,STM32,STM32CubeMX

3.设置按键引脚为输入,然后导出代码

FreeRTOS 消息队列 详解,FreeRTOS,FreeRTOS,STM32,STM32CubeMX

4.编写代码

freertos.c

void StartTaskSend(void const * argument)
{
	uint16_t buf = 100;
	BaseType_t status;
  for(;;)
  {
		if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
		{
			osDelay(20);
			if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
			{
				status = xQueueSend(myQueue01Handle, &buf, 0);
				if(status == pdTRUE)
				printf("写入队列成功,写入值为%d\r\n", buf);
				else
				printf("写入队列失败\r\n");
			}
			while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET);
		}
    osDelay(10);
  }
}


void StartTaskReceive(void const * argument)
{
	uint16_t buf = 100;
	BaseType_t status;
  for(;;)
  {
		if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
		{
			osDelay(20);
			if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
			{
				status = xQueueReceive(myQueue01Handle, &buf, 0);
				if(status == pdTRUE)
				printf("读取队列成功,写入值为%d\r\n", buf);
				else
				printf("读取队列失败\r\n");
			}
			while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET);
		}
    osDelay(10);
  }
}

5.编译烧录后打开串口助手

由于uint16_t buf ,所以最多写入16组数据

FreeRTOS 消息队列 详解,FreeRTOS,FreeRTOS,STM32,STM32CubeMX文章来源地址https://www.toymoban.com/news/detail-720368.html

到了这里,关于FreeRTOS 消息队列 详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FreeRTOS-消息队列详解

    ✅作者简介:嵌入式入坑者,与大家一起加油,希望文章能够帮助各位!!!! 📃个人主页: @rivencode的个人主页 🔥系列专栏: 玩转FreeRTOS 💬保持学习、保持热爱、认真分享、一起进步!!! 本文将详细全方位的讲解FreeRTOS的队列消息,其实在FreeRTOS中队列的重要性也不言

    2024年02月05日
    浏览(36)
  • 搭建STM32F407的Freertos系统(基于STM32CubeMX)

           本人长期开发Linux、Windows上应用软件,一直以来MCU开发有所接触,但较少(最近项目需要,小公司么,都得会,被逼的),好在有STM32CubeMX这样工具,貌似就是我想要的工具。         本次demo目标立下:         1. 搭建或移植FreeRTOS到STM32上,毕竟对于长期在Linux环境

    2024年02月10日
    浏览(46)
  • 基于STM32CubeMX创建FreeRTOS—以STM32F429为例

    目录 1. 实验任务 2. 使用STM32CubeMX创建基础工程 2.1 使用STM32CubeMX创建项目 2.2 创建新项目 2.3 时钟设置 2.4 时钟配置树 2.5 修改时钟基准,打开串行调试 2.6 配置串口 2.7 配置状态指示灯 2.8 FreeRTOS配置 2.9 配置工程输出项 3. 代码编辑 3.1 printf重映射 3.1.1 使用ARMCC 5编译器时的print

    2024年01月22日
    浏览(31)
  • STM32 CubeMX (Freertos任务:创建、删除、挂起、恢复)

    学习使用Freertos第一步 FreeRTOS 任务管理,您需要掌握以下几个关键函数: 1. xTaskCreate() :用于创建一个任务,需要指定任务函数、任务名称、任务栈大小和优先级等参数。 2. vTaskDelete() :用于删除一个任务,可以由任务自身或其他任务调用。 3. vTaskDelay() :用于使当前任务进

    2024年02月12日
    浏览(28)
  • STM32cubemx对FreeRTOS的适配(工程模板配置)

    本篇文章将带大家使用STM32cubemx对FreeRTOS进行工程模板的配置。 1.开始工程的创建: 2.芯片型号选择: 3.修改时钟为TIM8: 在FreeRTOS中SYSTICK需要为FreeRTOS提供心跳,故这里选择TIM8替换SYNTICK。 4.配置RCC: 5.配置FreeRTOS: 6.开启串口方便调试和观察: 7.工程路径及编译器选择等:

    2024年02月07日
    浏览(38)
  • STM32CubeMX+FATFS+FREERTOS读写U盘

    软件:STM32CubeMX V6.6.1 、 KEIL5 V5.29 硬件:STM32F429ZET6 USB_OTG_FS:PA11/PA12引脚 USART1:PA9/PA10,方便输出调试信息 1)SYS下载方式选择SW方式,因为要使用FREERTOS,提前将时钟源修改为TIM7(其他定时器也可以) 2) RCC设置,选择高速外部晶振HSE(根据具体硬件选择) 3)USART1设置,方便输出调

    2024年01月18日
    浏览(37)
  • 【STM32】利用CubeMX对FreeRTOS用按键控制任务

    对于FreeRTOS中的操作,最常用的就是创建、删除、暂停和恢复任务。 此次实验目标: 1.创建任务一:LED1每间隔1秒闪烁一次,并通过串口打印 2.创建任务二:LED2每间隔0.5秒闪烁一次,并通过串口打印 3.创建任务三:通过KEY1实现对任务一的创建和删除。 按键按下以后如果有任

    2024年02月13日
    浏览(51)
  • STM32基于HAL库和STM32CubeMX的实时操作系统FreeRtOS开发

    1、FreeRTOS RTOS是一类操作系统,µC/OS,FreeRTOS,RTX,RT-Thread 等这些都是RTOS 类的操作系统 FreeRTOS 是众多RTOS 类操作系统中的一种,FreeRTOS 十分的小巧,可以在资源有限的微控制器中运行,FreeRTOS 也不仅仅局限于在微控制器中使用。就单从文件数量上来看FreeRTOS 要比µC/OS 少得多

    2024年02月21日
    浏览(50)
  • STM32 CubeMX (第三步Freertos中断管理和软件定时)

    学习使用Freertos第三步 在 FreeRTOS 中,中断管理和软件定时: · taskENTER_CRITICAL() ·; 是一个函数在 FreeRTOS 中使用的,用于进入临界区(critical section)。在临界区内,中断会被禁用,这样可以确保在多任务环境下共享资源的安全性。你可以在需要保护共享资源的代码段中使用 ·

    2024年02月12日
    浏览(51)
  • STM32CubeMx学习FreeRTOS的绝对延时和相对延时

    在阻塞状态中 可以空闲出时间 来让低优先级的任务可以进行 有两种阻塞延时 一个是相对延时 也就是  这样的osDelay可以让在到这里的时候,延时500ms 也就是程序到这里才500ms 不记程序前面所用的时间 而还有一个绝对延时 绝对延时指的是 加上程序自己跑的时间 全部的一起

    2024年02月14日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包