7.物联网操作系统互斥信号量

1.使用互斥信号量解决信号量导致的优先级反转,

2.使用递归互斥信号量解决互斥信号量导致的死锁。

3.高优先级主函数中多次使用同一信号量的使用,使用递归互斥信号量,但要注意每个信号量的使用要对应一个释放

优先级翻转问题

优先级翻转功能需求

优先级翻转功能实现

一。实验:优先级翻转问题

1.优先级翻转的解释

(1)有三个任务,一个任务L优先级最低,一个任务M优先级为中间,一个任务H优先级为最高。

(2)刚开始任务L在运行,并且L占用信号量

(3)H任务突然开始运行,抢占L任务,但是由于信号量由L占有,所以进入堵塞状态,CPU继续运行L任务。

(4)M任务突然开始运行,抢占M任务,M任务不需要信号量,所以需要等运行完毕CPU才会分配给L。

(5)L不需要占用临界资源后,释放信号量。H任务由堵塞态变为就绪态,抢占L,运行H。

2.功能需求

  • 新建三个任务,优先级分别为中高低

  • 新建二值信号量,用于模拟优先级翻转

  • 低优先级任务获取信号量后,被中优先级打断,中优先级任务执行时间较长,因为低优先级任务还未释放信号量,高优先级任务就无法获取信号量继续
    实现方法:

1.低优先级

(1)获取二值信号量(2)循环释放CPU使用权(3)释放二值信号量(4)系统延时500ms

2.高优先级业务流程

(1)获取二值信号量(2)释放二值信号量(3)系统延迟500ms

API:taskYIELD

3.cubemx创建工程

(1)创建一个高优先级的任务

(2)建一个二值信号量

3.步骤:

(1)低优先级

使用二值信号量,与高优先级使用的二值信号量是同一个。与高优先级相比,多了一个释放CPU权限的函数(taskYIELD())。

复制代码
	printf("Low Task Take sem\n");
	  //二值信号量的使用
	  if(xSemaphoreTake(PrBinarySemHandle,portMAX_DELAY)==pdPASS){
		  printf("Low Task is Running\n");
	  }
	  for(i=0;i<2000000;i++){
		  //释放cpu
		  taskYIELD();
	  }
	  //二值信号量的释放
	  printf("Low Task Give Sem\n");
	  xSemaphoreGive(PrBinarySemHandle);
	  osDelay(500);

(2)中优先级

不做特殊处理,就是直接打印

(3)高优先级

与低优先级一起使用一个二值信号量

复制代码
	  printf("High Task Take sem\n");
	  if(xSemaphoreTake(PrBinarySemHandle,portMAX_DELAY)==pdPASS){
		  printf("High Task is running\n");
	  }
	  xSemaphoreGive(PrBinarySemHandle);
	  printf("High Task Give Sem\n");
    osDelay(500);

结果:

二。互斥信号量概念及其应用《解决上述出现的问题:优先级反转问题》

互斥信号量定义

FreeRTOS互斥信号量介绍

FreeRTOS互斥信号量工作原理

1.互斥信号量的定义

短暂提升低优先级的优先级,让他优先完成。

任务都有一个互斥锁

2.FreeRTOS互斥信号量介绍

Mutex包括Mutex与RecursiveMutex(递归信号量解决普通信号量的死锁问题)

3.FreeRTOS互斥信号量工作原理

短暂提升低优先级的优先级,让他优先完成。

3.递归互斥信号量解决死锁问题

多次使用foo()函数会导致死锁,信号量重复使用,任务把自己挂起。

解决方法:递归互斥信号量

三。实验:互斥信号量函数应用

1.功能需求

1、修改优先级翻转实验(优化代码)

2、使用互斥信号量,解决优先级翻转问题

2.API

(1)xSemaphoreCreateMutex()创建互斥信号量

(2)xSemaphoreGetMutexHolder()获取当前信号量任务句柄

3.cubemx创建工程

(1)使能互斥信号量

(2)创建互斥信号量

3.步骤:

把优先级反转的二值信号量,改为互斥信号量,就可以解决优先级反转的问题

替代地方:

(1)低优先级信号量使用与释放处

(2)高优先级信号量使用与释放处

(1)低优先级二值信号量句柄的使用与释放修改为互斥信号量的使用与释放。

修改为

(2)高优先级一样

结果:大量时间用来运行高优先级的任务,正确。

四。实验:递归互斥信号量函数应用

1.死锁现象

上述的互斥信号量如果在同一个任务的主函数中运行两次互斥信号量的使用,会导致任务把自身挂起,即:死锁。

为了解决死锁的问题,使用递归互斥信号量。

2.API

(1)xSemaphoreCreateRecursiveMutex()

(2) xSemaphoreTakeRecursive()

(3)xSemaphoreGiveRecursive()

3.实验验证

需求:

1、模拟死锁现象

2、使用递归互斥信号量解决死锁问题

4.cubemx创建工程

(1)递归互斥信号量的使能

(2)创建递归互斥信号量

5.步骤

1.使用上述的API接口,创建与释放的递归信号量接口(FREERTOS的参考手册有详细讲解函数的使用,不过是英文)

2.使用自己创建的递归信号量

(1)创建出来的递归互斥信号量

(2)高优先级:如果直接使用互斥信号量,这样使用两次会导致死锁,使用递归互斥信号量就会解决此类问题。

复制代码
	  //递归互斥信号量改为自己设置的信号量
      printf("High Task Take sem1\n");
	  if(xSemaphoreTakeRecursive(myRecursiveMutexHandle,portMAX_DELAY)==pdPASS){
		  printf("High Task is running1\n");
	  }
	  printf("High Task Take sem2\n");
	  if(xSemaphoreTakeRecursive(myRecursiveMutexHandle,portMAX_DELAY)==pdPASS){
		  printf("High Task is running2\n");
	  }
	  xSemaphoreGiveRecursive(myRecursiveMutexHandle);
	  printf("High Task Give Sem1\n");
	  xSemaphoreGiveRecursive(myRecursiveMutexHandle);
	  printf("High Task Give Sem2\n");
    osDelay(500);

(3)低优先级,注意:使用与高优先级一样的信号量

结果:高优先级占用CPU比率大,正确

五。互斥信号量实现原理

相关推荐
天一生水water38 分钟前
什么是调压器的P2s
linux·服务器·网络
风中凌乱1 小时前
ftp服务的安装与部署
linux·服务器
赖small强1 小时前
【Linux驱动开发】Linux Input子系统架构深度解析
linux·驱动开发·input·按键驱动·libinput
hero_heart1 小时前
ubuntu 密码重置(不用系统盘)
linux·运维·ubuntu
2301_816073832 小时前
SELinux 学习笔记
linux·运维·前端
Ronin3052 小时前
【Linux网络】传输层协议UDP
linux·网络·udp·传输层
ycydynq3 小时前
python html 解析的一些写法
linux·python·html
知识分享小能手3 小时前
openEuler入门学习教程,从入门到精通,openEuler 24.03 中的 Vim 编辑器 —— 全面知识点详解(7)
linux·vim·openeuler
TDengine (老段)3 小时前
TDengine 字符串函数 REGEXP_IN_SET 用户手册
数据库·物联网·mysql·时序数据库·tdengine·涛思数据
LCG元3 小时前
Linux 性能监控三板斧:top/vmstat/iostat 快速入门
linux