FreeRTOS二值信号量

目录

一、信号量的概念

1、信号量的基本概念

2、信号量的分类

二、二值信号量简介

三、二值信号量相关API

1、创建二值信号量

2、释放二值信号量

3、获取二值信号量

四、二值信号量实操

1、实验需求

2、CubeMX配置

3、代码实现


一、信号量的概念

1、信号量的基本概念

信号量(Semaphore),是在多任务环境下使用的一种机制,是可以用来保证两个或多个关键代 码段不被并发调用。

信号量这个名字,我们可以把它拆分来看,信号可以起到通知信号的作用,然后我们的量还可以 用来表示资源的数量,当我们的量只有0和1的时候,它就可以被称作二值信号量,只有两个状 态,当我们的那个量没有限制的时候,它就可以被称作为计数型信号量

信号量也是队列的一种

2、信号量的分类

二值信号量(同步应用)

计数信号量(资源管理)

互斥信号量(互斥访问)

递归互斥信号量(简要了解即可)

二、二值信号量简介

二值信号量其实就是一个长度为1,大小为零的队列只有0和1两种状态,通常情况下,我们用它来进行互斥访问或任务同步

互斥访问:比如门跟钥匙,只有获取到钥匙才可以开门

任务同步:比如学习完知识点才能写博客

三、二值信号量相关API

函数描述
xSemaphoreCreateBinary()使用动态方式创建二值信号量
xSemaphoreCreateBinaryStatic()使用静态方式创建二值信号量
xSemaphoreGive()释放信号量
xSemaphoreGiveFromISR()在中断中释放信号量
xSemaphoreTake()获取信号量
xSemaphoreTakeFromISR()在中断中获取信号量

1、创建二值信号量

SemaphoreHandle_t xSemaphoreCreateBinary( void );

参数:

返回值:

  • 成功,返回对应二值信号量的句柄;
  • 失败,返回 NULL 。

2、释放二值信号量

BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );

参数:

  • xSemaphore:要释放的信号量句柄

返回值:

  • 成功,返回 pdPASS ;
  • 失败,返回 errQUEUE_FULL 。

3、获取二值信号量

BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore,
                    TickType_t xTicksToWait );

参数:

  • xSemaphore:要获取的信号量句柄
  • xTicksToWait:超时时间,0 表示不超时,portMAX_DELAY表示卡死等待;

返回值:

  • 成功,返回 pdPASS ;
  • 失败,返回 errQUEUE_FULL 。

四、二值信号量实操

1、实验需求

创建一个二值信号量,按下 KEY1 则释放信号量,按下 KEY2 获取信号量。

2、CubeMX配置

这里已经将FreeRTOS移植到STM32F103C8T6,具体操作流程看前面的文章。

 查看原理图配置按键引脚

这里已经将FreeRTOS移植到STM32F103C8T6,具体操作流程看前面的文章。

创建两个任务用来放入和获取信号量

创建一个二值信号量

3、代码实现

uart.c 重定向printf

#include "stdio.h"
int fputc(int ch,FILE *f)
{
	unsigned char temp[1] = {ch};
	HAL_UART_Transmit(&huart1,temp,1,0xffff);
	return ch;
}

需要打开魔术棒勾上红框内选项实现串口打印

打开freertos.c并添加代码

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

可见释放二值信号量后便可以成功获取获取二值信号量,但是只能释放多次就只有第一次能释放成功,同时获取也是只能获取一次(前提是已经释放),多次获取也只有第一次能获取成功

注意:

  1. 创建后的二值信号量原先代码和修改后的代码如下:由于CubeMX内置函数中存在bug,即在创建二值信号量时就已经释放二值信号量,所以会出现不按下KEY1(释放二值信号量)时,按下KEY2就直接能获取二值信号量,如下:
  2. 若将获取二值信号量函数的第二个参数修改成卡斯等待,即portMAX_DELAY,如下
    xSemaphoreTake(myBinarySemHandle, portMAX_DELAY )

    那么会出现在没释放二值信号量前按下KEY2(获取二值信号量),那么会一直卡死等待释放二值信号量,当KEY1一按下,二值信号量会被立马获取,此时就不存在二值信号量,当KEY1再次按下时,还是会释放成功,如下:

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

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

相关文章

使用 CloudFlare 后如何才能不影响搜索引擎蜘蛛爬虫

今天,明月给大家再次详细讲解一下,明月在使用 CloudFlare 后如何才能不影响搜索引擎蜘蛛爬虫对站点的抓取,因为这是很多首次使用 CloudFlare 的站长们容易忽略和触犯的问题,并不是 CloudFlare 不友好,而是 CloudFlare 的防火墙(WAF)实在是太给力。其实在【CloudFlare 如…

IDEA及Maven配置代理及Maven中央仓库配置详解

一、配置代理 首先,需要本地开启代理入口,如图。 这个跟你使用代理软件有关。像我使用的是qv2ray。 其次,idea配置代理,如图。 1.1 idea配置代理 打开Settings,如图 1.2 maven配置代理 maven配置代理,修…

2024湖南理工学院程序设计竞赛(同步赛) G. 区间递减(思维题 分类讨论 ST表)

