队列与二值信号量、计数型信号量

【FreeRTOS】07 二值信号量、计数信号量 本节开始讲freeRTOS的信号量,先从最基本的二值信号量讲起,后面会讲解计数信号量,最后是信号量与临界段保护的区别。 阅读详情

一、队列简介:队列也称为消息队列,是一种用于消息间进行通信的数据结构,队列可以用于任务与任务之间、中断与任务之间传递消息,队列通常采用先进先出(FIFO)的数据缓冲机制。

二、队列常见的API函数

1.创建队列

2.写队列

 3.读队列

 三、实验操作

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

CubeMX配置信息:

 创建队列,CubeMX已经封装好了,和原始的函数有点差别:

 StartTaskSend函数:

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(1);
  }
 
}

 StartTaskRecive函数:

void StartTaskRecive(void const * argument)
{
 
		uint16_t buf ;
	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(1);
  }
  
}

 实验结果:通过按键1按三次,写入值三次;按按键2三次,读出值3次,按第四次读取失败。

二值信号量

一、信号量(Semaphore)

是在多任务环境下使用的一种机制,是可以用来保证两个或多个关键代码段不被并发调用。信号量这个名字,我们可以把它拆分来看,信号可以起到通知信号的作用,然后我们的量还可以用来表示资源的数量,当我们的量只有0和1的时候,它就可以被称作二值信号量,只有两个状态,当我们的那个量没有限制的时候,它就可以被称作为计数型信号量。信号量也是队列的一种。
二值信号量:二值信号量是一个长度为1,大小为0的队列,只有0和1两种状态,通常情况下,用来就行互斥访问或任务同步。互斥访问:比如获取了门钥匙,只有获取了钥匙才能开门。
二、二值信号量相关API函数

 

 

 

三、二值信号量实验

需求:创建一个二值信号量,按下KEY1释放信号量,按下KEY2获取信号量

1.cubeMX配置:释放(give)和获取(get)二值信号量,生成代码

 

注意: cubeMX生成的myBinaryHanle需要注释掉,使用xSemaphoreCreateBinary();

 2.释放二值信号量和获取二值信号量

void StartTaskGive(void const * argument)
{
 
  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)
				{	
				if(xSemaphoreGive(myBinaryHandle) == pdTRUE)
					printf("二值信号量放入成功\r\n");
					else
						printf("二值信号量放入失败\r\n");
			}
				while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET);
		}
    osDelay(1);
  }

}
void StartTaskTake(void const * argument)
{

  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)
				{	
				if(xSemaphoreTake(myBinaryHandle,portMAX_DELAY) == pdTRUE)//portMAX_DELAY表示卡死等待,0表示不超时
					printf("二值信号量获取成功\r\n");
					else
						printf("二值信号量获取失败\r\n");
			}
				while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==GPIO_PIN_RESET);
		}
    osDelay(10);
  }

}

实验结果:当为portMAX_DELAY(死等),可以先点击获取信号量在放入

 BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait );

当TickType_t xTicksToWait=0时,必须放一次信号量,拿一次信号量。

 

计数型信号量

一:定义:

计数型信号量相当于队列长度大于1 的队列,因此计数型信号量能够容纳多个资源,这在计数型
信号量被创建的时候确定的。

二、相关API函数

 配置cubeMX,需要将USE_COUNTING_SEMAPHORES打开成Enable,注释掉cubeMX生成的创建信号量函数,改用xSemaphoreCreateCounting()。

 

 

三、代码

void StartTaskGive(void const * argument)
{

  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)
				{	
				if(xSemaphoreGive(CountingSem01Handle) == pdTRUE)
					printf("计数型信号量放入成功\r\n");
					else
						printf("计数型信号量放入失败\r\n");
			}
				while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET);
		}
    osDelay(1);
  }

void StartTaskTake(void const * argument)
{

  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)
				{	
				if(xSemaphoreTake(CountingSem01Handle,0) == pdTRUE)
					printf("计数型信号量获取成功\r\n");
					else
						printf("计数型信号量获取失败\r\n");
			}
				while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==GPIO_PIN_RESET);
		}
    osDelay(10);
  }



实验结果:

