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随手笔记---轮播图(点击切换)
💌 所属专栏:【JavaScript随手笔记】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &#…...
机器人学 markdown数学公式常用语法
参考链接1 本文包含了markdown常用的数学公式,按照目录可查询选用 初始类 行内数学公式均用两个符号包裹行间数学公式均用两个符号包裹 行间数学公式均用两个符号包裹行间数学公式均用两个符号包裹,用于表示重要的、需在行间单独列出的公式 $行内数学…...
如何使用 Python 语言来编码和解码 JSON 对象
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写。 JSON 函数 使用 JSON 函数需要导入 json 库:import json。 函数 描述 json.dumps 将 Python 对象编码成 JSON 字符串 json.loads 将已编码的 JSON 字符串解码为 Pyth…...
【蓝桥云课】求正整数的约数个数
一、求正整数n的约数个数 方法一(常用算法):从1到n逐一判断其能否整除n,若能整除n即为n的约数,否则不是n的约数。 方法二:从1到n\sqrt{n}n逐一判断是否为n的约数,当n\sqrt{n}n为n的约数时,个数加1&…...
刷题记录: wannafly25 E 牛客NC19469 01串 [线段树维护动态dp]
传送门:牛客 题目描述: Bieber拥有一个长度为n的01 串,他每次会选出这个串的一个子串作为曲谱唱歌,考虑该子串从左 往右读所组成的二进制数P。 Bieber每一秒歌唱可以让P增加或减少 2 的 k次方(k由Bieber选 定),但必须…...

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

WRAN翻译
基于小波的图像超分辨残差注意力网络 Wavelet-based residual attention network for image super-resolution 代码: https://github.com/xueshengke/WRANSR-keras 摘要: 图像超分辨率技术是图像处理和计算机视觉领域的一项基础技术。近年来,…...
ROS学习笔记——第二章 ROS通信机制
主要跟着[1]学习ros::Rate r(1); //错误,应改为ros::Rate r(10);[2]对Topic通信打的比方很形象,便于理解记忆。[3]有整个过程的图片,对于初学者更加友好[4]对发布者的代码注释非常好,方便进一步学习此外CMake官方文档可以查询相关…...

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

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

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

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

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

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

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

MySQL优化篇-MySQL压力测试
备注:测试数据库版本为MySQL 8.0 MySQL压力测试概述 为什么压力测试很重要?因为压力测试是唯一方便有效的、可以学习系统在给定的工作负载下会发生什么的方法。压力测试可以观察系统在不同压力下的行为,评估系统的容量,掌握哪些是重要的变化…...
CF43A Football 题解
CF43A Football 题解题目链接字面描述题面翻译题面描述题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2代码实现题目 链接 https://www.luogu.com.cn/problem/CF43A 字面描述 题面翻译 题面描述 两只足球队比赛,现给你进…...

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

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

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...