STM32 CubeMX (Freertos任务通信:队列、信号量、互斥量,事件组,任务通知)第二步

STM32 CubeMX


STM32 CubeMX ____Freertos任务通信:队列、信号量、互斥量,事件组,任务通知

  • STM32 CubeMX
  • 一、STM32 CubeMX设置
    • 时钟配置
    • HAL时基选择TIM1(不要选择滴答定时器;滴答定时器留给OS系统做时基)
    • 使用STM32 CubeMX 库,配置Freertos
  • 二、实验一:消息队列
    • 消息队列是什么?适用于什么地方?
    • FreeRTOS 消息队列和数组 的几个区别:
    • 创建消息队列
    • 创建任务
    • 代码部分
    • 实验现象
  • 三,实验二:信号量
    • 信号量是什么?适用于什么地方?
    • 二值信号量
    • `代码部分`
    • 实验现象
    • 计数信号量
    • `代码部分`
    • 实验现象
  • 四,实验三:互斥量
    • 互斥量是什么?适用于什么地方?
    • `代码部分`
    • 实验现象
  • 五,实验四:事件组
  • 六,实验五:任务通知


学习使用Freertos第二步
在 FreeRTOS 中,任务通信可以通过以下函数来实现:

  1. xQueueCreate():用于创建一个消息队列。可以设置队列长度和每个消息的大小。

xQueueSend():将一条消息发送到队列中。可以选择阻塞或非阻塞发送。

xQueueReceive():从队列中接收一条消息。可以选择阻塞或非阻塞接收。

xQueuePeek():查看队列中的下一条消息,但不将其移除。

xQueueReset():清空队列中的所有消息。
2. xQueueSemaphoreTake()xQueueSemaphoreGive():用于实现二值信号量,控制任务之间的互斥访问。
3. xSemaphoreCreateMutex():创建一个互斥信号量,用于实现任务之间的互斥访问。
4. xTaskNotify()ulTaskNotifyTake():用于任务间的通知机制,一个任务可以通知另一个任务进行某种操作。
5. xEventGroupCreate()、xEventGroupSetBits()和xEventGroupWaitBits():用于创建、设置和等待事件标志组。

一、STM32 CubeMX设置

时钟配置

在这里插入图片描述

HAL时基选择TIM1(不要选择滴答定时器;滴答定时器留给OS系统做时基)

在这里插入图片描述

使用STM32 CubeMX 库,配置Freertos

选择CMISS_V1接口就可以满足Freertos接口;且代码量比CMISS_V2小(CMISS_V2支持更多的RTOS接口,所以代码量比CMISS_V1多)
在这里插入图片描述

二、实验一:消息队列

消息队列是什么?适用于什么地方?

  • 数据传递:消息队列允许任务之间传递数据,一个任务可以将数据打包成消息发送到队列,另一个任务则可以从队列中接收该消息并处理其中的数据。这使得任务之间可以方便地进行数据交换和共享。
  • 任务解耦:通过使用消息队列,任务之间的耦合度可以降低。一个任务只需要关注发送和接收消息,而不需要知道消息的具体处理细节和目标任务的实现。这样,当需要更改或替换某个任务时,只需要保证消息的格式和接口不变即可,不会对其他任务产生影响。
  • 同步与协作:消息队列可以用于实现任务之间的同步和协作。例如,一个任务可以等待某个特定的消息到达队列后才继续执行,从而实现任务间的同步。另外,多个任务可以通过发送和接收消息来协调彼此的执行顺序和操作。
  • 缓冲和调节:消息队列可以充当缓冲区,用于存储一定数量的消息。当发送方发送消息速度较快,而接收方处理速度较慢时,消息队列可以暂时存储未处理的消息,避免数据丢失。同时,消息队列还可以调节发送和接收任务之间的速度差异,以平衡任务负载。

FreeRTOS 消息队列和数组 的几个区别:

  • 数据组织方式:消息队列是一种先进先出(FIFO)的数据结构,用于存储和传递消息。每个消息都可以包含不同类型和长度的数据。而数组是一种线性的、连续的数据结构,用于存储相同类型和长度的元素。
  • 功能和用途:消息队列主要用于任务间通信,允许任务之间传递数据和进行同步。它提供了数据传递、解耦、同步和协作等功能。而数组通常用于存储一组具有相同类型的元素,可以进行遍历、访问和修改等操作。
  • 大小和容量:消息队列的大小是可以动态调整的,可以根据需要增加或减少队列的容量。而数组的大小在创建时就确定,并且通常是固定的。
  • 可用性和效率:消息队列可以实现多个任务之间的并发通信,提供了较高的可用性和灵活性。而数组通常在单个任务内进行操作,具有较高的效率和直接性
  • 总的来说,消息队列和数组是两种不同的数据结构,适用于不同的场景和需求。消息队列主要用于任务间通信和数据传递,具有灵活性和可调节性;而数组主要用于存储相同类型的元素,并进行遍历和访问操作。选择使用哪种数据结构取决于具体的应用需求和功能要求。