操作系统 FreeRTOS:延时函数,队列,信号量 系统延时函数 vTaskDelay()与vTaskDelayUnitl()。vTaskDelay()是相对模式(相对延时函数),函数 vTaskDelayUntil()是绝对模式(绝对延时函数)。函数 vTaskDelay()在文件 tasks.c 中有定义,要使用此函数的话宏 INCLUDE_vTaskDelay 必须为 1 相对延时函数vTaskDelay() void vTaskDelay( const TickType_t xTicksToDelay ) { BaseType_t xAlready 阅读详情

相关推荐

FreeRTOS入门教程(信号量的概念及API函数使用)

本篇文章正式带大家开始学习什么是信号量,并且掌握信号量函数的基本使用方法,并且将和队列进行一个对比。FreeRTOS 中的信号量是一种用于任务间同步和互斥的机制。它允许任务在临界区保护资源的访问、线程间通信以及任务之间的同步操作。信号量可以用来保护共享资源,限制对资源的并发访问,以及进行任务间的事件通知。本篇文章主要讲解了信号量的概念及API函数使用,大家看完后可以做个总结,并进行对应的实验。

m0_49476241的博客 1710

stm32c8t6之freertos二值信号量和计数信号量

在freertos中,信号量的作用大多是用来同步任务的。而信号量又分为4种信号量,分别是二值信号量、计数信号量、互斥量和递归信号量。这次主要是来介绍二值信号量和计数信号量。

w1256141689的博客 1385

【通俗易懂】Windows系统安装TensorRT

NVIDIA TensorRT是一个由NVIDIA公司开发的用于深度学习推理的高性能SDK。它专门设计用于在NVIDIA GPU上进行高效的神经网络推理,能够大幅度提升深度学习模型的推理速度和效率。TensorRT的主要特点包括:模型优化:TensorRT通过层融合、精度校准、动态形状等技术优化模型,减少推理时的计算量和内存占用。多精度推理:支持多种精度推理,包括FP32、FP16、INT8等,以平衡性能和精度。

王尼莫的博客 1586

FreeRTOS菜鸟入门(十一)·信号量·二值、计数、递归以及互斥信号量的区别·优先级翻转以及继承机制详解

详解信号量的基本概念,分别对二值信号量、计数信号量、互斥信号量以及递归信号量,进行详细介绍,并且对别其相互间的区别进行介绍,同时对互斥信号量的优先级翻转以及优先级继承机制进行详细描述

时光の尘的博客 2316

智能车学习日记【二】————十字和斜入十字

智能车学习日记【二】————十字和斜入十字 文章目录 智能车学习日记【二】————十字和斜入十字 前言 一、普通十字补线 二、斜入十字 1.判断是否为斜入十字和斜入十字类型 2.找斜入十字拐点 总结 前言 经过了一个多月的学习,小白的我终于也是能较稳定调出了2.8m以上的四轮车,过程中也遇到了很多困难,其中就有十字补线和斜入十字补线。尤其是斜入十字也是困扰了我快一周,现在和大家分享一下我处理斜入十字的方法(我的方法其实还有很多漏洞需要改进,仅供大家参考理解一下,欢迎各位在评论区指点出可

bsefef的博客 2740

LabVIEW实现HTTP通信

本节简要介绍HTTP通信的基础知识,并以工业物联网平台TLINK中云端设备的数据发布设计为例,阐述互联网环境下HTTP客户端应用程序设计的基本方法。重点讲解工业物联网平台TLINK中HTTP设备的创建、通信数据帧的构造与测试。

不脱发的程序猿 1543

23-二值信号量和计数信号量

在某个任务使用信号量后,互斥信号量就会变空,此时其他任务想要获取信号量,就会进入阻塞状态,保证了临界资源。每当某个事件发生的时候,任务或中断就会释放一个信号量,此时信号量的数值就会加1,当处理事件的时候,任务就会取走一个信号量,此时信号量的数值就会减去=1,信号量的数值就表示还有多少个事件没有被处理。xSemaphoreTake(),信号量获取函数(可用于二值信号量,计数信号量,互斥信号量,不能用于递归信号量的获取)在中断函数中释放信号量的时候,任务一仍然可以获得信号量,此时就是任务一和中断函数的同步。

weixin_60433980的博客 952

DFI协议时序

参数名称典型值应用场景关键影响tcmd_lat1-2个时钟周期命令与地址锁存同步地址错误风险tphy_wrlat1-2个时钟周期写操作响应速度写带宽与延迟2-3个时钟周期写操作端到端延迟系统吞吐量1-2个时钟周期连续写命令间隔信号干扰与资源冲突tphy_rdlat1-2个时钟周期读操作响应速度读带宽与延迟trddata_en由CL决定(如0.41 ns)读数据返回时间系统延迟10-20 ps写数据与命令对齐数据丢失风险<1 µs低功耗模式切换。

qq_43134430的博客 5101

学习FreeRTOS(二值信号量、计数型信号量)

信号量是用于多任务环境下的同步机制,分为二值信号量和计数型信号量。二值信号量只有0/1两种状态,用于互斥访问和任务同步;计数型信号量可容纳多个资源。文章详细介绍了两种信号量的创建(xSemaphoreCreateBinary/CreateCounting)、释放(xSemaphoreGive)和获取(xSemaphoreTake)API函数,并通过按键实验演示操作过程。实验发现:1)CubeMX生成的二值信号量默认已初始化,需修改;2)计数型信号量需手动设置初始值和最大值。当信号量达到上限时,继续操作会返回

