十一,FreeRTOS之——互斥信号量(优先级反转,优先级继承,递归锁)

2023-05-16

声明:本专栏参考韦东山,野火,正点原子以及其他博主的FreeRTOS教程,如若侵权请告知,马上删帖致歉,个人总结,如有不对,欢迎指正。

    • 互斥量理论
      • 实验一:互斥信号量基本使用
        • 调用函数创建互斥信号量
        • 打开宏开关
        • 创建任务
        • 实验仿真
      • 实验二:优先级反转实验
        • 实验描述
        • 实验仿真
      • 实验三:优先级继承
        • 实验仿真
      • 实验四:互斥量的缺陷(可由别人释放锁)
        • 实验概述
        • 实验仿真
      • 实验五:递归锁
        • 打开宏开关
        • 主函数创建递归信号量
        • 创建任务
        • 实验仿真

互斥量理论

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

实验一:互斥信号量基本使用

互斥信号量本使用与二进制信号量无太大差别,二进制信号量需要先释放,互斥信号量不用,直接调用函数即可

调用函数创建互斥信号量

在这里插入图片描述

打开宏开关

在这里插入图片描述

创建任务

该实验任务创建与前一节二进制信号量的任务创建一样
在这里插入图片描述

实验仿真

任务交替执行

在这里插入图片描述

实验二:优先级反转实验

实验描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建三个任务,分别为Flag1_Task,Flag2_Task,Flag3_Task ,优先级分别为1,2,3

按照时序来看看任务怎么执行,首先是任务3先执行,flag3标志置1后阻塞10个tick,接着执行任务2,任务2的flag2标志置1后阻塞30个tick,接着执行任务一,任务一的flag1标志置1后获得锁,10个tick后任务三执行,flag3标志置1后也获得锁,但是此时锁没有被释放,这时候任务三就一直处于阻塞的状态,这时候任务二的阻塞时间还没有到,任务1继续执行,到40个tick后任务二执行,这时候任务2进入循环且一直没有放弃cpu资源,

实验仿真

在这里插入图片描述

实验三:优先级继承

对于上述实验二的情况,为了解决这一问题,提出了优先级继承的方法,大概是在实验二的条件下,任务三的优先级会被任务一继承,这时候任务1的优先级就是3,就可以抢占任务2
在这里插入图片描述
在这里插入图片描述

在上一个实验的基础上,只把二进制信号量改为互斥量看看会发生什么

实验仿真

在这里插入图片描述

在这里插入图片描述

实验四:互斥量的缺陷(可由别人释放锁)

互斥量的本意是,谁持有,就由谁来释放,但是在freeRTOS这里并没有实现,递归锁实现了这一意思,谁持有,就由谁来释放,先来看看这一实验

实验概述

创建三个任务,任务1与任务2共用串口资源,互斥执行,任务三来释放这个锁,在其中捣蛋
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实验仿真

任务在运行一段时间之后,由于任务三把锁释放掉了,导致错误产生

在这里插入图片描述

实验五:递归锁

在这里插入图片描述

打开宏开关

在这里插入图片描述

主函数创建递归信号量

在这里插入图片描述

创建任务

 /* 创建Flag1_Task任务 */
  xReturn = xTaskCreate((TaskFunction_t )Flag1_Task, /* 任务入口函数 */
                        (const char*    )"Flag1_Task",/* 任务名字 */
                        (uint16_t       )512,   /* 任务栈大小 */
                        (void*          )"Task 1 is running",	/* 任务入口函数参数 */
                        (UBaseType_t    )1,	    /* 任务的优先级 */
                        (TaskHandle_t*  )&Task1_Handle);/* 任务控制块指针 */
  if(pdPASS == xReturn)
    printf("创建Flag1_Task任务成功!\r\n");
	
	 /* 创建Flag2_Task任务 */
  xReturn = xTaskCreate((TaskFunction_t )Flag2_Task, /* 任务入口函数 */
                        (const char*    )"Flag2_Task",/* 任务名字 */
                        (uint16_t       )512,   /* 任务栈大小 */
                        (void*          )"Task 2 is running",	/* 任务入口函数参数 */
                        (UBaseType_t    )1,	    /* 任务的优先级 */
                        (TaskHandle_t*  )&Task2_Handle);/* 任务控制块指针 */
  if(pdPASS == xReturn)
    printf("创建Flag2_Task任务成功!\r\n");
	
	
	 /* 创建Flag3_Task任务 */
  xReturn = xTaskCreate((TaskFunction_t )Flag3_Task, /* 任务入口函数 */
                        (const char*    )"Flag3_Task",/* 任务名字 */
                        (uint16_t       )512,   /* 任务栈大小 */
                        (void*          )"Task 3 is running",	/* 任务入口函数参数 */
                        (UBaseType_t    )1,	    /* 任务的优先级 */
                        (TaskHandle_t*  )&Task3_Handle);/* 任务控制块指针 */
  if(pdPASS == xReturn)
    printf("创建Flag3_Task任务成功!\r\n");

