FreeRTOS 计数型信号量 详解

简介: FreeRTOS 计数型信号量 详解

什么是计数型信号量?

计数型信号量相当于队列长度大于1 的队列,因此计数型信号量能够容纳多个资源,这在计数型信号量被创建的时候确定的。

使用计数型信号量可以解决多个任务之间的同步问题,例如控制对共享资源的访问和协调任务的执行顺序。

计数型信号量相关 API 函数

                                  函数                                     描述
xSemaphoreCreateCounting() 使用动态方法创建计数型信号量
xSemaphoreCreateCountingStatic() 使用静态方法创建计数型信号量
uxSemaphoreGetCount() 获取信号量的计数值

1. 创建计数型信号量

SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,
                                            UBaseType_t uxInitialCount);

参数:

uxMaxCount:可以达到的最大计数值 uxInitialCount:创建信号量时分配给信号量的计数值

返回值:

成功,返回对应计数型信号量的句柄;

失败,返回 NULL 。

2. 释放二值信号量

BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore )

参数:

xSemaphore:要释放的信号量句柄

返回值:

  • 成功,返回 pdPASS ;
  • 失败,返回 errQUEUE_FULL 。


3. 获取二值信号量

1. BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore,
2.                     TickType_t xTicksToWait );

参数:

  • xSemaphore:要获取的信号量句柄
  • xTicksToWait:超时时间,0 表示不超时,portMAX_DELAY表示卡死等待;

返回值:

  • 成功,返回 pdPASS ;
  • 失败,返回 errQUEUE_FULL 。


计数型信号量实操

1.打开CubeMX,将FreeRTOS移植到STM32F103C8T6,具体看我之前写过的文章

将FreeRTOS移植到STM32F103C8T6

2.然后创建两个任务和设置按键引脚为输入,通过按键来放入和获取信号量

3.使能计数信号量

4.创建一个计数信号量,设置最多存放3个信号量,导出代码

5.进行代码编写

freertos.c

void StartTaskKey1(void const * argument)
{
  for(;;)
  {
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
    {
      osDelay(20);
      if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
      {
        if(xSemaphoreGive(myCountingSem01Handle) == pdTRUE) 
          printf("计数型信号量放入成功\r\n");
        else
          printf("计数型信号量放入失败\r\n");
      }
      while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET);
    }
    osDelay(10);
  }
}
 
void StartTaskKey2(void const * argument)
{
  for(;;)
  {
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
    {
      osDelay(20);
      if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
      { 
        if(xSemaphoreTake(myCountingSem01Handle,0) == pdTRUE) 
          printf("计数型信号量获取成功\r\n");
        else
          printf("计数型信号量获取失败\r\n");
      }
      while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET);
    }
    osDelay(10);
  }
}

6.编译烧录程序后打开串口助手(默认初始化已经放入3个信号量)

相关文章
|
4月前
CubeMXST32 FreeRTOS 信号量
CubeMXST32 FreeRTOS 信号量
62 11
|
6月前
|
C++
【操作系统】信号量机制(整型信号量、记录型信号量),用信号量实现进程互斥、同步、前驱关系
【操作系统】信号量机制(整型信号量、记录型信号量),用信号量实现进程互斥、同步、前驱关系
247 6
|
5月前
|
消息中间件 API
【FreeRTOS(二)】FreeRTOS新手入门——计数型信号量和二进制信号量的基本使用并附代码解析
【FreeRTOS(二)】FreeRTOS新手入门——计数型信号量和二进制信号量的基本使用并附代码解析
|
6月前
|
API 调度
【FreeRTOS】信号量的使用
【FreeRTOS】信号量的使用
|
Java
线程计数器的使用
线程计数器的使用
49 1
|
存储 NoSQL Linux
Linux进程信号(产生、保存、处理)/可重入函数概念/volatile理解/SIGCHLD信号
本篇文章重点详细地写了Linux进程信号的知识点:Linux进程信号的概念、信号产生的方式、信号传递和信号阻塞的原理、信号捕捉的方式、内核态、用户态、可重入函数的概念、volatile理解等等。
Linux进程信号(产生、保存、处理)/可重入函数概念/volatile理解/SIGCHLD信号
|
存储 网络协议 API
4-FreeRTOS队列、互斥、信号量
4-FreeRTOS队列、互斥、信号量
STM32FreeRTOS二值信号量的基本介绍和操作
STM32FreeRTOS二值信号量的基本介绍和操作
156 0