2403_87767644的博客 1292

GibbsCAM软件二次开发:GibbsCAM软件API接口详解

API(Application Programming Interface,应用程序编程接口)是一种允许不同软件之间进行通信的接口。在GibbsCAM软件中,API提供了与外部程序交互的能力,使得开发者可以利用GibbsCAM的强大功能进行二次开发,定制化满足特定的制造需求。GibbsCAM的API主要基于.NET框架,使用C#或VB.NET等语言进行编程。在GibbsCAM软件中,通过API接口创建自定义几何形状是实现复杂零件设计和加工策略定制的关键步骤。

kkchenjj的博客 1494

基于Gurobi的综合能源系统运行优化:鲁棒两阶段优化方法

本文提出了一种基于Gurobi的综合能源系统鲁棒两阶段优化方法,针对包含换电站、光伏发电和电池储能的系统运行问题。研究采用多面体不确定性集合描述光伏出力随机性,构建了考虑电池衰减成本和弃光惩罚的两阶段优化模型:第一阶段制定日前调度计划,第二阶段处理实时运行中的不确定性。通过列与约束生成算法求解模型,并使用Python和Gurobi实现。仿真验证了该方法能有效平衡系统经济性与鲁棒性,为含高比例可再生能源的综合能源系统运行提供了实用解决方案。

huanghm88的专栏 240

在FREERTOS中,什么时候使用队列,什么时候使用二值信号量,什么时候使用计数型信号量,互斥量属于信号量吗

在FreeRTOS中,**队列**、**二值信号量**、**计数型信号量**和**互斥量**是常用的同步和通信机制。| **互斥量** | 保护共享资源 | 不支持 | 不支持 | 支持 | 支持 || **计数型信号量** | 资源管理或事件计数 | 不支持 | 支持 | 无 | 无 |信号量没有所有权,任何任务或中断都可以释放信号量。- **需要管理多个资源或事件计数**:使用**计数型信号量**。

xiaojin511025的博客 502

22、计算智能在自闭症检测与管理中的应用

本文探讨了计算智能在自闭症谱系障碍(ASD)检测与管理中的应用。在检测方面,结合可穿戴设备、传感技术与多模态数据(如眼动追踪、问卷、神经成像等),利用机器学习和深度学习算法提升诊断准确性,并介绍了多种公开数据集及研究方法。在管理方面,通过生理指标(HRV、GSR、呼吸频率)监测情绪状态,结合智能可穿戴设备与支持性应用平台(如LetMeTalk、MITA、Rethink Ed等),实现对ASD患者的实时干预与个性化支持。文章还展示了多模态筛查与管理流程的系统架构,强调未来技术整合与个性化服务的发展方向。

star的博客 91

1FreeRTOS学习(队列、二值信号量、计数型信号量之间的相同点和不同点)

队列、二值信号量、计数型信号量均可用在任务与任务,任务与中断之间进行消息传递 创建队列--发送队列--接受队列 创建二值信号量--发送二值信号量--接受二值信号量 创建计数型信号量--发送计数型信号量--接受计数型信号量 最主要的不同是队列在写队列和读队列过程中均可阻塞,信号量在释放过程中不可阻塞在获取过程中可阻塞。 二值信号量相当于队列长度为1的信号量,只有0和1两种状态 计数型信号

weixin_52448289的博客 491

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

FreeRTOS学习(五)队列与信号量

文章目录1.队列1.1 队列特性1.2 队列创建1.2.1 接口函数1.2.2 内存占用1.2.3 创建过程分析1.3 入队与出队1.3.1 队列项入队1.3.1 队列项出队2.信号量 1.队列   FreeRTOS支持多任务操作,那么任务之间以及任务与中断之间肯定需要通讯与同步,因此,继任务相关内容学习之后,下一个重要的概念就是队列。 1.1 队列特性   队列能够存储一定数目、大小固定的数据项目。因此创建队列时,需要指明数据的长度length和数据元素的大小 size。这里将队列类比成火车,长度leng

la_fe_的博客 3045

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

信号量(semaphore)

前面介绍的主要用于传输数据:任务与任务之间、任务与中断之间在有些情况下,不需要传输数据,只需要传递状态即可• 车开出停车位,你的车可以停进来了• 课已经录制完成,你可以进行观看了。

qq_68719489的博客 6995

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

07:信号量

综上:通过二值信号量来表示UART1的使用钥匙,当二值信号量为1时表示UART1使用钥匙还在信号量里面,然后Task将钥匙拿出来去使用UART1(二值信号量为0,其他Task不能使用UART1),然后UART1被使用完后,钥匙返回信号量里面,以便其他Task的使用。综上:二值信号量本质是一个长度为1的队列,但是此队列不能作为Task之间的数据传递。获取信号量,若信号量值为0,则阻塞等待,每调用一次函数,计数值-1。获取信号量,若信号量为0,则阻塞等待,获取成功后写入0。使用二值信号量需要添加如下2个代码;

