计数型信号量相当于队列长度大于1 的队列,因此计数型信号量能够容纳多个资源,这在计数型信号量被创建的时候确定的
使用计数型信号量的过程:创建计数型信号量 释放信号量 获取信号量
函数 | 描述 |
xSemaphoreCreateCounting() | 使用动态方法创建计数型信号量。 |
xSemaphoreCreateCountingStatic() | 使用静态方法创建计数型信号量 |
uxSemaphoreGetCount() | 获取信号量的计数值 |
此函数用于创建一个计数型信号量 。
#define xSemaphoreCreateCounting ( uxMaxCount , uxInitialCount) \
xQueueCreateCountingSemaphore((uxMaxCount) , (uxInitialCount))
形参 | 描述 |
uxMaxCount | 计数值的最大值限定 |
uxInitialCount | 计数值的初始值 |
返回值 | 描述 |
NULL | 创建失败 |
其他值 | 创建成功返回计数型信号量的句柄 |
此函数用于获取信号量当前计数值大小。
#define uxSemaphoreGetCount ( xSemaphore ) \
uxQueueMessagesWaiting(( QueueHandle_t) (xSemaphore))
形参 | 描述 |
xSemaphore | 信号量句柄 |
返回值 | 描述 |
整数 | 当前信号量的计数值大小 |
实验目的:学习 FreeRTOS 的计数型信号量相关API函数的使用
实验设计:将设计三个任务:start_task、task1、task2
三个任务的功能如下:
void freertos_demo(void)
{
xTaskCreate((TaskFunction_t )start_task, /* 任务函数 */
(const char* )"start_task", /* 任务名称 */
(uint16_t )START_STK_SIZE, /* 任务堆栈大小 */
(void* )NULL, /* 传入给任务函数的参数 */
(UBaseType_t )START_TASK_PRIO, /* 任务优先级 */
(TaskHandle_t* )&StartTask_Handler); /* 任务句柄 */
vTaskStartScheduler();
}
SemaphoreHandle_t CountSemaphore; /* 计数型信号量 */
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); /* 进入临界区 */
/* 创建计数型信号量 */
CountSemaphore = xSemaphoreCreateCounting((UBaseType_t )255,/* 计数型信号量最大值 */
(UBaseType_t )0); /* 计数型信号量初始值 */
if(CountSemaphore != NULL)
{
printf("计数型信号量创建成功\r\n");
}
/* 创建任务1 */
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1Task_Handler);
/* 创建任务2 */
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2Task_Handler);
vTaskDelete(StartTask_Handler); /* 删除开始任务 */
taskEXIT_CRITICAL(); /* 退出临界区 */
}
void task1(void *pvParameters)
{
uint8_t key = 0;
BaseType_t respond;
while (1)
{
key = key_scan(0);
if(key == KEY0_PRES)
{
respond = xSemaphoreGive(CountSemaphore); /* 释放计数型信号量 */
if(respond == pdTRUE)
{
printf("释放计数型信号量成功\r\n");
}
else printf("释放计数型信号量失败\r\n");
}
vTaskDelay(10);
}
}
void task2(void *pvParameters)
{
UBaseType_t semaphore_val = 0;
BaseType_t respond;
while (1)
{
respond = xSemaphoreTake(CountSemaphore, portMAX_DELAY); /* 获取计数型信号量 */
if(respond == pdTRUE)
{
printf("获取计数型信号量成功\r\n");
}
else printf("获取计数型信号量失败\r\n");
semaphore_val = uxSemaphoreGetCount(CountSemaphore);/* 获取计数型信号量资源数 */
printf("获取计数型信号量资源数为:%ld\r\n",semaphore_val);
vTaskDelay(1000);
}
}
造成上图的原因是 任务调度。本次实验仅涉及普通演示,如果想要深究可以看下面这篇,能解惑。
FreeRTOS 任务调度_freertos 调度-CSDN博客