题目 https://ac.nowcoder.com/acm/contest/82672/G 思路来源 出题人 涼風青葉7代码 题解 注意到三种情况即可, 第一种情况,10 9 8 1 2,保留1 第二种情况,6 5 10 9 4 4,保留5 4 4 第三种情况,6 5 4&…

基于Springboot的校园疫情防控管理系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的校园疫情防控管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系…

Python 整数类型(int)详解:无限范围与多种进制

引言 在编程中,整数是最基本的数据类型之一。不同编程语言对整数的处理方式各不相同,这往往影响到程序的性能和开发者的选择。本文将深入探讨 Python 中的整数类型(int),其独特的处理方式,以及它在日常编程…

【数据结构】环状链表OJ题

✨✨✨专栏:数据结构 🧑‍🎓个人主页:SWsunlight 一、OJ 环形链表: 快慢指针即可解决问题: 2情况: 快指针走到结尾(不是环)快指针和尾指针相遇(是环的) …

C语言——文件缓冲区

一、用户缓冲区和系统缓冲区 缓冲区的概念确实可以分为多个层次,其中最常见的两个层次是用户缓冲区和系统缓冲区。 这里的用户缓冲区和系统缓冲区都包括输入输出缓冲区。 1、用户缓冲区(User-space Buffer) 用户缓冲区是指由用户程序&…

09.zabbix自定义模块并使用

zabbix自定义模块并使用 根据tcp的11中状态获取值,进行批量配置监控项 [rootyunlong66 ~]# cat /etc/zabbix/zabbix_agentd.d/tcp.conf UserParameterESTABLISHED,netstat -antp |grep -c ESTABLISHED UserParameterSYN_SENT,netstat -antp |grep -c SYN_SENT Use…

免费思维13招之七:空间型思维

免费思维13招之七:空间型思维 本篇给你带来的是空间型思维。 空间型思维,具体分为内部空间型思维和外部空间型思维。 什么叫内部空间型思维呢? 内部空间型就是充分利用现有空间或资源为社会提供免费服务,积累人气,增加流量,从而带动消费。 为什么你生意不好?为什么你…

银河麒麟服务器操作系统扩展磁盘容量方法(非LVM)

此方法的使用场景为:对普通的分区扩容,分区格式为xfs,不适用于lvm逻辑卷的扩容。 注意:扩展磁盘空间的操作风险较高,最好先做好备份,或在实验环境下操作成功后,再对目标系统进行扩容操作&#…

当代 Qt 正确的 安装方法 及 多版本切换

此文写于 20240511 首先去网站Index of /official_releases/online_installers下载一个安装器 安装器有什么用? 可以浏览安装版本 安装组件 安装器版本越能 能装的东西越多 现在只能选Qt5 和 Qt6 至于你公司用的Qt4 我也没招 见招时再拆招 安装器 默认国外源 可以换国内…

栈的讲解

栈的概念及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底(因为先进后出)。栈中的数据元素遵守后进先出LIFO(Last In Firs…

18 【Aseprite 作图】工具栏介绍

1 在没有输入法的情况下, 按住Shift 大写的N,就可以快速新建图层 ctrl z 撤回这个图层 2 双击图层,可以修改图层名称和属性 3 按住图层,拖动图层,可以把图层拉到 组,就可以方便一组一组管理图层 4 保存的…

Redis—图文详解高可用原因

本文不会讲解Redis的用途,关于用途会发另一片文章讲解,本文主要讲的是高可用的原理。 Redis高可用主要有以下三个原因:主从模式(上一篇讲Kafka的文章里有涉及到),哨兵模式,Redis-Cluster(Redis集群)。 什么是主从模式…

消息队列——Kafka

1、什么是消息队列,什么是Kafka? 我们通常说的消息队列,简称MQ(Message Queue),它其实就指消息中间件,比较流行的开源消息中间件有:Kafka、RabbitMQ、RocketMQ等。今天我们要介绍的…

基于yolov8+gradio目标检测演示系统设计

YOLOv8与Gradio:开启目标检测的可视化新篇章 随着人工智能技术的飞速发展,目标检测作为计算机视觉领域的重要分支,已经广泛应用于安防监控、自动驾驶、医疗影像等多个领域。而YOLO(You Only Look Once)系列算法作为目…

(七)SQL基础知识练习题(选择题)(上)#CDA学习打卡

本文整理了SQL基础知识相关的练习题,共133道,可作为CDA一级的补充习题,也适用于刚入门初级SQL想巩固基础的同学。来源:如荷学数据科学题库(技术专项-SQL)。暂时按照原题库顺序present,如有需要之…

网安面经之文件包含漏洞

一、文件包含漏洞 1、文件包含漏洞原理?危害?修复? 原理:开发⼈员⼀般希望代码更灵活,所以将被包含的⽂件设置为变量,⽤来进⾏动态调⽤,但是由于⽂件包含函数加载的参数没有经过过滤或者严格的…

巩固学习6

正则表达式 又称规则表达式,Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a到z之间的字母)和特殊字符(称为“元字符”&…

基于Springboot的村庄果园预售系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的村庄果园预售系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构…