qq_51284092的博客 636

计数型信号量

计数型信号量相当于队列长度大于1 的队列,因此计数型信号量能够容纳多个资源,这在计数型信号量被创建的时候确定的。

m0_74156325的博客 368

FreeRtos笔记--创建队列和信号量的区别

介绍了FreeRTOS里创建队列和信号量的步骤及创建队列与信号量的区别

xk2lj 1111

FreeRTOS信号量

def 1: 信号量是一种解决问题的机制,可以实现共享资源的访问空车位: 信号量资源(计数值)让出占用车位: 释放信号量(计数值++)占用车位:获取信号量(计数值--)当计数值大于0时,代表信号量有资源,当释放信号量,信号量计数值(资源数) + 1当获取信号量,信号量计数值(资源数) - 1,信号量处于传递状态信号量的计数值都是有限制的:限定最大值,如果最大值被限定为1,那么它就是二值信号量,如果最大值不是1,它就是计数型信号量。def 2 :队列和信号量之间的对比队列。

qq_45973003的博客 1136

(FreeRTOS专题)四、信号量与消息队列

(1)事件计数:在此使用方案中,每次事件发生时,事件处理程序将“给出”一个信号量(信号量计数值递增),并且处理程任务每次处理事件(信号量计数值递减)时“获取”一个信号量。在具体的任务调度中,当一个高优先级任务等待一个低优先级任务所持有的资源时,系统会提升低优先级任务的优先级,以避免高优先级任务长时间等待的情况。使用队列的任务和中断不在乎队列容纳的是什么——它们只想知道队列是空的还是满的。互斥信号量的获取和释放函数与二值信号量的相应函数相似,但有一个重要的区别:互斥信号量不支持在中断服务程序中直接调用。

2301_80814410的博客 740

STM32---FreeRTOS信号量

二值信号量的本质是一个队列长度为1的队列,该对列只有空和满两种情况,这就是二值信号量;信号量通常用于互斥访问或任务同步,与互斥信号量比较类似,但是二值信号量有可能会导致优先级翻转问题,所以二值信号量更适用于同步!计数型信号量:计数型信号量相当于队列长度大于1的队列,因此计数型信号量能够容纳多个资源,这在计数型信号量被创建时确定的。优先级翻转:高优先级的任务反而慢执行,低优先级的任务反而优先执行;

2301_76762351的博客 1483

队列以及信号量

信号量(Semaphore),是在多任务环境下使用的一种机制,是可以用来保证两个或多个关键代码段不被并发调用。信号量这个名字,我们可以把它拆分来看,信号可以起到通知信号的作用,然后我们的量还可以用来表示资源的数量,当我们的量只有0和1的时候,它就可以被称作二值信号量,只有两个状态,当我们的那个量没有限制的时候,它就可以被称作为计数型信号量。信号量也是队列的一种。二值信号量其实就是一个长度为1,大小为零的队列,只有0和1两种状态,通常情况下,我们用它来进行互斥访问或任务同步。

2302_80169672的博客 1141

FreeRTOS(2):队列、信号量、互斥量

信号量(Semaphore),是在多任务环境下使用的一种机制,是可以用来保证两个或多个关键代码段不被并发调用。信号量这个名字,我们可以把它拆分来看,信号可以起到通知信号的作用,然后我们的量还可以用来表示资源的数量,当我们的量只有0和1的时候,它就可以被称作二值信号量,只有两个状态,当我们的那个量没有限制的时候,它就可以被称作为计数型信号量。信号量也是队列的一种。二值信号量其实就是一个长度为1,大小为零的队列,只有0和1两种状态,通常情况下,我们用它来进行互斥访问或任务同步。

qq_73379310的博客 1258

FreeRTOS信号量本质与工程选型指南

信号量是嵌入式实时系统中实现任务同步与资源管理的基础机制,其核心原理是基于状态计数而非数据传递的轻量级队列抽象。在FreeRTOS中,所有信号量类型均构建于零长度队列之上,通过维护计数器和等待链表实现事件通知、资源配额或临界区保护。技术价值体现在确定性延迟、极小内存占用与中断安全等关键指标,广泛应用于定时器中断同步、外设资源池管理、多任务互斥访问等典型场景。理解二值信号量的状态机模型、计数型信号量的量化语义,以及互斥信号量的优先级继承机制,是规避优先级反转、信号量泄漏与误用风险的前提。

berry的博客 657
上一篇: FreeRTOS知识梳理
下一篇: 互斥量与事件标志组
CodeThinker66
博客等级 码龄7年 3粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值