FreeRTOS中的锁
在FreeRTOS中,锁(locks)主要用于在多任务环境中同步访问共享资源,防止多个任务同时访问资源引发冲突。
FreeRTOS提供了几种不同的锁机制,每种锁都有其特定的使用场景和作用。
互斥锁(Mutexes)
互斥锁用于任务间的互斥访问,通常用来保护共享资源,确保同一时间只有一个任务能够访问资源,避免数据竞争。
在FreeRTOS中,互斥锁是二值信号量的一个扩展,但它增加了优先级继承机制,用于避免优先级反转(priority inversion)的问题。
通常用于保护共享资源(例如硬件设备、全局变量等)。
#include "FreeRTOS.h"
#include "semphr.h"
SemaphoreHandle_t xMutex;
void vTask1(void *pvParameters) {
while (1) {
// 获取互斥锁
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
// 访问共享资源
printf("Task 1 is accessing shared resource\n");
printf("Task 1 is run...\n");
vTaskDelay(pdMS_TO_TICKS(500));
printf("Task 1 is run end\n");
// 释放互斥锁
xSemaphoreGive(xMutex);
}
}
vTaskDelete(NULL);
}
void vTask2(void *pvParameters) {
while (1) {
// 获取互斥锁
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
// 访问共享资源
printf("Task 2 is accessing shared resource\n");
printf("Task 2 is run...\n");
vTaskDelay(pdMS_TO_TICKS(500));
printf("Task 2 is run end\n");
// 释放互斥锁
xSemaphoreGive(xMutex);
}
}
vTaskDelete(NULL);
}
int main() {
// 创建互斥锁
xMutex = xSemaphoreCreateMutex();
if (xMutex != NULL) {
// 创建两个任务
xTaskCreate(vTask1, "Task1", 1000, NULL, 1, NULL);
xTaskCreate(vTask2, "Task2", 1000, NULL, 1, NULL);
// 启动调度器
vTaskStartScheduler();
} else {
// 创建互斥锁失败
printf("Failed to create mutex\n");
}
return 0;
}
二值信号量(Binary Semaphores)
二值信号量(xSemaphoreCreateBinary,xSemaphoreTake,xSemaphoreGive)本质上是一种简单的锁机制,可以用来同步任务或中断与任务之间的通信,控制任务间的同步。
二值信号量只有两个状态:“已获取”或“未获取”。
但二值信号量不支持优先级继承机制,适用于比较简单的同步需求。
计数信号量(Counting Semaphores)
计数信号量可以用来控制多个任务访问共享资源的数量,通常用于限制资源的使用(例如限制同时可访问的设备数量)。
计数信号量可以有一个计数值,任务通过获取和释放信号量来减少或增加计数值。
通常用于控制对有限数量的资源(例如多个设备或缓冲区)的访问。
事件组(Event Groups)
事件组用于任务之间的复杂同步和状态管理。一个事件组由多个二进制标志位组成,任务可以等待这些标志位的变化。
事件组允许多个任务等待不同的标志位或者一个组合条件(例如:多个条件满足才继续执行)。
比较适用于需要多个任务同步或触发条件的场景。
通常用于任务间的复杂同步(例如多个任务的状态变化)。