网站模板 黑白/快速收录工具
这里写目录标题
- 一、信号量的简介(了解)
- 二、二值信号量(熟悉)
- 三、二值信号量实验(掌握)
- 四、计数型信号量(熟悉)
- 五、计数型信号量实验(掌握)
- 六、优先级翻转简介(熟悉)
- 七、优先级翻转实验(掌握)
- 八、互斥信号量(熟悉)
- 九、互斥信号量实验(掌握)
一、信号量的简介(了解)
信号量是一种解决同步问题的机制,可以实现对共享资源的有序访问
假设有一个人需要在停车场停车
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 )
三、二值信号量实验(掌握)
1、实验目的:学习 FreeRTOS 的二值信号量相关API函数的使用
2、实验设计:将设计三个任务:start_task、task1、task2
三个任务的功能如下:
QueueHandle_t semphore_handle;
/*** @brief FreeRTOS例程入口函数* @param 无* @retval 无*/
void freertos_demo(void)
{ semphore_handle = xSemaphoreCreateBinary();if(semphore_handle != NULL){printf("二值信号量创建成功!!!\r\n");}xTaskCreate((TaskFunction_t ) start_task,(char * ) "start_task",(configSTACK_DEPTH_TYPE ) START_TASK_STACK_SIZE,(void * ) NULL,(UBaseType_t ) START_TASK_PRIO,(TaskHandle_t * ) &start_task_handler );vTaskStartScheduler();
}/* 任务一,释放二值信号量 */
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");}else printf("信号量释放失败!!\r\n");}}vTaskDelay(10);}
}/* 任务二,获取二值信号量 */
void task2( void * pvParameters )
{uint32_t i = 0;BaseType_t err;while(1){err = xSemaphoreTake(semphore_handle,portMAX_DELAY); /* 获取信号量并死等 */if(err == pdTRUE){printf("获取信号量成功\r\n");}else printf("已超时%d\r\n",++i);}
}
四、计数型信号量(熟悉)
计数型信号量相当于队列长度大于1 的队列,因此计数型信号量能够容纳多个资源,这在计数型信号量被创建的时候确定的
计数型信号量适用场合:
事件计数:当每次事件发生后,在事件处理函数中释放计数型信号量(计数值+1),其他任务会获取计数型信号量(计数值-1) ,这种场合一般在创建时将初始计数值设置为 0
资源管理:信号量表示有效的资源数目。任务必须先获取信号量(信号量计数值-1 )才能获取资源控制权。当计数值减为零时表示没有的资源。当任务使用完资源后,必须释放信号量(信号量计数值+1)。信号量创建时计数值应等于最大资源数目
使用计数型信号量的过程:创建计数型信号量 、释放信号量 、获取信号量
计数型信号量的释放和获取与二值信号量相同 !
计数型信号量创建API函数
#define xSemaphoreCreateCounting( uxMaxCount , uxInitialCount ) \ xQueueCreateCountingSemaphore( ( uxMaxCount ) , ( uxInitialCount ) )
此函数用于创建一个计数型信号量 。
#define uxSemaphoreGetCount( xSemaphore ) \ uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
此函数用于获取信号量当前计数值大小
五、计数型信号量实验(掌握)
1、实验目的:学习 FreeRTOS 的计数型信号量相关API函数的使用
2、实验设计:将设计三个任务:start_task、task1、task2
三个任务的功能如下:
QueueHandle_t count_semphore_handle;
/*** @brief FreeRTOS例程入口函数* @param 无* @retval 无*/
void freertos_demo(void)
{ count_semphore_handle = xSemaphoreCreateCounting(100 , 0); /* 创建计数型信号量 */if(count_semphore_handle != NULL){printf("计数型信号量创建成功!!!\r\n");}xTaskCreate((TaskFunction_t ) start_task,(char * ) "start_task",(configSTACK_DEPTH_TYPE ) START_TASK_STACK_SIZE,(void * ) NULL,(UBaseType_t ) START_TASK_PRIO,(TaskHandle_t * ) &start_task_handler );vTaskStartScheduler();
}
/* 任务一,释放计数型信号量 */
void task1( void * pvParameters )
{uint8_t key = 0;while(1) {key = key_scan(0);if(key == KEY0_PRES){if(count_semphore_handle != NULL){xSemaphoreGive(count_semphore_handle); /* 释放信号量 */}}vTaskDelay(10);}
}/* 任务二,获取计数型信号量 */
void task2( void * pvParameters )
{BaseType_t err = 0;while(1){err = xSemaphoreTake(count_semphore_handle,portMAX_DELAY); /* 获取信号量并死等 */if(err == pdTRUE){printf("信号量的计数值为:%d\r\n",(int)uxSemaphoreGetCount(count_semphore_handle));}vTaskDelay(1000);}
}
六、优先级翻转简介(熟悉)
优先级翻转:高优先级的任务反而慢执行,低优先级的任务反而优先执行
优先级翻转在抢占式内核中是非常常见的,但是在实时操作系统中是不允许出现优先级翻转的,因为优先级翻转会破坏任务的预期顺序,可能会导致未知的严重后果。
在使用二值信号量的时候,经常会遇到优先级翻转的问题。
举个例子:
高优先级任务被低优先级任务阻塞,导致高优先级任务迟迟得不到调度。但其他中等优先级的任务却能抢到CPU资源。从现象上看,就像是中优先级的任务比高优先级任务具有更高的优先权(即优先级翻转)
七、优先级翻转实验(掌握)
1、实验目的:在使用二值信号量的时候会存在优先级翻转的问题,本实验通过模拟的方式实现优先级翻转,观察优先级翻转对抢占式内核的影响
2、实验设计:将设计四个任务:start_task、high_task、 middle_task , low_task
四个任务的功能如下:
QueueHandle_t semphore_handle;
/*** @brief FreeRTOS例程入口函数* @param 无* @retval 无*/
void freertos_demo(void)
{ semphore_handle = xSemaphoreCreateBinary();if(semphore_handle != NULL){printf("二值信号量创建成功!!!\r\n");}xSemaphoreGive(semphore_handle); /* 释放一次信号量 */xTaskCreate((TaskFunction_t ) start_task,(char * ) "start_task",(configSTACK_DEPTH_TYPE ) START_TASK_STACK_SIZE,(void * ) NULL,(UBaseType_t ) START_TASK_PRIO,(TaskHandle_t * ) &start_task_handler );vTaskStartScheduler();
}/* 任务一,低优先级任务 */
void low_task( void * pvParameters )
{while(1) {printf("low_task获取信号量\r\n");xSemaphoreTake(semphore_handle,portMAX_DELAY);printf("low_task正在运行!!!\r\n");delay_ms(3000);printf("low_task释放信号量\r\n");xSemaphoreGive(semphore_handle); vTaskDelay(1000);}
}/* 任务二,中优先级任务 */
void middle_task( void * pvParameters )
{while(1){printf("middle_task正在运行!!!\r\n");vTaskDelay(1000);}
}/* 任务三,高优先级任务 */
void high_task( void * pvParameters )
{while(1){printf("high_task获取信号量\r\n");xSemaphoreTake(semphore_handle,portMAX_DELAY);printf("high_task正在运行!!!\r\n");delay_ms(1000);printf("high_task释放信号量\r\n");xSemaphoreGive(semphore_handle); vTaskDelay(1000);}
}
八、互斥信号量(熟悉)
互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中!
优先级继承:当一个互斥信号量正在被一个低优先级的任务持有时, 如果此时有个高优先级的任务也尝试获取这个互斥信号量,那么这个高优先级的任务就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级。
优先级继承示例
此时任务H的阻塞时间仅仅是任务L 的执行时间,将优先级翻转的危害降到了最低
优先级继承并不能完全的消除优先级翻转的问题,它只是尽可能的降低优先级翻转带来的影响
注意:互斥信号量不能用于中断服务函数中,原因如下:
(1) 互斥信号量有任务优先级继承的机制, 但是中断不是任务,没有任务优先级, 所以互斥信号量只能用与任务中,不能用于中断服务函数。
(2) 中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态。
互斥信号量相关API函数(熟悉)
使用互斥信号量:首先将宏configUSE_MUTEXES置1
使用流程:创建互斥信号量 、(task)获取信号量 、(give)释放信号量
互斥信号量的释放和获取函数与二值信号量相同 !只不过互斥信号量不支持中断中调用
注意:创建互斥信号量时,会主动释放一次信号量
互斥信号量创建API函数
#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
此函数用于创建互斥信号量
九、互斥信号量实验(掌握)
1、实验目的:在优先级翻转实验的基础,加入互斥信号量,解决优先级翻转问题
2、实验设计:将优先级翻转所用到的信号量函数,修改成互斥信号量即可,通过串口打印提示信息
QueueHandle_t mutex_semphore_handle;
/*** @brief FreeRTOS例程入口函数* @param 无* @retval 无*/
void freertos_demo(void)
{ mutex_semphore_handle = xSemaphoreCreateMutex(); /* 创建互斥信号量,并且主动释放一次信号量 */if(mutex_semphore_handle != NULL){printf("互斥信号量创建成功!!!\r\n");}xTaskCreate((TaskFunction_t ) start_task,(char * ) "start_task",(configSTACK_DEPTH_TYPE ) START_TASK_STACK_SIZE,(void * ) NULL,(UBaseType_t ) START_TASK_PRIO,(TaskHandle_t * ) &start_task_handler );vTaskStartScheduler();
}/* 任务一,低优先级任务 */
void low_task( void * pvParameters )
{while(1) {printf("low_task获取信号量\r\n");xSemaphoreTake(mutex_semphore_handle,portMAX_DELAY);printf("low_task正在运行!!!\r\n");delay_ms(3000);printf("low_task释放信号量\r\n");xSemaphoreGive(mutex_semphore_handle); vTaskDelay(1000);}
}/* 任务二,中优先级任务 */
void middle_task( void * pvParameters )
{while(1){printf("middle_task正在运行!!!\r\n");vTaskDelay(1000);}
}/* 任务三,高优先级任务 */
void high_task( void * pvParameters )
{while(1){printf("high_task获取信号量\r\n");xSemaphoreTake(mutex_semphore_handle,portMAX_DELAY);printf("high_task正在运行!!!\r\n");delay_ms(1000);printf("high_task释放信号量\r\n");xSemaphoreGive(mutex_semphore_handle); vTaskDelay(1000);}
}
相关文章:

