FreeRTOS-计数信号量(三)

介绍计数信号量所用到的函数

1.创建计数信号量

SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,
										UBaseType_t uxInitialCount);

功 能:
		创建一个计数信号量。
参 数:
uxMaxCount: 计数信号量的最大值, 当达到这个值的时候,信号量不能再被释放。
uxInitialCount: 创建计数信号量的初始值。
返 回 值:
如果创建成功则返回一个计数信号量句柄,用于访问创建的计数信号量。
如果创建不成功则返回 NULL

2. 计数信号量的获取

 xSemaphoreTake( xSemaphore, xBlockTime )
 参数:
	xSemaphore:二值信号量句柄
	xBlockTime: portMAX_DELAY 既没有申请到资源阻塞,
				申请到立马返回
返回值:成功返回pdPASS	

3. 计数信号量的释放

xSemaphoreGive(SemaphoreHandle_t xSemaphore )
参数:
	xSemaphore :二值信号量句柄
返回值:成功返回pdPASS	

4. 代码

#include "main.h"

#define QUEUE_LEN_MAX 6
#define QUEUE_SIZE 4

void APP_TaskCreate(void *p);
void Recive_Task(void *p);
void Send_Task(void *p);
void All_Config(void);

TaskHandle_t APP_CreateHandle = NULL;
TaskHandle_t Send_CreateHandle = NULL;
TaskHandle_t Recive_CreateHandle = NULL;
SemaphoreHandle_t p_Semap = NULL;			


int main(void)
{
	BaseType_t Task_Ret = pdPASS;
	All_Config();

	Task_Ret = xTaskCreate(APP_TaskCreate,
							"App_TaskCreate",
							 32,
							 NULL,
							 2,
							 &APP_CreateHandle);
	
	if(Task_Ret == pdPASS)
	{
		printf("任务创建成功\r\n");
		vTaskStartScheduler();//开启任务调度
	}
}

/****************************
函数名称:APP_TaskCreate
函数作用:任务创建
函数参数:无
函数返回值:无
****************************/
void APP_TaskCreate(void *p) 
{
	taskENTER_CRITICAL();	//开启临界段
	BaseType_t Task_Ret = pdPASS;
	//创建计数信号量
	p_Semap = xSemaphoreCreateCounting(10,10);
	if(p_Semap == NULL)
		printf("创建计数信号量失败\r\n");
	else
		printf("创建计数信号量成功\r\n");

	Task_Ret = xTaskCreate(Send_Task,	//函数名称
							"Send_TaskCreate",		//任务名称
							512,									//任务堆栈大小
							NULL,									//传递给任务的参数
							3,										//优先级
							&Send_CreateHandle		//任务句柄
	);
	if(Task_Ret == pdPASS)
		printf("send任务创建成功\r\n");
	else
		printf("send任务创建失败\r\n");
		
	Task_Ret = xTaskCreate(Recive_Task,	//函数名称
							"Recive_TaskCreate",		//任务名称
							512,										//任务堆栈大小
							NULL,										//传递给任务的参数
							2,											//优先级
							&Recive_CreateHandle		//任务句柄
	);
	if(Task_Ret == pdPASS)
		printf("Recive任务创建成功\r\n");
	else
		printf("Recive任务创建失败\r\n");
	
	//删除本任务
	vTaskDelete(APP_CreateHandle);	
	printf("APP任务删除\r\n");
	taskEXIT_CRITICAL();		//关闭临界段
}

/****************************
函数名称:Recive_Task
函数作用:释放信号量(+1)
函数参数:无
函数返回值:无
****************************/
void Recive_Task(void *p) 
{
	BaseType_t Task_Ret = pdTRUE;
	while(1)
	{
		if(KEY_GetVal() == 1)
		{
			Task_Ret = xSemaphoreGive(p_Semap);//释放二值信号量
			if ( Task_Ret == pdTRUE )
				printf("释放一个车位!\r\n");
			else
				printf("已释放全部车位!\r\n");
		}
		
		vTaskDelay(20);//释放CPU
	}
}

/****************************
函数名称:Send_Task
函数作用:得到信号量(-1)
函数参数:无
函数返回值:无
****************************/
void Send_Task(void *p) 
{
	BaseType_t Task_Ret = pdPASS;
	uint8_t data = 0X00;

	while(1)
	{
		if((USART1->SR &(0X01<<5)))
		{
			data=USART1->DR;
			if(data == 'A')
			{
				data=0;
				Task_Ret = xSemaphoreTake(p_Semap,/* 二值信号量句柄 */
																			0); /* 等待时间 */
				
				if (Task_Ret == pdTRUE)
					printf("获得一个车位!\r\n");					
				else 
					printf("车位已满!\r\n");
			}
		}		
		vTaskDelay(20);//释放CPU
	}
}


void All_Config(void)
{
	NVIC_SetPriorityGrouping(5);
	BEEP_Config();
	LED_Config();
	KEY_Config();
	USART_Config(9600);
	printf("USART1 OK\r\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS 中的计数信号量是一种同步机制,用于在任务之间进行复杂的通信和同步。与二值信号量不同,计数信号量可以有多个状态,每个状态对应一个计数值。一个任务可以获取(占用)计数信号量,并且可以根据计数信号量计数值来决定是否要阻塞。 下面是使用 FreeRTOS 计数信号量的一般步骤: 1. 创建计数信号量:使用 xSemaphoreCreateCounting() 函数创建一个计数信号量。这个函数接受两个参数:最大计数值和初始计数值。最大计数值确定计数信号量的范围,而初始计数值确定创建时的计数值。 2. 获取计数信号量:在任务中使用 xSemaphoreTake() 函数来获取计数信号量。如果计数信号量计数值大于零,则该任务可以继续执行。如果计数值为零,则该任务将被阻塞,直到有其他任务释放计数信号量。 3. 释放计数信号量:在任务中使用 xSemaphoreGive() 函数来释放计数信号量。一旦释放了计数信号量,其计数值将增加。如果有等待该信号量的任务被阻塞,则其中一个任务将被唤醒,可以继续执行。 需要注意的是,可以使用 xSemaphoreGiveFromISR() 函数在中断服务子程序(ISR)中释放计数信号量,以便与中断处理程序配合使用。 计数信号量常用于以下情况: 1. 资源池管理:多个任务可以共享一个资源池,通过计数信号量来控制对资源的访问。每个任务获取资源时,计数值减少;释放资源时,计数值增加。 2. 有限资源管理:当系统中某些资源数量有限时,可以使用计数信号量来限制对资源的访问。当资源可用时,计数值大于零;当资源不可用时,计数值为零,任务需要等待。 3. 任务同步:多个任务可以使用计数信号量来同步它们的执行顺序。任务 A 可以获取计数信号量,只有当计数值大于零时,任务 B 才能获取计数信号量并继续执行。 FreeRTOS计数信号量功能灵活且易于使用,可以帮助开发者实现复杂的任务同步和资源管理。在使用时,应注意正确地获取和释放计数信号量,以避免死锁和竞争条件等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值