FreeRTOS 计数型信号量 详解

目录

什么是计数型信号量?

计数型信号量相关 API 函数

1. 创建计数型信号量

2. 释放二值信号量

3. 获取二值信号量

计数型信号量实操


什么是计数型信号量?

计数型信号量相当于队列长度大于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. 获取二值信号量

BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore,
                    TickType_t xTicksToWait );

参数:

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

返回值:

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

计数型信号量实操

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

将FreeRTOS移植到STM32F103C8T6

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

FreeRTOS 计数型信号量 详解_第1张图片

3.使能计数信号量

FreeRTOS 计数型信号量 详解_第2张图片

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

FreeRTOS 计数型信号量 详解_第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个信号量)

FreeRTOS 计数型信号量 详解_第4张图片

你可能感兴趣的:(FreeRTOS,FreeRTOS,STM32)