好比一个停车场,停车场里面有 10 个车位,当车进入的时候,车位被占用一个,计数器减一;车开出去的时候,车位被是释放,计数器加一。这就是计数型的信号量。当信号量为零时,则表名停车场内已经没有可用车位。
4.11 uxSemaphoreGetCount()
[[FreeRTOS_Reference_Manual_V10.0.0.pdf#page=234&selection=2,0,4,21|FreeRTOS_Reference_Manual_V10.0.0, page 234]]
4.4 xSemaphoreCreateCounting()
[[FreeRTOS_Reference_Manual_V10.0.0.pdf#page=218&selection=2,0,4,26|FreeRTOS_Reference_Manual_V10.0.0, page 218]]
xSemaphoreCreateCounting()#include "FreeRTOS.h"
#include "semphr.h"
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount );
函数说明:
参数:
uxMaxCount: 计数型信号量的计数最大值。uxInitialCount:创建信号量时赋予的计数值。返回值:
NULL:如果没有足够的堆内存,则信号量创建失败。Any other value:信号量成功创建。注意事项:
event handler -> Give, task handler -> take)uxSemaphoreGetCount()#include "FreeRTOS.h"
#include "semphr.h"
UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
函数说明:
参数:
xSemaphore:信号量的句柄。返回值:
此代码模拟了一个停车场(资源管理型),两个任务函数分别模拟车进车出,用信号量当前值表示为停车场剩余空间,用信号量最大值表示停车场总共空间。
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
static SemaphoreHandle_t semaphore_handle;
void car_in(void *pvPara)
{
int empty_space = 0;
while (true) {
// 获取停车场剩余空间
empty_space = uxSemaphoreGetCount(semaphore_handle);
printf("empty_space = %d\n", empty_space);
// 从停车场拿走一个空间用来停车 ( Take )
xSemaphoreTake(semaphore_handle, portMAX_DELAY);
if (semaphore_state == pdPASS) {
printf("[CAR IN]: One car in.\n");
} else {
printf("[CAR IN]: No more empty space.\n");
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void car_out(void *pvPara)
{
while (true) {
vTaskDelay(pdMS_TO_TICKS(6000));
// 车要走了,所以给停车场还回去一个车位( Give )
xSemaphoreGive(semaphore_handle);
printf("[CAR OUT]: One car out\n");
}
}
void app_main(void)
{
// 创建技术型信号量,初始值为10,最大值为10。即 停车场初始有 10 个空位,一共有 10 个车位
semaphore_handle = xSemaphoreCreateCounting(10, 10);
xTaskCreate(car_in, "Car In", 2048, (void *)semaphore_handle, 1, NULL);
xTaskCreate(car_out, "car Out", 2048, (void *)semaphore_handle, 1, NULL);
}

程序输出结果表明,停车场运行正常,车停满之后就等待位置空出来,新的车再进去。