【FreeRTOS】信号量的相关函数使用及示例解释

FreeRTOS中的信号量是一种用于任务间同步的机制。它可以用来实现任务之间的互斥访问共享资源或者等待某个事件发生。

文章目录

    • 信号量类型
      • [1. 二进制信号量(Binary Semaphore):](#1. 二进制信号量(Binary Semaphore): "#1_Binary_Semaphore_9")
      • [2. 计数信号量(Counting Semaphore):](#2. 计数信号量(Counting Semaphore): "#2_Counting_Semaphore_14")
    • 信号量使用
      • [1. `xSemaphoreCreateBinary()`](#1. xSemaphoreCreateBinary() "#1_xSemaphoreCreateBinary_27")
      • [2. `xSemaphoreCreateCounting()`](#2. xSemaphoreCreateCounting() "#2_xSemaphoreCreateCounting_41")
      • [3. `xSemaphoreCreateMutex()`](#3. xSemaphoreCreateMutex() "#3_xSemaphoreCreateMutex_55")
      • [4. `xSemaphoreTake()`](#4. xSemaphoreTake() "#4_xSemaphoreTake_67")
      • [5. `xSemaphoreGive()`](#5. xSemaphoreGive() "#5_xSemaphoreGive_79")
    • 示例代码块

信号量类型

FreeRTOS中的信号量有两种类型:二进制信号量和计数信号量。

1. 二进制信号量(Binary Semaphore):

  • 二进制信号量只有两种状态:0和1。
  • 当一个任务获取到二进制信号量时,它会将信号量的值减1,如果信号量的值已经为0,则任务会被阻塞,直到有其他任务释放了该信号量。
  • 当一个任务释放二进制信号量时,它会将信号量的值加1,如果有其他任务正在等待该信号量,则会唤醒其中一个等待的任务。

2. 计数信号量(Counting Semaphore):

  • 计数信号量可以有多个状态,取决于其初始值和每次操作的增减值。
  • 当一个任务获取到计数信号量时,它会将信号量的值减去指定的增减值,如果信号量的值已经为0,则任务会被阻塞,直到有其他任务释放了足够的信号量。
  • 当一个任务释放计数信号量时,它会将信号量的值加上指定的增减值,如果有其他任务正在等待该信号量,则会唤醒其中一个等待的任务。

在FreeRTOS中使用信号量的步骤如下:

  1. 创建一个信号量对象,可以使用xSemaphoreCreateBinary()函数创建二进制信号量,或者使用xSemaphoreCreateCounting()函数创建计数信号量。
  2. 在任务中使用xSemaphoreTake()函数获取信号量,在需要访问共享资源或者等待事件发生的地方调用该函数。
  3. 在任务中使用xSemaphoreGive()函数释放信号量,在完成对共享资源的访问或者事件发生后调用该函数。
  4. 根据需要,可以使用xSemaphoreTake()函数的阻塞时间参数来控制任务等待信号量的时间。

信号量使用

1. xSemaphoreCreateBinary()

  • 原型

    c 复制代码
    SemaphoreHandle_t xSemaphoreCreateBinary(void)
  • 作用:创建一个二进制信号量。

  • 参数:无。

  • 返回值 :返回一个指向信号量的句柄(SemaphoreHandle_t)。

2. xSemaphoreCreateCounting()

  • 原型:

    c 复制代码
    SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, UBaseType_t uxInitialCount)
  • 作用:创建一个计数信号量。

  • 参数:一个参数,指定信号量的最大计数值。

  • 返回值 :返回一个指向信号量的句柄(SemaphoreHandle_t)。

3. xSemaphoreCreateMutex()

  • 原型
c 复制代码
SemaphoreHandle_t xSemaphoreCreateMutex(void)
  • 作用:创建一个互斥信号量。
  • 参数:无。
  • 返回值 :返回一个指向信号量的句柄(SemaphoreHandle_t)。

4. xSemaphoreTake()

  • 原型
c 复制代码
BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait)
  • 作用:获取一个信号量。
  • 参数 :信号量的句柄(SemaphoreHandle_t)和可选的超时时间(TickType_t)。
  • 返回值 :如果获取成功,则返回pdTRUE;如果获取失败(超时或其他原因),则返回pdFALSE

5. xSemaphoreGive()

  • 原型:
c 复制代码
BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore)
  • 作用:释放一个信号量。
  • 参数 :信号量的句柄(SemaphoreHandle_t)。
  • 返回值:无。

示例代码块

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;
}

在示例中,使用了上述函数来创建互斥信号量(xSemaphoreCreateMutex()),获取互斥信号量(xSemaphoreTake()),释放互斥信号量(xSemaphoreGive())。其中,互斥信号量的句柄存储在全局变量mutex中。

相关推荐
浮梦终焉1 天前
_FYAW智能显示控制仪表的简单使用_串口通信
嵌入式·串口通信·fyaw
LunarCod2 天前
Linux驱动开发快速入门——字符设备驱动(直接操作寄存器&设备树版)
linux·驱动开发·设备树·嵌入式·c/c++·字符设备驱动
stone51952 天前
鸿蒙系统ubuntu开发环境搭建
c语言·ubuntu·华为·嵌入式·harmonyos
飞凌嵌入式2 天前
飞凌嵌入式旗下教育品牌ElfBoard与西安科技大学共建「科教融合基地」
嵌入式硬件·学习·嵌入式·飞凌嵌入式
飞凌嵌入式2 天前
飞凌嵌入式T113-i开发板RISC-V核的实时应用方案
人工智能·嵌入式硬件·嵌入式·risc-v·飞凌嵌入式
blessing。。2 天前
I2C学习
linux·单片机·嵌入式硬件·嵌入式
网易独家音乐人Mike Zhou3 天前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
jjyangyou5 天前
物联网核心安全系列——智能汽车安全防护的重要性
算法·嵌入式·产品经理·硬件·产品设计
FreakStudio5 天前
全网最适合入门的面向对象编程教程:59 Python并行与并发-并行与并发和线程与进程
python·单片机·嵌入式·面向对象·电子diy·电子计算机
憧憬一下6 天前
UART硬件介绍
arm开发·嵌入式硬件·串口·嵌入式·linux驱动开发