以下代码可以看出,使用递归锁可以有效保护资源,不会被别的任务开锁

/*优先级1*/
static void Flag1_Task(void * param)
{
  
	int i;
	while (1)
	{
		xSemaphoreTakeRecursive(xSemUART, portMAX_DELAY);

		printf("%s\r\n", (char *)param);
		for (i = 0; i < 10; i++)
		{
			xSemaphoreTakeRecursive(xSemUART, portMAX_DELAY);
			printf("%s in loop %d\r\n", (char *)param, i);
			xSemaphoreGiveRecursive(xSemUART);
		}
		
		xSemaphoreGiveRecursive(xSemUART);
		vTaskDelay(1);
	}
}


/*优先级1*/
static void Flag2_Task(void * param)
{
 
	int i;
	while (1)
	{
		xSemaphoreTakeRecursive(xSemUART, portMAX_DELAY);

		printf("%s\r\n", (char *)param);
		for (i = 0; i < 10; i++)
		{
			xSemaphoreTakeRecursive(xSemUART, portMAX_DELAY);
			printf("%s in loop %d\r\n", (char *)param, i);
			xSemaphoreGiveRecursive(xSemUART);
		}
		
		xSemaphoreGiveRecursive(xSemUART);
		vTaskDelay(1);
	}
}

/*优先级1*/
static void Flag3_Task(void * param)
{
 vTaskDelay(10);
	while (1)
	{
		while (1)
		{
			if (xSemaphoreTakeRecursive(xSemUART, 0) != pdTRUE)/*如果获取锁不成功的话*/
			{
				xSemaphoreGiveRecursive(xSemUART);/*释放这个锁*/			
			}
			else/*获取成功*/
			{
				break;/*跳出循环*/
			}
		}
		printf("%s\r\n", (char *)param);/*打印……*/
		xSemaphoreGiveRecursive(xSemUART);/*释放锁*/
		vTaskDelay(1);
	}
}

实验仿真

在这里插入图片描述

git仓库源码地址:https://gitee.com/he-dejiang/free-rtos.git

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

