FreeRTOS——互斥信号量知识总结及其实战

news2024/11/27 4:16:49

1互斥信号量的概念

1)互斥信号量:是一个拥有优先级继承的二值信号量,在同步的应用中二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中!

2)优先级继承:当一个互斥信号量正在被一个低优先级的任务持有时, 如果此时有个高优先级的任务也尝试获取这个互斥信号量,那么这个高优先级的任务就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级。
在这里插入图片描述
3)互斥信号量有任务优先级继承的机制, 但是中断不是任务,没有任务优先级, 所以互斥信号量只能用与任务中,不能用于中断服务函数。
4)中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态。

2 互斥信号量的使用流程

1)使用互斥信号量:首先将宏configUSE_MUTEXES置一
2)使用流程:创建互斥信号量 ->(task)获取信号量 ->(give)释放信号量

3 互斥信号量API函数

#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
返回值: NULL 创建失败
其他 返回信号量失败

互斥信号量的释放和获取函数与二值信号量相同 !只不过互斥信号量不支持中断中调用
注意:创建互斥信号量时,会主动释放一次信号量

4 互斥信号量实战

实验设计:将优先级翻转所用到的信号量函数,修改成互斥信号量即可,通过串口打印提示信息

4.1 freertos_demo.c

#include "freertos_demo.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

//FreeRTOS配置

//1.任务配置
//1.1 START_TASK 任务 配置

#define START_TASK_PRIO 1                   /* 任务优先级 */
#define START_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            StartTask_Handler;  /* 任务句柄 */
void start_task(void *pvParameters);        /* 任务函数 */

//1.2 TASK1 任务 配置

#define TASK1_PRIO      2                   /* 任务优先级 */
#define TASK1_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            lowTask_Handler;  /* 任务句柄 */
void task1(void *pvParameters);             /* 任务函数 */

//1.2 TASK2 任务 配置

#define TASK2_PRIO      3                   /* 任务优先级 */
#define TASK2_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            middleTask_Handler;  /* 任务句柄 */
void task2(void *pvParameters);             /* 任务函数 */

//1.3 TASK3 任务 配置

#define TASK3_PRIO      4                   /* 任务优先级 */
#define TASK3_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            highTask_Handler;  /* 任务句柄 */
void task3(void *pvParameters);             /* 任务函数 */

//1.4 二值信号量句柄定义
SemaphoreHandle_t        mutexSemaphore;  