【正点原子FreeRTOS学习笔记】————(12)信号量
这里写目录标题 一、信号量的简介(了解)二、二值信号量(熟悉)三、二值信号量实验(掌握)四、计数型信号量(熟悉)五、计数型信号量实验(掌握)六、优先级翻转简介…...

【数据分享】1929-2023年全球站点的逐年平均露点(Shp\Excel\免费获取)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 有关气象指标的监测站点数据,之前我们分享过1929-2023年全球气象站…...

PHP+MySQL开发组合:智慧同城便民信息小程序源码系统 带完整的安装代码包以及安装部署教程
当前,城市生活的节奏日益加快,人们对各类便民信息的需求也愈发迫切。无论是寻找家政服务、二手交易,还是发布租房、求职信息,一个高效、便捷的信息平台显得尤为重要。传统的信息发布方式往往存在信息更新不及时、查找困难等问题&a…...

Linux相关命令(1)
1、找出文件夹下包含 “aaa” 同时不包含 “bbb”的文件,然后把他们重新生成一下。要求只能用一行命令。 find ./ -type f -name "*aaa*" ! -name "*bbb*" -exec touch {} \;文件系统操作命令 df:列出文件系统的整体磁盘使用情况 …...

NO9 蓝桥杯单片机实践之串口通信的使用
1 回顾 串口通信的代码编写结构还是与中断一样,不同的是: 初始中断函数条件涉及到串口通信相关的寄存器和定时器1相关的寄存器(定时器1用于产生波特率),但初始条件中的中断寄存器只考虑串口通信而不考虑定时器1。 vo…...

