【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进行操作,并在操作完成后释放互斥量。这样可以确保同时只有一个任务能够访问共享资源,避免了数据竞争的问题。

相关推荐
用户805533698035 小时前
Input 子系统架构:Core、Handler、Driver 三层是怎么协作的
linux·嵌入式
用户805533698035 小时前
RK-Forge外设系列开篇 - 把板子从「能启动」变成「能用」:Ethernet/SPI/MMC 三个纯接线外设
linux·github·嵌入式
小猿姐12 小时前
唯品会大规模数据库云原生实践:基于 KubeBlocks 管理数千实例的统一运维之路
运维·elasticsearch·云原生
七歌杜金房17 小时前
我终于又有了自己的 Linux 电脑
linux·debian·mac
SkyWalking中文站1 天前
认识 Horizon UI · 5/17:3D 基础设施地图
运维·监控·自动化运维
tntxia2 天前
linux curl命令详解_curl详解
linux
扛枪的书生2 天前
Linux 网络管理器用法速查
linux
SkyWalking中文站2 天前
认识 Horizon UI · 1/17:SkyWalking 新一代可观测性控制台
运维·前端·监控
顺风尿一寸2 天前
Java Socket 内核之旅:从 SocketChannel.read() 到 tcp_recvmsg 与 epoll 的完整调用链路
linux
雪梨酱QAQ2 天前
Kubeneters HA Cluster部署
运维