目录
什么是计数型信号量?
计数型信号量相关 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.然后创建两个任务和设置按键引脚为输入,通过按键来放入和获取信号量
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");elseprintf("计数型信号量放入失败\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");elseprintf("计数型信号量获取失败\r\n");}while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET);}osDelay(10);}
}
6.编译烧录程序后打开串口助手(默认初始化已经放入3个信号量)