创建消息队列

在这里插入图片描述

  • Queue Name: 队列名称
  • Queue Size: 队列能够存储的最大单元数目,即队列深度
  • Queue Size: 队列中数据单元的长度,以字节为单位
  • Allocation: 分配方式:Dynamic 动态内存创建
  • Buffer Name: 缓冲区名称
  • Buffer Size: 缓冲区大小
  • Conrol Block Name: 控制块名称

创建任务

在这里插入图片描述

  • Task Name: 任务名称
  • Priority: 优先级,在 FreeRTOS 中,数值越大优先级越高,0 代表最低优先级
  • Stack Size (Words): 堆栈大小,单位为字,在32位处理器(STM32),一个字等于4字节,如果传入128那么任务大小为128*4字节
  • Entry Function: 入口函数
  • Code Generation Option: 代码生成选项
  • Parameter: 任务入口函数形参,不用的时候配置为0或NULL即可
  • Allocation: 分配方式:Dynamic 动态内存创建
  • Buffer Name: 缓冲区名称
  • Conrol Block Name: 控制块名称

代码部分

void sendTask1(void const * argument)
{
  /* USER CODE BEGIN sendTask1 */
	BaseType_t xsatus;
	uint32_t buff=9600;
  /* Infinite loop */
  for(;;)
  {
      xsatus=xQueueSendToBack(myQueue01Handle,&buff,0);
			 if( xsatus!=pdPASS)
			 {
			 printf("输入失败\r\n");		// printf输出字符串
			 }
			 else
			 {
			 printf("成功写入%d\r\n", buff);		// printf输出字符串
			 }
			 osDelay(1000);
  }
  /* USER CODE END sendTask1 */
}
void readTask3(void const * argument)
{
  /* USER CODE BEGIN readTask3 */
  BaseType_t xsatus;
	uint32_t buff=115200;
  /* Infinite loop */
  for(;;)
  {
      xsatus=xQueueReceive(myQueue01Handle,&buff,0);
		  if( xsatus!=pdPASS)
			 {
			 printf("读取失败\r\n");		// printf输出字符串
			 }
			 else
			 {
			 printf("成功读取%d\r\n", buff);		// printf输出字符串
			 }
			  osDelay(3000);
  }
  /* USER CODE END readTask3 */
}

实验现象

在这里插入图片描述

 
			 xsatus=xQueueSendToBack(myQueue01Handle,&buff,portMAX_DELAY);//一直等待
			 if( xsatus!=pdPASS)
			 {
			 printf("输入失败\r\n");		// printf输出字符串
			 }
			 else
			 {
			 printf("成功写入%d\r\n", buff);		// printf输出字符串
			 }

还一种方式:读取不会删除信息(偷窥信息)

三,实验二:信号量

信号量是什么?适用于什么地方?

FreeRTOS中的信号量是一种用于任务间同步和资源共享的机制。它可以用来实现任务之间的互斥访问共享资源,或者在某个任务等待某个事件发生时进行阻塞。

FreeRTOS提供了两种类型的信号量:二进制信号量(Binary Semaphore)和计数信号量(Counting Semaphore)。

二进制信号量是一种简单的信号量,只有两种状态:空闲和占用。当一个任务获取到二进制信号量时,它就可以继续执行,而其他任务则会被阻塞。当任务释放二进制信号量时,其他任务可以获取到它并继续执行。

计数信号量是一种更复杂的信号量,它可以有多个资源可供获取。计数信号量可以用来实现资源池的管理,例如限制同时访问某个资源的任务数量

在FreeRTOS中,可以使用以下函数来创建和操作信号量:

  • xSemaphoreCreateBinary(): 创建二进制信号量。
  • xSemaphoreCreateCounting(): 创建计数信号量。
  • xSemaphoreTake(): 获取一个信号量。
  • xSemaphoreGive(): 释放一个信号量。

