【FreeRTOS】互斥量的使用与逐步实现

在FreeRTOS中,互斥量是一种用于保护共享资源的同步机制。它通过二进制信号量的方式,确保在任意时刻只有一个任务可以获取互斥量并访问共享资源,其他任务将被阻塞。使用互斥量的基本步骤包括创建互斥量、获取互斥量、访问共享资源和释放互斥量。互斥量在FreeRTOS中起到了重要的作用,保护共享资源的访问,提供了一种有效的同步机制,确保任务之间的协作和数据的一致性。

文章目录

互斥量的理解

在FreeRTOS中,互斥量是一种用于保护共享资源的同步机制。它是一种二进制信号量,只有两种状态:可用和不可用。当互斥量可用时,一个任务可以获取互斥量并访问共享资源,而其他任务将被阻塞。当互斥量不可用时,任务将等待直到互斥量可用。

互斥量使用的相关函数

  1. xSemaphoreCreateMutex()

    • 作用:创建一个互斥量。
    • 原型SemaphoreHandle_t xSemaphoreCreateMutex(void)
    • 参数:无。
    • 返回值 :返回一个指向互斥量的句柄(SemaphoreHandle_t)。
  2. xSemaphoreTake()

    • 作用:获取(锁定)互斥量。
    • 原型BaseType_t xSemaphoreTake(SemaphoreHandle_t xMutex, TickType_t xTicksToWait)
    • 参数
      • xMutex:互斥量的句柄。
      • xTicksToWait:可选参数,指定等待互斥量的时间,单位为时钟周期(Tick)。
    • 返回值
      • 如果成功获取互斥量,则返回pdPASS
      • 如果等待超时或其他原因导致获取失败,则返回errQUEUE_EMPTY
  3. xSemaphoreGive()

    • 作用:释放(解锁)互斥量。
    • 原型BaseType_t xSemaphoreGive(SemaphoreHandle_t xMutex)
    • 参数xMutex:互斥量的句柄。
    • 返回值 :返回pdPASS

使用互斥量的步骤

  1. 创建互斥量:使用xSemaphoreCreateMutex()函数创建一个互斥量。该函数返回一个指向互斥量的句柄。

  2. 获取互斥量:在需要访问共享资源的任务中,使用xSemaphoreTake()函数获取互斥量。如果互斥量当前可用,则任务将继续执行。如果互斥量不可用,则任务将被阻塞,直到互斥量可用。

  3. 访问共享资源:在获得互斥量后,可以安全地访问共享资源。

  4. 释放互斥量:使用xSemaphoreGive()函数释放互斥量。这将使得其他任务可以获取互斥量并访问共享资源。

需要注意的是,获取互斥量后,任务应该在访问共享资源后尽快释放互斥量,以便其他任务能够获取互斥量。否则,如果任务长时间持有互斥量,可能会导致其他任务被阻塞,影响系统的响应性能。
互斥量还有一些其他的使用方式和函数,比如可超时获取互斥量的函数xSemaphoreTake(),以及获取互斥量时阻塞的最长时间等。这些功能可以根据具体需求进行使用。

示例代码

c 复制代码
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

// 共享资源
int sharedResource = 0;

// 互斥量
SemaphoreHandle_t mutex;

void task1(void *pvParameters)
{
    while (1) {
        // 获取互斥量
        xSemaphoreTake(mutex, portMAX_DELAY);

        // 访问共享资源
        sharedResource++;

        // 释放互斥量
        xSemaphoreGive(mutex);

        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

void task2(void *pvParameters)
{
    while (1) {
        // 获取互斥量
        xSemaphoreTake(mutex, portMAX_DELAY);

        // 访问共享资源
        sharedResource--;

        // 释放互斥量
        xSemaphoreGive(mutex);

        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

int main(void)
{
    // 创建互斥量
    mutex = xSemaphoreCreateMutex();

    // 创建任务
    xTaskCreate(task1, "Task 1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
    xTaskCreate(task2, "Task 2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);

    // 启动调度器
    vTaskStartScheduler();

    return 0;
}

在示例中,两个任务分别获取互斥量mutex,然后对共享资源sharedResource进行操作,并在操作完成后释放互斥量。这样可以确保同时只有一个任务能够访问共享资源,避免了数据竞争的问题。

相关推荐
十月的皮皮9 小时前
C语言学习笔记20260606- 求月份天数三种写法
c语言·笔记·学习
Jason_chen10 小时前
Linux 6.2 音频机制深度解析:AI驱动的低延迟音频与零信任音频安全架构
linux
下午写HelloWorld10 小时前
Linux系统及Ubuntu常用指令
linux·ubuntu·操作系统
caimouse10 小时前
Reactos 第 5 章 进程与线程 — 5.8 Windows 的 APC 机制
c语言·windows
云计算磊哥@11 小时前
运维开发宝典026-MySQL02数据库表操作
运维·数据库·运维开发
weixin_5231853211 小时前
Collections.unmodifiableMap详解:真的不可修改吗?
java·linux·前端
天天进步201511 小时前
Tunnelto 源码解析 #9:控制服务器设计:Warp、WebSocket、Ping/Pong 与连接保活
运维·服务器·websocket
凡人叶枫12 小时前
Effective C++ 条款04:确定对象被使用前已先被初始化
java·linux·开发语言·c++·嵌入式开发
云栖梦泽12 小时前
玩转RK3506SDK
linux·嵌入式硬件
极客先躯12 小时前
高级java每日一道面试题-2026年02月01日-实战篇[Docker]-Docker Volume 的生命周期管理是怎样的?
java·运维·docker·容器·持久化·架构图·容器卷