数据库管理-第163期 19c重建ADG的两个方法(20240323
数据库管理163期 2024-03-23 数据库管理-第163期 19c重建ADG的两个方法(20240323)1 ORA-081032 新办法1 关闭MRP2 恢复备库3 其他操作4 启动备库5 启动MRP 3 老办法4 预告总结 数据库管理-第163期 19c重建ADG的两个方法(20240323)…...

8款常见的自动化测试开源框架
在如今开源的时代,我们就不要再闭门造车了,热烈的拥抱开源吧!本文针对性能测试、Web UI 测试、API 测试、数据库测试、接口测试、单元测试等方面,为大家整理了github或码云上优秀的自动化测试开源项目,希望能给大家带来…...

【QT】:基本框架
基本框架 一.创建程序二.初识函数1.main2.Widget.h3.Wight.cpp4.Wight.ui5.文件名.pro 三.生成的中间文件 本系列的Qt均使用Qt Creator进行程序编写。 一.创建程序 二.初识函数 1.main 2.Widget.h 3.Wight.cpp 4.Wight.ui 此时再点击编辑,就看到了ui文件的本体了。…...

【Python】定时更换clashx工具
An empty street An empty house A hole inside my heart I’m all alone The rooms are getting smaller I wonder how I wonder why I wonder where they are The days we had The songs we sang together Oh yeah And oh, my love I’m holding on forever Reaching for a l…...

2024年第16届大广赛新命题发布-爱华仕箱包
2024年3月27日,2024年第16届大广赛发布了新的命题,爱华仕箱包命题,自2017年起,爱华仕箱包已连续8年担任全国大学生广告艺术大赛命题单位。 爱华仕现已实现百货、超市、电商、礼品、投标、海外市场6大零售网络的全覆盖,…...

前端理论总结(js)——闭包和内存泄漏
闭包 什么是闭包? 函数内部和函数外部连接起来的桥梁,可以在一个内层函数中访问到其外层函数的作用域 为什么要用 封装变量 收敛权限 临时变量持久化 优点 1.保护函数内的变量安全 2.在内存中维持一个变量(用的太多就变成了缺点,…...

PHP页面如何实现设置独立访问密码
PHP网页如果需要查看信息必须输入密码,验证后才可显示出内容的代码如何实现? 对某些php页面设置单独的访问密码,如果密码不正确则无法查看内容,相当于对页面进行了一个加密。 如何实现这个效果,详细教程可以参考:PHP页面如何实现…...

M1 mac安装 Parallels Desktop 18 激活
M1 mac安装 Parallels Desktop 18 激活 下载安装Parallels Desktop 18.1.1 (53328) 激活1. 拷贝prl_disp_service2. 在终端打开Crack所在位置3. 输入命令,激活成功 下载 安装包和激活文件下载地址 链接: https://pan.baidu.com/s/1EjT7xeEDcntIIoOvvhBDfg?pwd9pue …...

嵌入式学习46——硬件相关2串口通信
串口: 端口: COM 波特率: 9600 115200 (bps) 每秒传输的数据…...

企业产品网络安全建设日志3月20
今天主要以下几个事情 确定了OCI当前情况下,更新某安全配置会导致链接中断 这问题说大不大,说小不小。 由此引申出各云服务器产品的完善度: AWS>OCI>其他 国内一些安全公司提供的WAF功能,缺点在于其全球的…...

BRICK POP展示了有趣的链上游戏玩法与奖励
新游戏BRICK POP将Sui区块链技术与低Gas费用,以及我们在Web3游戏开发方面的专业知识无缝结合。通过充分利用Sui和我们自己的INNO平台的优势,BRICK POP为玩家提供了一个融合了前沿技术和引人入胜游戏的沉浸式游戏体验。BRICK POP游戏设计为实时交易和高用…...

jetcache 2级缓存模式实现批量清除
需求 希望能够实现清理指定对象缓存的方法,例如缓存了User表,当User表巨大时,通过id全量去清理不现实,耗费资源也巨大。因此需要能够支持清理指定本地和远程缓存的批量方法。 分析 查看jetcache生成的cache接口,并没…...

【MD】激光驱动原子动力学的全尺寸从头算模拟
Zeng Q, Chen B, Zhang S, et al. Full-scale ab initio simulations of laser-driven atomistic dynamics[J]. npj Computational Materials, 2023, 9(1): 213.核心研究内容: 本文研究了激光驱动的原子动力学的全尺度从头算模拟。研究的重点是探讨在极端条件下材料…...

访问者模式(数据与行为解耦)
目录 前言 UML plantuml 类图 实战代码 SimpleFileVisitor FileVisitor 接口 删除指定文件夹 模板 IVisitor IVisitable Client 前言 一个类由成员变量和方法组成,成员变量即是类的数据结构,方法则是类的行为。 如果一个类的数据结构稳定&am…...

LeetCode:1319. 连通网络的操作次数(并查集 Java)
目录 1319. 连通网络的操作次数 题目描述: 实现代码与解析: 并查集 原理思路: 1319. 连通网络的操作次数 题目描述: 用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示…...

C++ STL教程
C STL教程 文章目录 C STL教程1.1 std::vector1.1.1vector的定义1.1.2vector容器的初始化1.1.3vector容器内元素的访问和修改1.1.4vector中的常用函数 1.2 std::string1.2.1string的定义1.2.2string的初始化1.2.3string中元素的访问和修改1.2.4string中连接字符串1.2.5string中…...

系列学习前端之第 6 章:一文掌握 jQuery(熟悉即可)
前言:为什么说 jQuery 熟悉即可,已日渐过时? 作为前端开发中常用的两个库或框架:Vue.js 和 jQuery。不少开发者想要学习 Vue.js 时,都会有一个疑惑:学习 Vue.js 是否一定要学习 jQuery? 从几个…...

python 中判断文件、目录是否存在的方法
判断目录是否存在并创建目录 一、实现上传文件功能二、判断目录是否存在的办法2.1、使用os模块2.1.1、判断目录是否存在2.1.2、os.makedirs():递归创建目录 2.2、使用pathlib模块2.2.1、path.exist()判断目录是否存在2.2.1、path.mkdir():创建目录 2.3、…...

Redis的安装与启动
一、Linux环境安装&启动Redis 1. 安装步骤 第一步:在官网下载好Redis安装包,上传到Linux中并进行解压到相应(如/opt/software/)目录中;(注意:完成了第二步后,即安装了C/C语言…...

WebGIS航线编辑器(无人机航线规划)
无人机航点、航线规划,实现全自动航点飞行作业及飞行航拍。禁飞区、作业区功能保障飞行安全。 GIS引擎加载 const viewer new Cesium.Viewer("cesiumContainer", { imageryProvider: new Cesium.IonImageryProvider({ assetId: 3872 }), }); const im…...

STEP 格式三维模型读取
STEP是常用的三维模型存储格式,使用Express语言描述几何图形,文件存储方式为BRep,分为STEP203和STEP214,后者多了颜色信息,opencascade中提供了相应算法读取STEP文件。 #include <STEPControl_Reader.hxx>TopoD…...

Mora: Enabling Generalist Video Generation via A Multi-Agent Framework
目录 论文地址:Mora: Enabling Generalist Video Generation viaA Multi-Agent Framework github地址:https://github.com/lichao-sun/Mora 一、摘要 (1)Mora 的主要特点: (2)Mora的应用场景…...

[c++] 自写 MyString 类
实现了 MyString 类,同时实现了运算符重载,重载的运算符包括 <、>、、!、<<、>>、[] 等。 如果一个类重载了某个运算符,那么对这个类的对象进行操作的时候便会使用类重载的运算符。比如下边代码 MyString 类中重载了 <、…...

三、阅读器开发--4、阅读器目录、全文搜索功能开发
1、阅读器目录 1.1、实现目录 先实现目录的布局 定义一个蒙版,充满整个屏幕浮在阅读器上方,左侧为目录右侧为背景,目录下方包含一个tab,点击后会切换不同的内容,这里tab是目录、书签,这里可以通过如下的…...

AMEYA360代理 | 江苏长晶科技FST2.0高性能 IGBT产品介绍
江苏长晶科技股份有限公司是一家专业从事半导体产品研发、生产和销售的企业。自2019年起,连续4年被中国半导体行业协会评为 “功率器件十强企业”。2021年开始自主研发有着“工业CPU”之称的IGBT,截至2023年Q3在家电/工业/新能源等行业实现8款产品市场应…...