计数型信号量简介:
计数型信号量的创建:
计数型信号量动态创建函数:
释放和获取信号量(与二值信号量相同)
释放信号量:
获取信号量:
测试实验
用按键来模拟事件,按键按下后表示有事件发生,则释放计数型信号量。
创建两个任务,任务1用于按键检测和释放信号量,按键2用于获取信号量。
测试程序如下所示:
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
count_semphr = xSemaphoreCreateCounting(5, 0);
if (count_semphr != NULL)
{
printf("计数型信号量创建成功\n");
}
else
{
printf("计数型信号量创建失败\n");
}
// 创建任务1
xTaskCreate((TaskFunction_t ) task1_task,
(char * ) "task1_task",
(uint16_t ) TASK1_TASK_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK1_TASK_PRIO,
(TaskHandle_t * ) &Task1_Handle);
// 创建任务2
xTaskCreate((TaskFunction_t )task2_task,
(char * )"task2_task",
(uint16_t )TASK2_TASK_SIZE,
(void * )NULL,
(UBaseType_t )TASK2_TASK_PRIO,
(TaskHandle_t * )&Task2_Handle);
taskEXIT_CRITICAL();
// 删除开始任务
vTaskDelete(Start_Task_Handle);
}
void task1_task(void *pvParameters)
{
BaseType_t error_state;
for (;;)
{
// 按键KEY1用于释放信号量
if (key_scan(KEY1_GPIO_Port, KEY1_Pin) == KEY_ON)
{
if (count_semphr != NULL)
{
error_state = xSemaphoreGive(count_semphr);
if (error_state == pdTRUE)
{
printf("信号量释放成功\n");
}
else
{
printf("信号量释放失败\n");
}
}
}
vTaskDelay(20);
}
}
void task2_task(void *pvParameters)
{
BaseType_t error_state;
UBaseType_t current_semphr_value;
for (;;)
{
// 按键KEY2用于获取信号量
if (key_scan(KEY2_GPIO_Port, KEY2_Pin) == KEY_ON)
{
if (count_semphr != NULL)
{
// 等待获取信号量
error_state = xSemaphoreTake(count_semphr, portMAX_DELAY);
if (error_state == pdTRUE)
{
printf("获取信号量成功\n");
current_semphr_value = uxSemaphoreGetCount(count_semphr);
printf("当前信号量计数值为%d\n", (int)current_semphr_value);
}
else
{
printf("获取信号量失败\n");
}
}
}
vTaskDelay(50);
}
}
测试结果: