当前位置: 首页 > news >正文

14_FreeRTOS二值信号量

目录

信号量的简介

队列与信号量的对比

二值信号量

二值信号量相关API函数

实验源码


信号量的简介

信号量是一种解决同步问题的机制,可以实现对共享资源的有序访问

假设有一个人需要在停车场停车

1.首先判断停车场是否还有空车位(判断信号量是否有资源)

2.停车场正好有空车位(信号量有资源),那么就可以直接将车开入空车位进行停车(获取信号量成功) ;

3.停车场已经没有空车位了(信号量没有资源) ,那么这个人可以选择不停车(获取信号量失败) ;也可以选择等待(任务阻塞)其他人将车开出停车场(释放信号量资源),然后再将车停入空车位。

空车位:可以理解为信号量资源数(计数值)

让出占用车位:释放信号量(计数值++)

占用车位:获取信号量(计数值--)

当计数值大于0,代表有信号量资源

当释放信号量,信号量计数值(资源数)加一

当获取信号量,信号量计数值(资源数)减一

信号量:用于传递状态

信号量的计数值都有限制:限定最大值。

如果最大值被限定为1,那么它就是二值信号量;

如果最大值不是1,它就是计数型信号量。

队列与信号量的对比

 

 

二值信号量

二值信号量的本质是一个队列长度为1的队列,该队列就只有空和满两种情况,这就是二值。

二值信号量通常用于互斥访问或任务同步,与互斥信号量比较类似,但是二值信号量有可能会导致优先级翻转的问题,所以二值信号量更适合用于同步!

二值信号量相关API函数

使用二值信号量的过程:创建二值信号量→释放二值信号量→获取二值信号量

 

创建二值信号量函数: SemaphoreHandle_t  xSemaphoreCreateBinary(void)
#define xSemaphoreCreateBinary()xQueueGenericCreate(1,semSEMAPHORE_QUEUE_ITEM_LENGTH,queueQUEUE_TYPE_BINARY_SEMAPHORE) #define semSEMAPHORE_QUEUE_ITEM_LENGTH ((uint8_t) 0U)#define queueQUEUE_TYPE_BASE  		((uint8_t) 0U)		 /*队列*/
#define queueQUEUE_TYPE_SET		((uint8_t) 0U)		 /*队列集*/
#define queueQUEUE_TYPE_MUTEX		((uint8_t) 1U)		/*互斥信号量*/
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE 	 ((uint8_t) 2U)	 /*计数型信号量*/
#define queueQUEUE_TYPE_BINARY_SEMAPHORE 	 ((uint8_t) 3U) /*二值信号量*/
#define queueQUEUE_TYPE_RECURSIVE_MUTEX		((uint8_t) 4U) 	/*递归互斥信号量*/

 

释放二值信号量函数:BaseType_t xSemaphoreGive(xSemaphore)#define xSemaphoreGive ( xSemaphore )xQueueGenericSend( (QueueHandle_t) (xSemaphore), NULL , 
semGIVE_BLOCK_TIME , queueSEND_TO_BACK)#define semGIVE_BLOCK_TIME((TickType_t) 0U)

 

 

获取二值信号量函数: BaseType_t xSemaphoreTake(xSemaphore, xBlockTime)

 

 

实验源码

将设计三个任务:start_task、task1、task2

start_task:用来创建task1和task2任务

Task1:用于按键扫描,当检测到按键KEY0被按下时,释放二值信号量

task2:获取二值信号量,当成功获取后打印提示信息

/********************************************************************************* @file           : user_mian.h* @brief          : V1.00******************************************************************************* @attention********************************************************************************//* Include 包含---------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdbool.h>
#include "user_gpio.h"
#include "user_delay.h"
#include "user_rcc_config.h"
#include "user_uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "user_key.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/*二值信号量句柄*/
QueueHandle_t semphore_handle;
/* Variables 变量--------------------------------------------------------------*/ 
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*///任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);//任务优先级
#define TASK1_PRIO			2
//任务堆栈大小	
#define TASK1_STK_SIZE 		100  
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);//任务优先级
#define TASK2_PRIO			3
//任务堆栈大小	
#define TASK2_STK_SIZE 		100  
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);int main(void){	/*配置系统中断分组为4位抢占*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);/*延时函数初始化*/delay_init();/*RCC配置*/Rcc_config();/*GPIO初始化*/ Gpio_Init();/*USART1初始化*/Uart1_Init(9600);/*创建二值信号量*/semphore_handle = xSemaphoreCreateBinary(); if(semphore_handle == NULL){printf("二值信号量创建不成功\r\n\r\n");}else{printf("二值信号量创建成功\r\n\r\n");}/*创建开始任务*/xTaskCreate((TaskFunction_t )start_task,            //任务函数(const char*    )"start_task",          //任务名称(uint16_t       )START_STK_SIZE,        //任务堆栈大小(void*          )NULL,                  //传递给任务函数的参数(UBaseType_t    )START_TASK_PRIO,       //任务优先级(TaskHandle_t*  )&StartTask_Handler);   //任务句柄              vTaskStartScheduler();          //开启任务调度}/*!\brief		开始任务函数\param[in]	传递形参,创建任务时用户自己传入\param[out]	none\retval 	none
*/
void start_task(void *pvParameters)
{taskENTER_CRITICAL();           //进入临界区//创建任务1xTaskCreate((TaskFunction_t )task1,     	(const char*    )"task1",   	(uint16_t       )TASK1_STK_SIZE, (void*          )NULL,				(UBaseType_t    )TASK1_PRIO,	(TaskHandle_t*  )&Task1_Handler);   //创建任务2xTaskCreate((TaskFunction_t )task2,     (const char*    )"task2",   (uint16_t       )TASK2_STK_SIZE, (void*          )NULL,(UBaseType_t    )TASK2_PRIO,(TaskHandle_t*  )&Task2_Handler); vTaskDelete(StartTask_Handler); //删除开始任务taskEXIT_CRITICAL();            //退出临界区
}/*!\brief		task1释放二值信号量\param[in]	传递形参,创建任务时用户自己传入\param[out]	none\retval 	none
*/
void task1(void *pvParameters)
{uint8_t key = 0;BaseType_t err;while(1){	/*获取按键值*/key = Key_Scan(0);if(key == KEY0_PRES){if(semphore_handle != NULL){	err = xSemaphoreGive(semphore_handle);if(err == pdPASS){printf("信号量释放成功\r\n\r\n");}else{printf("信号量释放失败\r\n\r\n");}}		}vTaskDelay(100);}
} /*!\brief		task2获取二值信号量\param[in]	传递形参,创建任务时用户自己传入\param[out]	none\retval 	none
*/
void task2(void *pvParameters)
{while(1){/*获取信号量死等,进入阻塞态*/xSemaphoreTake(semphore_handle,portMAX_DELAY);printf("获取信号量成功!!!\r\n\r\n");}
}/************************************************************** END OF FILE ****/

 

相关文章:

14_FreeRTOS二值信号量

目录 信号量的简介 队列与信号量的对比 二值信号量 二值信号量相关API函数 实验源码 信号量的简介 信号量是一种解决同步问题的机制,可以实现对共享资源的有序访问。 假设有一个人需要在停车场停车 1.首先判断停车场是否还有空车位(判断信号量是否有资源) 2.停车场正好…...

JavaScript随手笔记---轮播图(点击切换)

&#x1f48c; 所属专栏&#xff1a;【JavaScript随手笔记】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#…...

机器人学 markdown数学公式常用语法

参考链接1 本文包含了markdown常用的数学公式&#xff0c;按照目录可查询选用 初始类 行内数学公式均用两个符号包裹行间数学公式均用两个符号包裹 行间数学公式均用两个符号包裹行间数学公式均用两个符号包裹&#xff0c;用于表示重要的、需在行间单独列出的公式 $行内数学…...

如何使用 Python 语言来编码和解码 JSON 对象

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写。 JSON 函数 使用 JSON 函数需要导入 json 库&#xff1a;import json。 函数 描述 json.dumps 将 Python 对象编码成 JSON 字符串 json.loads 将已编码的 JSON 字符串解码为 Pyth…...

【蓝桥云课】求正整数的约数个数

一、求正整数n的约数个数 方法一(常用算法)&#xff1a;从1到n逐一判断其能否整除n&#xff0c;若能整除n即为n的约数&#xff0c;否则不是n的约数。 方法二&#xff1a;从1到n\sqrt{n}n​逐一判断是否为n的约数&#xff0c;当n\sqrt{n}n​为n的约数时&#xff0c;个数加1&…...

刷题记录: wannafly25 E 牛客NC19469 01串 [线段树维护动态dp]

传送门:牛客 题目描述: Bieber拥有一个长度为n的01 串&#xff0c;他每次会选出这个串的一个子串作为曲谱唱歌&#xff0c;考虑该子串从左 往右读所组成的二进制数P。 Bieber每一秒歌唱可以让P增加或减少 2 的 k次方&#xff08;k由Bieber选 定&#xff09;&#xff0c;但必须…...

懂九转大肠的微软New Bing 内测申请教程

最近微软的New Bing开放内测了&#xff0c;网上已经有拿到内测资格的大佬们对比了ChatGPT和New Bing。对比结果是New Bing比ChatGPT更强大。来看看具体对比例子吧 1.时效性更强 ChatGPT的库比较老&#xff0c;跟不上时事&#xff0c;比如你问它九转大肠的梗&#xff0c;ChatG…...

WRAN翻译

基于小波的图像超分辨残差注意力网络 Wavelet-based residual attention network for image super-resolution 代码&#xff1a; https://github.com/xueshengke/WRANSR-keras 摘要&#xff1a; 图像超分辨率技术是图像处理和计算机视觉领域的一项基础技术。近年来&#xff0c…...

ROS学习笔记——第二章 ROS通信机制

主要跟着[1]学习ros::Rate r(1); //错误&#xff0c;应改为ros::Rate r(10);[2]对Topic通信打的比方很形象&#xff0c;便于理解记忆。[3]有整个过程的图片&#xff0c;对于初学者更加友好[4]对发布者的代码注释非常好&#xff0c;方便进一步学习此外CMake官方文档可以查询相关…...

MacOS Pytorch 机器学习环境搭建

学习 Pytorch &#xff0c;首先要搭建好环境&#xff0c;这里将采用 Anoconda Pytorch PyCharm 来一起构建 Pytorch 学习环境。 1. Anoconda 安装与环境创建 Anoconda 官方介绍&#xff1a;提供了在一台机器上执行 Python/R 数据科学和机器学习的最简单方法。 为什么最简单…...

项目——博客系统

文章目录项目优点项目创建创建相应的目录&#xff0c;文件&#xff0c;表&#xff0c;导入前端资源实现common工具类实现拦截器验证用户登录实现统一数据返回格式实现加盐加密类实现encrypt方法实现decrypt方法实现SessionUtil类实现注册页面实现前端代码实现后端代码实现登录页…...

PHP(14)会话技术

PHP&#xff08;14&#xff09;会话技术一、概念二、分类三、cookie技术1. cookie的基本使用2. cookie的生命周期3. cookie的作用范围4. cookie的跨子域5. cookie的数组数据四、session1. session原理2. session基本使用3. session配置4. 销毁session一、概念 HTTP协议是一种无…...

对JAVA 中“指针“理解

对于Java中的指针&#xff0c;以下典型案例会让你对指针的理解更加深刻。 首先对于&#xff1a; 系统自动分配对应空间储存数字 1&#xff0c;这个空间被变量名称b所指向即: b ——> 1 变量名称 空间 明…...

功率放大器在MEMS微结构模态测试研究中的应用

实验名称&#xff1a;功率放大器在MEMS微结构模态测试研究中的应用研究方向&#xff1a;元器件测试测试目的&#xff1a;随着MEMS器件在各个领域中广泛应用&#xff0c;对微结构进行模态测试获得其动态特性参数对微结构的设计、仿真、制造、以及质量控制和评价等方面具有十分重…...

【算法基础】字典树(Trie树)

一、Trie树原理介绍 1. 基本概念 Trie 树,也叫“字典树”。顾名思义,它是一个树形结构。它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题。【高效存储和查找字符串集合的数据结构】,存储形式如下: 2. 用数组来模拟Trie树的…...

MyBatis 插件 + 注解轻松实现数据脱敏

问题在项目中需要对用户敏感数据进行脱敏处理&#xff0c;例如身份号、手机号等信息进行加密再入库。解决思路就是&#xff1a;一种最简单直接的方式&#xff0c;在所有涉及数据敏感的查询到对插入时进行密码加解密方法二&#xff1a;有方法一到出现对所有重大问题的影响&#…...

MySQL优化篇-MySQL压力测试

备注:测试数据库版本为MySQL 8.0 MySQL压力测试概述 为什么压力测试很重要&#xff1f;因为压力测试是唯一方便有效的、可以学习系统在给定的工作负载下会发生什么的方法。压力测试可以观察系统在不同压力下的行为&#xff0c;评估系统的容量&#xff0c;掌握哪些是重要的变化…...

CF43A Football 题解

CF43A Football 题解题目链接字面描述题面翻译题面描述题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2代码实现题目 链接 https://www.luogu.com.cn/problem/CF43A 字面描述 题面翻译 题面描述 两只足球队比赛&#xff0c;现给你进…...

Nginx常用命令及具体应用(Linux系统)

目录 一、常用命令 1、查看Nginx版本命令&#xff0c;在sbin目录下 2、检查配置文件的正确性 3、启动和停止Nginx 4、查看日志&#xff0c;在logs目录下输入指令&#xff1a; 5、重新加载配置文件 二、Nginx配置文件结构 三、Nginx具体应用 1、部署静态资源 2、反向代…...

从零实现Web服务器(三):日志优化,压力测试,实战接收HTTP请求,实战响应HTTP请求

文章目录一、日志系统的运行流程1.1 异步日志和同步日志的不同点1.2 缓冲区的实现二、基于Webbench的压力测试三、HTTP请求报文解析http报文处理流程epoll相关代码服务器接收http请求四、HTTP请求报文响应一、日志系统的运行流程 步骤: 单例模式&#xff08;局部静态变量懒汉…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里

写一个shell脚本&#xff0c;把局域网内&#xff0c;把能ping通的IP和不能ping通的IP分类&#xff0c;并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...

关于疲劳分析的各种方法

疲劳寿命预测方法很多。按疲劳裂纹形成寿命预测的基本假定和控制参数&#xff0c;可分为名义应力法、局部应力一应变法、能量法、场强法等。 1名义应力法 名义应力法是以结构的名义应力为试验和寿命估算的基础&#xff0c;采用雨流法取出一个个相互独立、互不相关的应力循环&…...