FreeRTOS 中互斥锁的使用

本文介绍了互斥锁在并发编程中的作用,特别是FreeRTOS中的二进制信号量实现。通过实例展示了如何在STM32F103中使用互斥锁保证线程安全,以及如何在任务间协调访问共享资源,以避免竞态条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

互斥锁的概念

        互斥锁(Mutex,全名Mutual Exclusion)是一种用于控制多个线程对共享资源访问的同步机制。在并发编程中,多个线程同时访问共享资源可能导致数据不一致性或竞态条件(Race Condition)。为了避免这种情况,可以使用互斥锁来确保在任意时刻只有一个线程能够访问共享资源。

        互斥锁的基本原理是,当一个线程想要访问共享资源时,它必须先尝试获取互斥锁。如果该锁已经被其他线程持有,那么请求线程就会被阻塞,直到锁被释放。一旦线程成功获取了互斥锁,它就可以安全地访问共享资源,完成操作后再释放锁,以便其他线程可以继续访问。

dd31b41b11ad429e8c2130383db237a1.png

        在不同的编程语言和操作系统中,互斥锁的实现方式可能会有所不同,但基本的思想是一致的。使用互斥锁可以有效地防止多个线程同时修改共享数据,从而确保线程安全性。

        需要注意的是,虽然互斥锁能够解决竞态条件问题,但过度使用锁可能导致性能问题,因为锁的获取和释放会引入额外的开销。因此,在设计并发程序时,需要谨慎考虑锁的使用,以在安全性和性能之间找到平衡。

FreeRTOS的互斥锁

1ab7ce9e40bb4a6bafad5957cb47dadd.png

        FreeRTOS 是一款用于嵌入式系统的实时操作系统(RTOS)。FreeRTOS 提供了一些同步机制,其中包括用于保护共享资源的互斥锁。在 FreeRTOS 中,互斥锁称为二进制信号量,通过 Semaphore 数据结构实现。

d0aa03d63b40480e8221a8b7657181b3.png

        以下是 FreeRTOS 中互斥锁的基本使用方法:

1. 引入头文件

        在使用互斥锁之前,需要引入 FreeRTOS 的头文件。

#include "FreeRTOS.h"

#include "semphr.h"

2. 创建互斥锁

        使用 xSemaphoreCreateMutex() 函数创建一个互斥锁。这个函数返回一个指向互斥锁的句柄。

SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();

3. 获取互斥锁(加锁)

        在访问共享资源之前,需要获取互斥锁。使用 xSemaphoreTake() 函数来尝试获取锁。

if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {

    // 访问共享资源的代码

    // ...

}

        portMAX_DELAY 表示无限等待,直到成功获取锁。

4. 释放互斥锁(解锁)

        在访问共享资源后,需要释放互斥锁,以便其他任务可以获取锁。

xSemaphoreGive(xMutex);

        通过调用 xSemaphoreGive() 来释放互斥锁。

        在以上的代码片段中,xMutex 是互斥锁的句柄,xSemaphoreTake() 用于获取锁,xSemaphoreGive() 用于释放锁。在实时系统中,这样的互斥锁机制有助于确保共享资源的线程安全性。

        请注意,FreeRTOS 还提供其他类型的信号量,如计数信号量,可以用于更灵活的同步操作。在使用 FreeRTOS 时,建议查阅官方文档和示例代码,以确保正确地使用互斥锁和其他同步机制。

STM32F103案例

        创建一个互斥锁,然后有两个任务,每个任务都会尝试获取互斥锁,然后对共享资源进行访问。

        请确保已经配置好 STM32CubeMX 和相关的开发环境,同时已经集成了 FreeRTOS。

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "stm32f1xx_hal.h"

// 互斥锁句柄
SemaphoreHandle_t xMutex;
// 共享资源
volatile uint32_t sharedResource = 0;

void Task1(void *pvParameters) {
    while (1) {
        // 尝试获取互斥锁
        if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
            // 访问共享资源
            sharedResource++;
            // 释放互斥锁
            xSemaphoreGive(xMutex);
        }
        vTaskDelay(pdMS_TO_TICKS(1000));  // 任务延时1秒
    }
}

void Task2(void *pvParameters) {
    while (1) {
        // 尝试获取互斥锁
        if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
            // 访问共享资源
            sharedResource--;
            // 释放互斥锁
            xSemaphoreGive(xMutex);
        }
        vTaskDelay(pdMS_TO_TICKS(500));  // 任务延时500毫秒
    }
}

int main(void) {
    // 初始化 FreeRTOS
    HAL_Init();
    SystemClock_Config();

    // 创建互斥锁
    xMutex = xSemaphoreCreateMutex();

    // 创建任务
    xTaskCreate(Task1, "Task1", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
    xTaskCreate(Task2, "Task2", configMINIMAL_STACK_SIZE, NULL, 2, NULL);

    // 启动调度器
    vTaskStartScheduler();
    // 程序不应该执行到这里
    while (1) {

    }

}

        在这个例子中,使用 xMutex 作为互斥锁的句柄,两个任务 Task1 和 Task2 分别尝试获取互斥锁,对共享资源进行读写,并在操作后释放互斥锁。 vTaskDelay 函数用于模拟任务的执行时间。

        请注意,这只是一个简单的示例,实际的应用可能需要更多的复杂性和保护来确保线程安全。此外,确保在 STM32CubeMX 中正确配置 FreeRTOS,包括堆栈和任务优先级等。在实际应用中,你可能需要添加更多的任务和功能,以满足特定的需求。

        关于CubeMX的配置请看我以前更新的博客

 

FreeRTOS中,互斥锁用于保护共享资源,防止多个线程同时访问共享资源而引发的竞争条件。互斥锁使用步骤如下: 1. 定义互斥锁变量和互斥锁句柄:在代码中先定义一个互斥锁变量和一个互斥锁句柄,例如: ``` osMutexId resource_mutex = NULL; // 定义互斥锁句柄 osMutexDef(resource_mutex); // 定义互斥锁变量 ``` 2. 创建互斥锁:在初始化函数中创建互斥锁,例如: ``` void resource_mutex_init(void) { resource_mutex = osMutexCreate(osMutex(resource_mutex)); } ``` 3. 获取互斥锁:在需要使用共享资源的函数中,首先获取互斥锁,例如: ``` void function(void) { resource_mutex_acquire(); // 获取互斥锁 // 操作共享资源 resource_mutex_release(); // 释放互斥锁 } ``` 总结:在FreeRTOS中,使用互斥锁的步骤包括定义互斥锁变量和句柄、创建互斥锁、获取互斥锁以及释放互斥锁。通过这些步骤,可以确保多个线程对共享资源的安全访问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [freertos互斥锁使用](https://blog.csdn.net/weixin_45379397/article/details/130604913)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [【FreeRTOS互斥锁使用](https://blog.csdn.net/qq_43581670/article/details/127688331)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JiaYu嵌入式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值