引言: FreeRTOS提供了多种同步机制,其中信号量(Semaphore)和互斥量(Mutex)是两个常用的工具,用于在任务之间共享资源和实现同步。本篇博客将深入讨论FreeRTOS信号量与互斥量的区别以及它们的使用场景,为开发者提供清晰的指导。

1. 信号量与互斥量的区别:

  • 信号量:
  • 特点: 信号量是一种计数信号,其值可以大于等于0。它允许多个任务同时访问一组资源。
  • 操作: xSemaphoreTake用于获取信号量,xSemaphoreGive用于释放信号量。
  • 使用场景: 适用于资源数目可大于1的情况,如多个任务可以同时访问的资源池。
  • 互斥量:
  • 特点: 互斥量是一种二进制信号,其值只能是0或1。它用于保护对资源的独占性访问。
  • 操作: xSemaphoreTakexSemaphoreGive同样适用于互斥量。
  • 使用场景: 适用于资源数目只有一个,且需要保证独占性访问的情况,如全局变量、共享设备等。

2. 代码演示:

以下是一个简单的FreeRTOS代码演示,展示了信号量和互斥量的使用:

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

// 信号量
SemaphoreHandle_t xSemaphore;

// 互斥量
SemaphoreHandle_t xMutex;

void task1(void *pvParameters) {
    for (;;) {
        // 使用信号量获取资源
        if (xSemaphoreTake(xSemaphore, portMAX_DELAY)) {
            // 访问共享资源
            // ...

            // 释放信号量
            xSemaphoreGive(xSemaphore);
        }

        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void task2(void *pvParameters) {
    for (;;) {
        // 使用互斥量获取资源
        if (xSemaphoreTake(xMutex, portMAX_DELAY)) {
            // 访问共享资源
            // ...

            // 释放互斥量
            xSemaphoreGive(xMutex);
        }

        vTaskDelay(500 / portTICK_PERIOD_MS);
    }
}

int main() {
    // 创建信号量和互斥量
    xSemaphore = xSemaphoreCreateCounting(10, 0);
    xMutex = xSemaphoreCreateMutex();

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

    // 启动调度器
    vTaskStartScheduler();

    return 0;
}

结论:

在FreeRTOS中,选择信号量还是互斥量取决于任务对共享资源的访问需求。信号量适用于资源数目大于1的情况,而互斥量适用于资源数目为1的情况。合理选择同步机制有助于提高系统的并发性和可维护性,确保多任务系统的稳定运行。通过深入理解信号量和互斥量的特性和应用场景,开发者能够更好地设计和调试FreeRTOS系统。