需要注意的是,使用信号量时要确保正确的获取和释放顺序,以避免出现死锁或资源竞争的问题。

二值信号量

创建信号量
在这里插入图片描述

代码部分

void sendTask1(void const * argument)
{
  /* USER CODE BEGIN sendTask1 */
	BaseType_t xsatus;
	uint32_t buff=9600;
  /* Infinite loop */
  for(;;)
  {
		
       if( xSemaphoreTake(myBinarySem01Handle,portMAX_DELAY)!=pdPASS)
			 {
			  printf("刷新失败#信号量获取失败\r\n");		// printf输出字符串
			 }
			 else
			 {
			  printf("成功刷新#信号量获取成功\r\n");		// printf输出字符串
			 }
	
			 osDelay(2000);
  }
  /* USER CODE END sendTask1 */
}
void readTask3(void const * argument)
{
  /* USER CODE BEGIN readTask3 */
  BaseType_t xsatus;
	uint32_t buff=115200;
  /* Infinite loop */
  for(;;)
  {
  
		 	 if( xSemaphoreGive(myBinarySem01Handle)!=pdPASS)
			 {
			  printf("读取失败#信号量不能释放\r\n");		// printf输出字符串
			 }
			 else
			 {
			  printf("成功读取#信号量已经释放\r\n");		// printf输出字符串
			 }
			  osDelay(1000);
  }
  /* USER CODE END readTask3 */
}

实验现象

在这里插入图片描述

计数信号量

创建计数信号量
在这里插入图片描述
在这里插入图片描述

代码部分

void sendTask1(void const * argument)
{
  /* USER CODE BEGIN sendTask1 */
	BaseType_t xsatus;
	uint32_t buff=9600;
  /* Infinite loop */
  for(;;)
  {
		
       if( xSemaphoreGive(myCountingSem01Handle)!=pdTRUE)
			 {
			  printf("停车已满\r\n");		// printf输出字符串
			 }
			 else
			 {
			  printf("停车成功\r\n");		// printf输出字符串
			 }
			 osDelay(2000);
  }
  /* USER CODE END sendTask1 */
}
void readTask3(void const * argument)
{
  /* USER CODE BEGIN readTask3 */
  BaseType_t xsatus;
	uint32_t buff=115200;
  /* Infinite loop */
  for(;;)
  {
  
		 	 if( xSemaphoreTake(myCountingSem01Handle,0)!=pdTRUE)
			 {
			  printf("无车\r\n");		// printf输出字符串
			 }
			 else
			 {
			   printf("取走车\r\n");		// printf输出字符串
			 }
			  osDelay(1000);
  }
  /* USER CODE END readTask3 */
}

实验现象

在这里插入图片描述

四,实验三:互斥量

互斥量是什么?适用于什么地方?

FreeRTOS中的互斥量(Mutex)是一种用于保护共享资源的同步机制。它可以确保在任何给定时刻只有一个任务可以访问被保护资源,以避免竞争条件和数据损坏。

在FreeRTOS中,互斥量通过以下API函数进行创建、获取和释放:

  • xSemaphoreCreateMutex():用于创建一个互斥量,并返回一个指向该互斥量的句柄。
  • xSemaphoreTake():用于获取(锁定)互斥量。如果互斥量当前未被锁定,则任务可以 获取互斥量并继续执行;否则,任务将被阻塞,直到互斥量可用。
  • xSemaphoreGive():用于释放(解锁)互斥量。一旦任务完成了对共享资源的访问,应该调用此函数来释放互斥量,以允许其他任务获取它。
    创建互斥量
    在这里插入图片描述

代码部分

void sendTask1(void const * argument)
{
  /* USER CODE BEGIN sendTask1 */
	BaseType_t xsatus;
	uint32_t buff=9600;
  /* Infinite loop */
  for(;;)
  {
		 osDelay(20);
       if(xSemaphoreTake(myMutex01Handle,portMAX_DELAY)!=pdTRUE)
			 {
			   printf("1号:你上完厕所,下一个就轮到我了\r\n");		// printf输出字符串
			 }
			 else
			 {
			   printf("1号:现在是我在上厕所\r\n");		// printf输出字符串
				 xSemaphoreGive(myMutex01Handle);
	       printf("1号:我上完了\r\n");		// printf输出字符串
			 }	
			 osDelay(2000);
  }
  /* USER CODE END sendTask1 */
}

/* USER CODE BEGIN Header_sendTask2 */
/**
* @brief Function implementing the Task2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_sendTask2 */
void sendTask2(void const * argument)
{
  /* USER CODE BEGIN sendTask2 */
	BaseType_t xsatus;
	uint32_t buff=115200;
  /* Infinite loop */
  for(;;)
  {
     xSemaphoreTake(myMutex01Handle,0); 
     printf("2号:我在厕所\r\n");		// printf输出字符串
	   osDelay(3000);
     printf("2号:我上完了\r\n");		// printf输出字符串
	   xSemaphoreGive(myMutex01Handle);
     osDelay(2000);
	}
  /* USER CODE END sendTask2 */
}

/* USER CODE BEGIN Header_readTask3 */
/**
* @brief Function implementing the read thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_readTask3 */
void readTask3(void const * argument)
{
  /* USER CODE BEGIN readTask3 */
  BaseType_t xsatus;
	uint32_t buff=115200;
  /* Infinite loop */
  for(;;)
  {
      if(xSemaphoreTake(myMutex01Handle,0)!=pdTRUE)
			 {
			   printf("3号:厕所有人,等一会儿再来\r\n");		// printf输出字符串
			 }
			 else
			 {
			    printf("3号:到我上小便了\r\n");		// printf输出字符串
	        printf("3号:我撒完尿了\r\n");		// printf输出字符串
				  xSemaphoreGive(myMutex01Handle);
			 }	 
			  osDelay(1000);
  }
  /* USER CODE END readTask3 */
}

实验现象

在这里插入图片描述

五,实验四:事件组

六,实验五:任务通知

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【STM32+ESP8266上云连载①】给ESP8266烧录AT固件

文章目录 一、给NodeMCU烧录固件1.1硬件准备1.2软件准备1.3AT固件下载1.4配置设置1.5开始烧录 二、给ESP8266-01S烧录固件2.1硬件准备2.2AT固件下载2.3连线2.4烧录配置 三、给ESP-12E/F/S单片烧录固件四、指令测试4.1HTTP测试4.2MQTT测试 我在使用ESP8266的时候遇到了一些问题&…

智能仓储管理系统(自动化仓库管理解决方案)

企业实际的仓储管理中,往往会出现那样这样的错误,归根结底,主要是由于没使用合适的仓库管理工具。相反,人工使用合适的仓库管理工具,不仅可以在日常仓库管理方法中根据采集到的产品信息数据,大大地提高管理…

vue3学习笔记(一)

一、API风格 Vue 的组件可以按两种不同的风格书写:选项式 API 和组合式 API。 二、组合式API 1.(组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量,并将从多个函数中得到的状态组合起来处理复杂问题。这种形式更加自由&#x…

vue项目根据word模版导出word文件

一、安装依赖 //1、docxtemplaternpm install docxtemplater pizzip -S//2、jszip-utilsnpm install jszip-utils -S//3、pizzipnpm install pizzip -S//4、FileSaver npm install file-saver --save二、创建word模版 也就是编辑一个word文档,文档中需要动态取值的…

用 React+ts 实现无缝滚动的走马灯

一、走马灯的作用 走马灯是一种常见的网页交互组件,可以展示多张图片或者内容,通过自动播放或者手动切换的方式,让用户能够方便地浏览多张图片或者内容。 本次实现的不是轮播图而是像传送带一样的无限滚动的形式。 二、需求梳理 走马灯可设…

大数据培训前景怎么样?企业需求量大吗

大数据行业对大家来说并不陌生,大数据行业市场人才需求量大,越早入行越有优势,发展机会和上升空间等大。不少人通过大数据培训来提升自己的经验和自身技术能力,以此来获得更好的就业机会。 2023大数据培训就业前景怎么样呢?企业需…

034_小驰私房菜_[问题复盘] Qcom平台,某些三方相机拍照旋转90度

全网最具价值的Android Camera开发学习系列资料~ 作者:8年Android Camera开发,从Camera app一直做到Hal和驱动~ 欢迎订阅,相信能扩展你的知识面,提升个人能力~ 【一、问题】 某些三方相机,预览正常,拍照旋转90度 【二、问题排查】 1 ) HAL这边Jpeg编码数据在哪个地方…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的固定帧率(C++)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的固定帧率(C) Baumer工业相机Baumer工业相机的固定帧率功能的技术背景CameraExplorer如何查看相机固定帧率功能在BGAPI SDK里通过函数设置相机固定帧率 Baumer工业相机通过BGAPI SDK设置相机固定帧…

