[FREERTOS]队列

news2024/11/20 16:28:37

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);

参数1:UBaseType_t uxQueueLength:队列中最大可存放的项目数

参数2:UBaseType_t uxItemSize:每个项目的大小

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

在cubeMX中配置好后会自动封装新的函数创建队列

声明定义两个任务和一个队列的句柄

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:待写入的数据

xTickToWait:阻塞超时时间

成功写入的话返回pdTRUE,否则返回errQUEUE_FULL       

4.读队列

 xQueueReceive();//从队列头部读取消息并删除此消息

 xQueuePeek();//从队列头部读取消息但不删除此消息

xQueueReceiveFromISR();//在中断中从队列头部读取消息,并删除消息

xQueueRPeekFromISR();在中断中从队列头部读取消息,不删除消息

BaseType_t xQueueReceive{        

        QueueHandle_t       xQueue,

        const void*  pvBuffer,

        TickType_t  xTicksToWait

};

xQueue:待读取的队列

pvItemToQueue:数据读取缓存区

xTickToWait:阻塞超时时间

成功写入的话返回pdTRUE,否则返回pdFALSE

按键key1发送数据给队列,按键key2接收队列数据

 

freertos.c

/*cubeMX配置的代码------------------------------↓*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
osThreadId taskSendHandle;
osThreadId taskReceiveHandle;
osMessageQId myQueueHandle;

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void StartTaskSend(void const * argument);
void StartTaskReceive(void const * argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );

/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];

void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
  *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
  *ppxIdleTaskStackBuffer = &xIdleStack[0];
  *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
  /* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* Create the queue(s) */
  /* definition and creation of myQueue */
  osMessageQDef(myQueue, 16, uint16_t);
  myQueueHandle = osMessageCreate(osMessageQ(myQueue), NULL);

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* definition and creation of taskSend */
  osThreadDef(taskSend, StartTaskSend, osPriorityNormal, 0, 128);
  taskSendHandle = osThreadCreate(osThread(taskSend), NULL);

  /* definition and creation of taskReceive */
  osThreadDef(taskReceive, StartTaskReceive, osPriorityNormal, 0, 128);
  taskReceiveHandle = osThreadCreate(osThread(taskReceive), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

}
/*cubeMX配置的代码------------------------------↑*/







/*需要手动敲的代码------------------------------↓*/
void StartTaskSend(void const * argument)
{
  /* USER CODE BEGIN StartTaskSend */
	uint16_t buf = 100;
	BaseType_t status;
  /* Infinite loop */
  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(myQueueHandle,&buf,0);
				if(status == pdTRUE)/如果发送成功会返回pdTRUE
				{
					printf("send success:%d\r\n",buf);
				}else
				{
					printf("send error\r\n");
				}
			}
			while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET);
		}
    osDelay(10);
  }
  /* USER CODE END StartTaskSend */
}

/* USER CODE BEGIN Header_StartTaskReceive */
/**
* @brief Function implementing the taskReceive thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskReceive */
void StartTaskReceive(void const * argument)
{
  /* USER CODE BEGIN StartTaskReceive */
		uint16_t buf;
	BaseType_t status;
  /* Infinite loop */
  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(myQueueHandle,&buf,0);
				if(status == pdTRUE)//如果接收成功会返回pdTRUE
				{
					printf("read success:%d\r\n",buf);
				}else
				{
					printf("read error\r\n");
				}
			}
			while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == GPIO_PIN_RESET);
		}
    osDelay(10);
  }
  /* USER CODE END StartTaskReceive */
}
/*需要手动敲的代码------------------------------↑*/

 uart.c

#include "usart.h"

/* USER CODE BEGIN 0 */
#include <string.h>
#include <stdio.h>
int fputc(int ch,FILE*f)//printf重定向
{
	unsigned char temp[1] = {ch};
	HAL_UART_Transmit(&huart1,temp,strlen((const char*)temp),0xffff);
	return ch;
}

重定向一定记住 勾选Use MicroLIB!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/428318.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网工必知—什么是堡垒机?-CCIE

什么是堡垒机&#xff1f; 网络工程师一定听过或用过所谓的“堡垒机”&#xff0c;那么堡垒机到底是什么呢&#xff1f; 堡垒机是一种跳板机制&#xff08;Jump Server&#xff09;&#xff0c;在一个特定的网络环境下&#xff0c;为了保障网络和数据不受来自外部和内部用户的…

flink 1.16 在centos安装 部署踩的坑

报错: 1 RESOURCES_DOWNLOAD_DIR : 这个错误是修改了 conf目录下 的 master 或 workers 等信息造成的. 2 修改了这个信息可能会造成输入密码的问题. 3 Could not connect to BlobServer at address localhost/127.0.0.1:39203 这个端口还会变化,这种问题可能是因为conf下的…

Python将Word文件中的内容写入Excel文件

在日常办公中我们经常需要将word文件中的数据写入Excel中&#xff0c;如果是手动一个一个进行复制粘贴&#xff0c;那将会非常的耗时且繁琐&#xff01; 遇到这种问题我们首先想到就是利用编程解决&#xff0c;今天我分享一个word转excel的小方法&#xff01; 首先我有一个wo…

常见漏洞扫描工具AWVS、AppScan、Nessus的使用

HVV笔记——常见漏洞扫描工具AWVS、AppScan、Nessus的使用1 AWVS1.1 安装部署1.2 激活1.3 登录1.4 扫描web应用程序1.4.1 需要账户密码登录的扫描1.4.2 利用录制登录序列脚本扫描1.4.3 利用定制cookie扫描1.5 扫描报告分析1.5.1 AWVS报告类型1.5.2 最常用的报告类型&#xff1a…

Microchip的10M以太网解决方案

&#xff08;以下所有图片均来源于Microchip官网&#xff09; 一 为什么需要10M车载以太网 目前车载百兆以太网&#xff08;100Base-T1&#xff09;和千兆以太网&#xff08;1000Base-T1&#xff09;技术较为成熟&#xff0c;但如果直接用100Base-T1/1000Base-T1来替代目前被广…

anaconda 创建虚拟环境 基本命令操作

下载好之后直接打开 anaconda prpmpt : 此时直接输入 &#xff1a;activate 不加环境名是直接进入到base环境中的 必须先进入到base环境中再使用后边的命令 &#xff1a; activate 直接进入base环境&#xff1a;如图&#xff1a;conda create -n 名字 python3.7 创建虚拟…

善用Embedding,我们来给文本分分类

你好&#xff0c;我是徐文浩。 上一讲里我们看到大模型的确有效。在进行情感分析的时候&#xff0c;我们通过OpenAI的API拿到的Embedding&#xff0c;比T5-base这样单机可以运行的小模型&#xff0c;效果还是好很多的。 不过&#xff0c;我们之前选用的问题的确有点太简单了。…

springboot服务端接口外网远程调试,并实现HTTP服务监听 - 内网穿透

文章目录前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统2.2 创建隧道映射本地端口2.3 测试公网地址3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址4. …

segment anything paper笔记

demo主页&#xff08;包含paper, demo, dataset&#xff09; 通过demo可以看到一个酷炫的效果&#xff0c;鼠标放在任何物体上都能实时分割出来。 segment anything宣传的是一个类似BERT的基础类模型&#xff0c;可以在下游任务中不需要再训练&#xff0c;直接用的效果。 而且…

增强领域的知识图谱

以下是一些近两年基于知识图谱做知识增强的顶会论文&#xff1a; "knowledge-enhanced hierarchical graph convolutional networks for intent detection" (acl 2021) "kg-bert: bert for knowledge graph completion" (emnlp 2019) "k-adapter: i…

C语言刷题--内存存储、操作符

