FreeRTOS 计数型信号量

admin2024-09-05  25

计数型信号量

        计数型信号量相当于队列长度大于1 的队列,因此计数型信号量能够容纳多个资源,这在计数型信号量被创建的时候确定的 

计数型信号量适用场合:

  • 事件计数:当每次事件发生后,在事件处理函数中释放计数型信号量(计数值+1),其他任务 会获取计数型信号量(计数值-1) ,这种场合一般在创建时将初始计数值设置为 0
  • 资源管理:信号量表示有效的资源数目。任务必须先获取信号量(信号量计数值-1 )才能获取资源控制权。当计数值减为零时表示没有的资源。当任务使用完资源后,必须释放信号量(信号量计数值+1)。信号量创建时计数值应等于最大资源数目

计数型信号量相关API函数 

 使用计数型信号量的过程:创建计数型信号量 FreeRTOS 计数型信号量,\rightarrow,第1张释放信号量 FreeRTOS 计数型信号量,\rightarrow,第1张 获取信号量

函数

描述

xSemaphoreCreateCounting()

使用动态方法创建计数型信号量。

xSemaphoreCreateCountingStatic()

使用静态方法创建计数型信号量

uxSemaphoreGetCount()

获取信号量的计数值

计数型信号量创建API函数

此函数用于创建一个计数型信号量 。

#define xSemaphoreCreateCounting     ( uxMaxCount  ,  uxInitialCount)   		\		            
        xQueueCreateCountingSemaphore((uxMaxCount) , (uxInitialCount)) 

形参

描述

uxMaxCount

计数值的最大值限定

uxInitialCount

计数值的初始值

返回值

描述

NULL

创建失败

其他值

创建成功返回计数型信号量的句柄

获取信号量的计数值API函数

 此函数用于获取信号量当前计数值大小。

#define uxSemaphoreGetCount   (  xSemaphore   ) 					\		 
        uxQueueMessagesWaiting(( QueueHandle_t) (xSemaphore))

形参

描述

xSemaphore

信号量句柄

返回值

描述

整数

当前信号量的计数值大小

计数型信号量实验

实验目的:学习 FreeRTOS 的计数型信号量相关API函数的使用

实验设计:将设计三个任务:start_task、task1、task2

三个任务的功能如下:

  • start_task:用来创建其他的2个任务
  • task1:用于按键扫描,当检测到按键KEY0被按下时,释放计数型信号量
  • 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 计数型信号量,第3张

FreeRTOS 计数型信号量,第4张 

         造成上图的原因是 任务调度。本次实验仅涉及普通演示,如果想要深究可以看下面这篇,能解惑。

FreeRTOS 任务调度_freertos 调度-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!