十一,FreeRTOS之——互斥信号量(优先级反转,优先级继承,递归锁) 的相关文章

  • 【FreeRTOS 信号量】互斥信号量

    互斥信号量与二值信号量类似 但是互斥信号量可以解决二值信号量出现的优先级翻转问题 解决办法就是优先级继承 普通互斥信号量创建及运行 参阅安富莱电子demo 互斥信号量句柄 static SemaphoreHandle t xMutex NU
  • FreeRTOS简述和移植文档

    FreeRTOS简述和移植文档 文章目录 FreeRTOS简述和移植文档 1 前言 2 FreeRTOS简述 1 概述 2 实现 3 主要特色 4 支持平台 3 移植FreeRTOS 4 最后 1 前言 目前由于IOT的飞速发展 针对单片机
  • 【FreeRTOS开发问题】FreeRTOS内存溢出

    FreeRTOS内存溢出 如下图所示 FreeRTOS编译完成后可以看到 系统提示无法分配内存到堆 Objects Template axf Error L6406E No space in execution regions with A
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

    我用的是F103ZET6的板子 移植成功后 编译出现两个错误是关于stm32f10x it c 里 void SVC Handler void void PendSV Handler void 两个函数的占用问题 随后编译出现以下两个问题
  • 基于HAL库的FREERTOS-----------三.队列

    一 队列简介 在实际的应用中 常常会遇到一个任务或者中断服务需要和另外一个任务进行 沟通交流 这个 沟通交流 的过程其实就是消息传递的过程 在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式 但是如果在使用操作系统的应用中用
  • freertos————互斥锁

    线程安全 多线程程序处于一个多变的环境 可访问的全局变量和堆数据随时可能被其他的线程改变 多个线程同时访问一个共享数据 可能造成严重的后果 出现问题的是之前移植了一个freemodbus的从站 多个任务访问全局变量保持寄存器区 导致最后读出
  • FreeRTOS之软件定时器

    FreeRTOS之软件定时器 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 include sys h include delay h include usart h include led h in
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • 【FreeRTOS 事件】任务通知事件

    普通任务通知事件创建创建及运行 参阅安富莱电子demo define BIT 0 1 lt lt 0 define BIT 1 1 lt lt 1 static TaskHandle t xHandleTaskUserIF NULL sta
  • FreeRTOS笔记(二)

    FreeRTOS笔记 二 静态任务 文章目录 FreeRTOS笔记 二 静态任务 一 任务定义 二 任务创建 2 1 定义任务栈 2 2 定义任务函数 2 3 定义任务控制块 2 4 实现任务创建函数 三 实现就绪列表 3 1 定义就绪列表
  • 单片机通信数据延迟问题排查

    1 问题说明 笔者在最近的项目中 发现系统的响应延迟较高 经过排查 排除了单片机运行卡死的问题 2 原因分析 具体排查过程这里就不细致说明了 直接给出排查后原因 任务执行周期规划不合理 导致freertos队列发送接收到的命令有延迟 为了便
  • 13-FreeRTOS任务创建与删除

    任务创建和删除API函数位于文件task c中 需要包含task h头文件 task h里面包函数任务的类型函数 例如 对xTaskCreate的调用 通过指针方式 返回一个TaskHandle t 变量 然后可将该变量用vTaskDele
  • FreeRTOS实时操作系统(三)任务挂起与恢复

    系列文章 FreeRTOS实时操作系统 一 RTOS的基本概念 FreeRTOS实时操作系统 二 任务创建与任务删除 HAL库 FreeRTOS实时操作系统 三 任务挂起与恢复 FreeRTOS实时操作系统 四 中断任务管理 FreeRTO
  • 再论FreeRTOS中的configTOTAL_HEAP_SIZE

    关于任务栈和系统栈的基础知识 可以参考之前的随笔 FreeRTOS 任务栈大小确定及其溢出检测 这里再次说明 define configTOTAL HEAP SIZE size t 17 1024 这个宏 官方文档解释 configTOTA
  • FreeRTOS 配置TICK_RATE_HZ

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 使用 GCC 编译器的 ARM 内核的堆栈回溯(当存在 MSP 到 PSP 切换时)

    核心 ARM Cortex M4 编译器 GCC 5 3 0 ARM EABI 操作系统 免费 RTOS 我正在使用 gcc 库函数 Unwind Reason Code Unwind Backtrace Unwind Trace Fn v
  • 如何更改 FreeRTOS 中任务的最大可用堆大小?

    我通过以下方式在任务中创建元素列表 l dllist pvPortMalloc sizeof dllist dlllist 有 32 字节大 我的嵌入式系统有 60kB SRAM 所以我希望系统可以轻松处理我的 200 个元素列表 我发现在
  • 小型 ARM 微控制器的 RTOS 内核之间的可量化差异 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有许多不同的 RTOS 可用于微控制器 我专门寻找支持 ARM Cortex M 处理器的 RTOS 另外 我对闭源解决方案不感兴趣 试图从网站

