在FreeRTOS中,互斥量是一种用于保护共享资源的同步机制。它通过二进制信号量的方式,确保在任意时刻只有一个任务可以获取互斥量并访问共享资源,其他任务将被阻塞。使用互斥量的基本步骤包括创建互斥量、获取互斥量、访问共享资源和释放互斥量。互斥量在FreeRTOS中起到了重要的作用,保护共享资源的访问,提供了一种有效的同步机制,确保任务之间的协作和数据的一致性。
文章目录
- 互斥量的理解
- 互斥量使用的相关函数
- 使用互斥量的步骤
- 示例代码
互斥量的理解
在FreeRTOS中,互斥量是一种用于保护共享资源的同步机制。它是一种二进制信号量,只有两种状态:可用和不可用。当互斥量可用时,一个任务可以获取互斥量并访问共享资源,而其他任务将被阻塞。当互斥量不可用时,任务将等待直到互斥量可用。
互斥量使用的相关函数
-
xSemaphoreCreateMutex()
- 作用:创建一个互斥量。
- 原型:
SemaphoreHandle_t xSemaphoreCreateMutex(void)
- 参数:无。
- 返回值:返回一个指向互斥量的句柄(
SemaphoreHandle_t
)。
-
xSemaphoreTake()
- 作用:获取(锁定)互斥量。
- 原型:
BaseType_t xSemaphoreTake(SemaphoreHandle_t xMutex, TickType_t xTicksToWait)
- 参数:
xMutex
:互斥量的句柄。xTicksToWait
:可选参数,指定等待互斥量的时间,单位为时钟周期(Tick)。
- 返回值:
- 如果成功获取互斥量,则返回
pdPASS
。 - 如果等待超时或其他原因导致获取失败,则返回
errQUEUE_EMPTY
。
- 如果成功获取互斥量,则返回
-
xSemaphoreGive()
- 作用:释放(解锁)互斥量。
- 原型:
BaseType_t xSemaphoreGive(SemaphoreHandle_t xMutex)
- 参数:
xMutex
:互斥量的句柄。 - 返回值:返回
pdPASS
。
使用互斥量的步骤
-
创建互斥量:使用
xSemaphoreCreateMutex()
函数创建一个互斥量。该函数返回一个指向互斥量的句柄。 -
获取互斥量:在需要访问共享资源的任务中,使用
xSemaphoreTake()
函数获取互斥量。如果互斥量当前可用,则任务将继续执行。如果互斥量不可用,则任务将被阻塞,直到互斥量可用。 -
访问共享资源:在获得互斥量后,可以安全地访问共享资源。
-
释放互斥量:使用
xSemaphoreGive()
函数释放互斥量。这将使得其他任务可以获取互斥量并访问共享资源。
需要注意的是,获取互斥量后,任务应该在访问共享资源后尽快释放互斥量,以便其他任务能够获取互斥量。否则,如果任务长时间持有互斥量,可能会导致其他任务被阻塞,影响系统的响应性能。
互斥量还有一些其他的使用方式和函数,比如可超时获取互斥量的函数xSemaphoreTake()
,以及获取互斥量时阻塞的最长时间等。这些功能可以根据具体需求进行使用。
示例代码
#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
进行操作,并在操作完成后释放互斥量。这样可以确保同时只有一个任务能够访问共享资源,避免了数据竞争的问题。