目录
什么是计数型信号量?
计数型信号量相关 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");
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个信号量)