随机推荐

  • 【C语言】求n的阶乘(递归法和循环法)

    文章目录 一 循环法二 递归法 一 循环法 根据阶乘的计算方法 xff1a n xff01 61 1 2 3 n xff0c 我们在一个for循环完成 n 次乘法运算 注意因为是连乘 xff0c 最终阶乘结果可能会非常大所以我们在Fac函数
  • 【C语言】数组排序方法总结

    一 冒泡排序 相邻元素两两比较 xff0c 按照要求交换位置 xff0c n个元素一共要比较n 1趟 xff0c 每趟要两两比较未排序元素个数 1次 span class token macro property span class to
  • 【C语言】通讯录实现

    通讯录功能 添加联系人信息 xff08 名字 xff0c 性别 xff0c 年龄 xff0c 电话号码 xff0c 家庭住址 xff09 输出指定联系人信息查找指定联系人信息修改指定联系人信息打印所有联系人信息对所有联系人 xff08 通过
  • 【C++】多态学习总结

    文章目录 一 多态的分类1 静态的多态2 动态的多态 二 多态的相关概念介绍及其实现1 虚函数2 虚函数的重写 xff08 覆盖 xff09 3 多态的构成条件4 C 43 43 11的 override 和 final5 重载 覆盖 重写
  • 【Linux】线程基础知识

    文章目录 一 什么是线程 xff1f 1 线程概念2 重新理解进程3 线程优缺点4 线程周期5 线程调度6 线程工作原理7 线程异常8 线程资源 二 为什么要有线程 xff1f 三 如何控制线程 xff1f 1 Linux支持的POSIX线
  • 【MySQL】数据库基础知识

    文章目录 一 什么是数据库二 为什么要有数据库三 数据库分类四 数据库的基本使用1 MySQL安装2 检查MySQL后端服务器是否启动3 连接MySQL服务器4 服务器 xff0c 数据库 xff0c 表关系5 数据存储逻辑 五 MySQL
  • 【C语言】typedef关键字

    文章目录 一 使用介绍1 对一般类型进行重命名2 对结构体类型进行重命名3 对指针进行重命名4 对数组进行重命名 二 typedef 和 define 的区别 一 使用介绍 typedef 的作用就是对类型进行重命名 xff0c 具体作用在
  • 【C语言】深入理解注释

    文章目录 一 预处理阶段对注释的处理二 注释使用时的注意事项1 C风格的注释无法嵌套使用2 基本注释注意事项3 注释导致的二义性 四 关于注释的一个使用建议 一 预处理阶段对注释的处理 我们知道一个源文件要变成可执行程序的话 xff0c 首
  • 【Java】数组

    文章目录 一 为什么要有数组 xff1f 二 什么是数组 xff1f 1 基本语法2 数组的本质 三 数组的使用1 获取长度 访问元素2 遍历数组3 下标越界 空引用4 数组作为函数参数5 数组作为函数返回值 四 数组拷贝1 手动拷贝2 使
  • 欧几里得算法的图形化理解

    欧几里得算法用于求两个数的最大公约数 xff0c 这篇博文力求以可视化的图形帮助读者理解欧几里得算法 首先 xff0c 简单介绍一下欧几里得算法 设a b N xff0c 我们规定gcd a b 代表a与b的最大公约数 欧几里得算法的实质是
  • PX4IO刷写BootLoader、固件 PX4IO固件损坏修复

    前两天玩坏了一个飞控的IO芯片 xff0c 具体表现为上电后红灯一直闪或常亮 xff0c 有以下解决办法 xff1a 文章目录 FMU给IO刷写重新烧写BootLoader FMU给IO刷写 先断电 xff0c 按住安全开关 xff0c 上
  • Maven版本3.6.1环境配置安装

    文章目录 前言一 操作步骤 xff1a 总结 前言 注意 xff1a 在换源时保持联网状态 xff0c 才能成功换成 提示 xff1a 以下是本篇文章正文内容 xff0c 下面案例可供参考 一 操作步骤 xff1a 1 下载maven安装包
  • 蓝桥杯STM32F103RB数码管计时(秒表)

    STM32F103RB数码管定时 xff08 秒表 xff09 硬件单路 96 配置TIM2及其中断代码片如下 示例 96 96 中断执行函数代码片如下 示例 96 96 seg c 数码管 代码片如下 示例 96 完整工程下载 gt gt
  • 第七届蓝桥杯嵌入式(省赛)程序题

    第七届蓝桥杯 xff08 省赛 xff09 解读 43 程序 解读 xff1a 这里自己多读几遍设计任务以及要求再看下面 96 A 先搭总体框架 96 各初始化函数 96 LCD初始化 96 96 按键初始化 96 96 ADC初始化 96
  • STM32普通io口模拟pwm输出的三种方法

    STM32F103RB普通io口模拟pwm输出的第三种方法 xff08 周期占空比可调 xff09 第 xff08 一 xff09 种定时器中断产生pwm 96 第 xff08 一 xff09 种代码片 96 第 xff08 二 xff09
  • STM32 RS232通信实验

    stm32F103 RS232通信实验 什么是RS232 软件设计 完整工程下载 什么是RS232 先来看看UART传输所存在的问题 于是就有了RS232协议 这里注意使用的是负逻辑电平信号 在规定范围内的电平信号代表逻辑1或0 xff0c
  • MDK中变量无法添加到逻辑分析仪中原因

    MDK中变量无法添加到逻辑分析仪中原因 解决方法 去掉static 提示无法将变量添加到逻辑分析仪中 解决方法 去掉static 设置为bit 全速运行
  • 三,FreeRTOS之——动态创建多任务+优先级

    声明 xff1a 本专栏参考韦东山 xff0c 野火 xff0c 正点原子以及其他博主的FreeRTOS教程 xff0c 如若侵权请告知 xff0c 马上删帖致歉 xff0c 个人总结 xff0c 如有不对 xff0c 欢迎指正 动态创建多
  • ESP8266组网+STM32数据传输项目

    ESP8266 43 STM32数据传输项目 实验硬件 xff1a 项目关键词 xff1a 项目描述项目涉及知识 xff1a 1 ESP8266开发2 MQTT协议3 STM32 整体开发流程 xff1a 实验硬件 xff1a ESP826
  • 十一,FreeRTOS之——互斥信号量(优先级反转,优先级继承,递归锁)

    声明 xff1a 本专栏参考韦东山 xff0c 野火 xff0c 正点原子以及其他博主的FreeRTOS教程 xff0c 如若侵权请告知 xff0c 马上删帖致歉 xff0c 个人总结 xff0c 如有不对 xff0c 欢迎指正 互斥量理论