//2.在freertos_demo函数中创建start_task任务
void freertos_demo(void)
{
    //创建互斥信号量
     mutexSemaphore = xSemaphoreCreateMutex();         //互斥型信号量创建成功后会释放一次信号量
    if(mutexSemaphore != NULL)
    {
        printf("二值信号量创建成功!!!\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();
}

//3.在start_task函数中创建task1、task2任务
void start_task(void *pvParameters)
{
    
    //进入临界区
    taskENTER_CRITICAL();
    //创建任务1
      xTaskCreate((TaskFunction_t )task1,            /* 任务函数 */
                (const char*    )"task1",          /* 任务名称 */
                (uint16_t       )TASK1_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK1_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&lowTask_Handler);   /* 任务句柄 */
     //创建任务2          
     xTaskCreate((TaskFunction_t )task2,            /* 任务函数 */
                (const char*    )"task2",          /* 任务名称 */
                (uint16_t       )TASK2_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK2_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&middleTask_Handler);   /* 任务句柄*/
    //创建任务3          
    xTaskCreate((TaskFunction_t )task3,            /* 任务函数 */
                (const char*    )"task3",          /* 任务名称 */
                (uint16_t       )TASK3_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK3_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&highTask_Handler);   /* 任务句柄*/         
      //删除开始任务        
      vTaskDelete(StartTask_Handler);   
                
     //退出临界区
     taskEXIT_CRITICAL();
}


//4.任务一 低优先级任务
void task1(void *pvParameters)
{
    while (1)
    {
        printf("low Task获取信号量\r\n");
        xSemaphoreTake(mutexSemaphore, portMAX_DELAY);
        printf("low Task正在运行\r\n");
        delay_ms(3000);
        printf("low Task正在释放信号量\r\n");
        xSemaphoreGive(mutexSemaphore);
        vTaskDelay(1000);
    }
}

//5.任务二 中优先级任务
void task2(void *pvParameters)
{
    
    while(1)
    {
        printf("middle Task正在释放信号量\r\n");
        vTaskDelay(1000); 
    }
   
}

//6.任务三 高优先级任务
void task3(void *pvParameters)
{
    while(1)
    {
        printf("high Task获取信号量\r\n");
        xSemaphoreTake(mutexSemaphore, portMAX_DELAY);
        printf("high Task正在运行\r\n");
        delay_ms(1000);
        printf("high Task正在释放信号量\r\n");
        xSemaphoreGive(mutexSemaphore);
        vTaskDelay(1000);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1357311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 8.0 开关 Redo Logging

一 前言 前几天有客户测试使用云数据库的时候提出 要禁止mydumper 关闭redo log的操作 (说白了就是导入数据时保持MySQL 实例的redo logging功能), 这才想起 在 MySQL 8.0.21 版本中,开启了一个新特性 “Redo Logging 动态开关”。 在新实例导数据的场…

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 概述

【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 概述-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行环境搭建-CSDN博客 【大数据进阶第二阶段之Hadoop学习笔记】Hadoop 运行模式-CSDN博客 1、 Hadoop 是什么 (1)Hadoop是一个由Apache基…

第二百四十六回

我们在上一章回中介绍了"修改页面导航中遇到的问题"沉浸式状态样相关的内容,本章回中将介绍如何修改Avatar的大小.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在正常使用CirCleAvatar组件时可以通过该组件的radius属性来修改它的…

ssm基于web的素材网的设计与实现+vue论文

基于web的素材网站的设计与实现 摘要 当下,正处于信息化的时代,许多行业顺应时代的变化,结合使用计算机技术向数字化、信息化建设迈进。传统的素材信息管理模式,采用人工登记的方式保存相关数据,这种以人力为主的管理…

C语言中关于strcpy函数的理解

strcpy的功能是将源指向的字符串复制到另外一个字符串中 目标指向的数组的大小应该要足够长&#xff0c;避免让源字符串中的数据溢出 关于这个函数的具体用法&#xff0c;我们可以看看下面这个程序 注意&#xff1a;strcpy函数的头文件是<string.h>&#xff0c;我们在用…

rollup 插件输出生成钩子

✨专栏介绍 Rollup专栏是一个专门介绍Rollup打包工具的系列文章。Rollup是一个现代化的JavaScript模块打包工具&#xff0c;它可以将多个模块打包成一个或多个文件&#xff0c;以提高应用程序的性能和加载速度。 在Rollup专栏中&#xff0c;您将学习到如何安装和配置Rollup&a…

面向对象的三大特征之一多态

多态 概念 多态是同一个对象&#xff0c;在不同时刻表现出来不同的形态&#xff0c;称之为多态。 例如&#xff1a;水&#xff0c;我们把水理解成为一个对象&#xff0c;而水会有不同的形态&#xff0c;比如 液态水、冰块、水蒸气 多态的前提 有继承/实现关系&#xff08;继承…

OpenCV-15位运算

OpenCV中的逻辑运算就是对应位置的元素进行与、或、非和异或。 Opencv与Python不同的是&#xff1a;OpenCV中0的非反过来是255&#xff0c;255反过来是0。 但是Python中255非为-256。 一、非运算 使用API---cv.bitwise_not(str) 示例代码如下&#xff1a; import cv2 imp…

EasyRecovery2024永久免费版电脑数据恢复软件

EasyRecovery是一款操作安全、价格便宜、用户自主操作的非破坏性的只读应用程序&#xff0c;它不会往源驱上写任何东西&#xff0c;也不会对源驱做任何改变。它支持从各种各样的存储介质恢复删除或者丢失的文件&#xff0c;其支持的媒体介质包括&#xff1a;硬盘驱动器、光驱、…

小程序测试和APP测试的区别

今天看了一下关于如何测试小程序的教学视频&#xff0c;里面讨论了一个很经典的面试题&#xff1a;小程序测试和APP测试的区别&#xff0c;包括在之前的面试过程中也确实是遇到过这个问题&#xff0c;所以这次打算把它记录下来&#xff0c;也算是知识巩固了。 首先从测试的内容…

C++使用map插入insert数据(二进制数据和非二进制数据)接口封装+读取文件

1、定义编写代码 //生成insert sql语句std::string GetInsertsql(XDATA kv, std::string table);//插入非二进制数据bool Insert(XDATA kv, std::string table);//插入二进制数据bool InsertBin(XDATA kv, std::string table); std::string LXMysql::GetInsertsql(XDATA kv, s…

【51单片机系列】LCD1602液晶模块

本文是关于液晶显示屏的相关介绍。相对于静态数码管、动态数码管、LED点阵等&#xff0c;LCD1602液晶显示器能够显示更多的字符数字信息&#xff0c;并且也是常用的一种显示装置。 文章目录 一、LCD1602介绍1.1、LCD1602简介1.2、LCD1602常用指令1.3、LCD1602使用 二、LCD1602使…

大数据StarRocks(三) StarRocks数据表设计

1. 列式存储 1.1 列式存储方式有以下几个优点&#xff1a; 1.快速的数据查询 由于数据是按照列进行存储的&#xff0c;所以查询某个列时只需要读取该列所在的块&#xff0c;而不是整行数据&#xff0c;从而大大提高了查询效率。 2.压缩效率高 由于列式存储的数据块中只有一…

数据库之存储引擎

1. 存储引擎的概念 存储引擎是MYSQL数据库的组件&#xff0c;负责执行时间的数据I/O操作&#xff08;数据的存储和提取&#xff09;&#xff0c;工作在文件系统之上&#xff0c;数据库的数据会先传到存储引擎&#xff0c;再按照存储引擎的存储格式保存到文件系统。 &#xff…

【AMD Xilinx】ZUBoard(5):移植KSZ9131千兆phy驱动

【AMD Xilinx】ZUBoard&#xff08;5&#xff09;&#xff1a;移植KSZ9131千兆phy驱动 一、需求二、软件搭建1. 在bsp中添加lwip库2. 创建lwip的例子 三、 Phy驱动调试1. 问题查找2. 修改驱动1&#xff09; 查找芯片手册2&#xff09;增加宏PHY_MICROCHIP_IDENTIFIER3&#xff…

Hadoop集群环境下HDFS实践编程过滤出所有后缀名不为“.abc”的文件时运行报错:java.net.ConnectException: 拒绝连接;

一、问题描述 搭建完Hadoop集群后&#xff0c;在Hadoop集群环境下运行HDFS实践编程使用Eclipse开发调试HDFS Java程序&#xff08;文末有源码&#xff09;&#xff1a; 假设在目录“hdfs://localhost:9000/user/hadoop”下面有几个文件&#xff0c;分别是file1.txt、file2.tx…

两阶段提交协议三阶段提交协议

两阶段提交协议 分布式事务是指会涉及到操作多个数据库的事务,在分布式系统中&#xff0c;各个节点之间在物理上相互独立&#xff0c;通过网络进行沟通和协调。 XA 就是 X/Open DTP 定义的交易中间件与数据库之间的接口规范&#xff08;即接口函数&#xff09;&#xff0c;交易…

使用Go语言实现RESTful API

RESTful架构是一种设计风格&#xff0c;用于构建网络应用程序的API。它基于HTTP协议&#xff0c;并使用不同的HTTP方法&#xff08;如GET、POST、PUT、DELETE等&#xff09;来处理不同的操作。在Go语言中&#xff0c;我们可以使用标准库中的net/http包来实现RESTful API。 下面…

不同阶数的巴特沃斯低通滤波器的空间域表示——数字图像处理

原理 巴特沃斯低通滤波器&#xff08;Butterworth Low-Pass Filter&#xff09;在频率域中的定义是明确的&#xff0c;但它在空间域中的表示不是直观的。这是因为巴特沃斯滤波器的形式是基于频率的&#xff0c;并且其空间域表示涉及到一个复杂的逆傅里叶变换&#xff0c;该变换…

Hive10_窗口函数

窗口函数&#xff08;开窗函数&#xff09; 1 相关函数说明 普通的聚合函数聚合的行集是组,开窗函数聚合的行集是窗口。因此,普通的聚合函数每组(Group by)只返回一个值&#xff0c;而开窗函数则可为窗口中的每行都返回一个值。简单理解&#xff0c;就是对查询的结果多出一列…