Python发送QQ邮件

使用Python的smtplib可以发送QQ邮件,代码如下 #!/usr/bin/python3 import smtplib from email.mime.text import MIMEText from email.header import Headersender 111qq.com # 发送邮箱 receivers [222qq.com] # 接收邮箱 auth_code "abc" # 授权…

大数据-玩转数据-Flink RedisSink

一、添加Redis Connector依赖 具体版本根据实际情况确定 <dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-redis_2.11</artifactId><version>1.1.5</version> </dependency>二、启动redis 参…

两个案例熟悉String的基本操作

1、第一个案例 Java语言规范要求完全相同的字符串字面量&#xff0c;应该包含同样的Unicode字符序列&#xff08;包含同一份码点序列的常量&#xff09;&#xff0c;并且必须是指向同一个String类实例。 package string; public class StringTest4 {public static void main(St…

AutoSAR系列讲解(深入篇)13.3-Mcal Dio配置

目录 一、Dio port配置 二、Dio pin配置 一、Dio port配置 同之前的Port一样,双击进入Dio配置界面后会看到几乎差不多的配置界面。General和Port类似,我们不再赘述,主要讲解Dio的配置 1. 其实Dio并没有什么实质的作用,主要起到了一个重命名的功能。双击DioConfig_0进入下…

文本图片怎么转Excel?分享一些好用的方法

在处理数据时&#xff0c;Excel 是一个非常强大的工具&#xff0c;但有时候需要将文本和图片转换为 Excel 格式&#xff0c;这可能会让人感到困惑。在本文中&#xff0c;我们将介绍一些好用的方法&#xff0c;以便您能够轻松地将文本和图片转换成 Excel 格式。 将文本图片为Exc…

高性能本地缓存Ristretto(四)—— NumCounters 与 MaxCost参数的设置

ristretto 参数 我在使用ristretto时&#xff0c;对于参数的设置有些疑问。主要是 NumCounters &#xff0c;MaxCost 分别表示什么含义&#xff0c;以及如何确定其数值的问题。 在此记录并分享一下&#xff0c;欢迎各位批评指正&#xff0c;谢谢 官方的指导 先看一下官方的…

前端开发,怎么解决浏览器兼容性问题? - 易智编译EaseEditing

解决浏览器兼容性问题是前端开发中常见的挑战之一。不同的浏览器可能对网页元素的渲染和功能支持有所不同&#xff0c;因此需要采取一些策略来确保您的网页在不同浏览器上都能正常运行和呈现。以下是一些解决浏览器兼容性问题的方法和策略&#xff1a; 使用CSS Reset&#xff…

MMdetection在VisDrone2019上训练FCOS和CenterNet

配置环境 Python 3.5>PyTorch 1.1>CUDA 9.0NCCL 2>GCC 4.9mmcv‘’ 把mmdetection的代码下载下来 git clone https://github.com/open-mmlab/mmdetection.git进入这个mmdetection文件,准备编译mmdetection的文件 cd mmdetection 装一下下面这些包&#xff0c; #…

idea cannot download sources 解决方法

问题 点击class文件右上角下载源码失败 解决方案 找到idea terminal 控制台cd 至maven工程执行 mvn dependency:resolve -Dclassifiersources

ElasticSearch相关概念

1、概述 先说Elasticsearch的文件存储&#xff0c;Elasticsearch是面向文档型数据库&#xff0c;一条数据在这里就是一个文档&#xff0c;用JSON作为文档序列化的格式&#xff0c;比如下面这条用户数据&#xff1a; {"name" : "John","sex"…

web连接桌面打开gptmap

一&#xff1a;环境配置 需要的材料&#xff1a; python-3.10.4 我使用的是这个版本的&#xff0c;3.8.10 该版本和以下版本组件组合&#xff0c;验证过能正常运行&#xff08;python 3.6.8测试异常&#xff09; websockify 该项目有python版本和node js版本 noVNC 形式的app…

Android-网络访问技术Retrofit浅析

Retrofit是一种基于注解的网络请求库&#xff0c;专门用于在Android应用中进行网络访问。它使用简洁的方式定义了网络请求的接口&#xff0c;并自动将请求结果解析为Java对象。Retrofit的核心原理是利用了Java的动态代理技术&#xff0c;将网络请求接口的注解信息转化为具体的网…