魔王的介绍&#xff1a;&#x1f636;‍&#x1f32b;️一名双非本科大一小白。魔王的目标&#xff1a;&#x1f92f;努力赶上周围卷王的脚步。魔王的主页&#xff1a;&#x1f525;&#x1f525;&#x1f525;大魔王.&#x1f525;&#x1f525;&#x1f525; ❤️‍&#x1…

04-Mysql常用操作

1. DDL 常见数据库操作 # 查询所有数据库 show databases; # 查询当前数据库 select databases();# 使用数据库 use 数据库名;# 创建数据库 create database [if not exits] 数据库名; # []代表可选可不选# 删除数据库 drop database [if exits] 数据库名; 常见表操作 创建…

Nestjs实战干货-概况-中间件-Middleware

中间件 中间件是一个在路由处理程序之前被调用的函数。中间件函数可以访问请求和响应对象&#xff0c;以及应用程序的请求-响应周期中的next()中间件函数。下一个中间件函数通常由一个名为next的变量来表示。 Nest 中间件在默认情况下等同于Express中间件。下面是来自官方 exp…

MBD—模型的回调函数

目录 前面 如何设置&#xff1f; 应用 简单的提示 数据的初始化 前面 常用的回调函数有三类&#xff1a;模型的回调函数、模块的回调函数、信号的回调函数。这里分享一下模型的回调函数。 回调函数就是CallBack. 如何设置&#xff1f; 打开一个模型&#xff0c;在空白…

【计算机网络】TCP拥塞控制、丢包重传机制与滑动窗口机制

文章目录TCP 拥塞控制原理为什么拥塞期间&#xff0c;发送方会收到接收方的重复确认&#xff1f;TCP 滑动窗口机制原理TCP 丢包重传机制TCP 拥塞控制原理 TCP拥塞控制是指在网络拥塞的情况下&#xff0c;TCP协议通过调整发送数据的速率来避免网络拥塞的一种机制。TCP拥塞控制的…

物料分类视图:200 和 300 分类测试记录

一、概述 测试目的&#xff1a;将销售订单中成品对原材料的需求&#xff0c;通过MRP运行&#xff0c;传递到生产订单中 系统版本&#xff1a;S4 工厂代码&#xff1a;1001(计划工厂) 、1008(执行工厂) 成品: CP0000535 原材料&#xff1a; 编码 描述 板材特性 123…

国内 中 大 型 IT 软件 外包公司 名单 汇总(2023 最新版!)

文章目录***\*1、软件外包公司名单\*******\*2、如何区分是否是外包公司\*******\*3、外包公司真是无一是处吗&#xff1f;\*******\*4、软件外包的几种形式\*******\*5、哪些情况可选择外包\****结语1、软件外包公司名单2、如何区分是否是外包公司3、外包公司真是无一是处吗&a…

【Transformer系列(1)】encoder(编码器)和decoder(解码器)

前言 这个专栏我们开始学习transformer&#xff0c;自推出以来transformer在深度学习中占有重要地位&#xff0c;不仅在NLP领域&#xff0c;在CV领域中也被广泛应用&#xff0c;尤其是2021年&#xff0c;transformer在CV领域可谓大杀四方。 在论文的学习之前&#xff0c;我们…

【C++】类和对象—日期类的实现

目录一、日期类的功能二、获取月的天数三、Date类中的默认成员函数构造函数析构函数拷贝构造赋值运算符重载取地址操作符重载和const取地址操作符重载四、运算符重载&#x1f312;、、-、-日期天数日期天数日期-天数日期-天数&#x1f312;、!、>、>、<、<日期-日期…

C++ :websocket 通讯下的五种 I/O 模型

目录 I/O 多路复用&#xff08;一种同步 I/O 模型&#xff09; 非阻塞与阻塞 select、poll、epoll 起因 改善 select 与 poll 的差别 I/O 模型 阻塞 I/O 模型 非阻塞 I/O 模型 I/O 多路复用模型 信号驱动 I/O 模型&#xff08;SIGIO&#xff09; 异步 I/O 模型&…