FreeRTOS-二值信号量(四)

本文介绍FreeRTOS中二值信号量的使用方法,包括信号量的创建、获取和释放,并通过实例代码展示了如何在任务间使用二值信号量进行同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先介绍二值信号量用到的几个函数

1. 二值信号量的创建

xSemaphoreCreateBinary();//创建二值信号量

参数:无
返回值:返回一个二值信号量的句柄

2. 二值信号量的获取

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

3. 二值信号量的释放

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

4. 代码

#include "main.h"
#include "semphr.h"//二值信号量头文件

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

TaskHandle_t APP_CreateHandle = NULL;//创建任务句柄
TaskHandle_t Send_CreateHandle = NULL;//发送任务句柄
TaskHandle_t Recive_CreateHandle = NULL;//接收任务句柄

SemaphoreHandle_t BinarySem_Handle = NULL;//二值信号量句柄

#define QUEUE_LEN_MAX 6
#define QUEUE_SIZE 4

int main(void)
{
	BaseType_t Task_Ret = pdPASS;//定义一个创建信息返回值,默认为 pdPASS
	All_Config();

	Task_Ret = xTaskCreate(APP_TaskCreate,// 任务入口函数
						  "App_TaskCreate",//任务名字
						  32,//任务栈大小
						  NULL,//任务入口函数参数
						  1,//任务的优先级
						  &APP_CreateHandle);//任务控制块指针
	
	if(Task_Ret == pdPASS)
	{
		printf("任务创建成功\r\n");
		vTaskStartScheduler();//开启任务调度
	}
	else
		return -1;
}

/****************************
函数名称:APP_TaskCreate
函数作用:任务创建
函数参数:无
函数返回值:无
****************************/
void APP_TaskCreate(void *p) 
{
	taskENTER_CRITICAL();	//开启临界段
	BaseType_t Task_Ret = pdPASS;	//定义返回值默认为 pdPASS

	BinarySem_Handle = xSemaphoreCreateBinary();//创建二值信号量
	
	if (NULL != BinarySem_Handle)
		printf("BinarySem_Handle 二值信号量创建成功!\r\n");

	Task_Ret = xTaskCreate(Send_Task,		//函数名称
							"Send_TaskCreate",			//任务名称
							512,//任务堆栈大小
							NULL,//传递给任务的参数
							3,	//优先级
							&Send_CreateHandle			//任务句柄
	);
	
	if(Task_Ret == pdPASS)
		printf("send任务创建成功\r\n");

	Task_Ret = xTaskCreate(Recive_Task,	//函数名称
							"Recive_TaskCreate",		//任务名称
							512,										//任务堆栈大小
							NULL,									  //传递给任务的参数
							2,										  //优先级
							&Recive_CreateHandle		//任务句柄
	);
	if(Task_Ret == pdPASS)
		printf("Recive任务创建成功\r\n");

	vTaskDelete(APP_CreateHandle);		//删除本任务
	taskEXIT_CRITICAL();							//关闭临界段
}

/****************************
函数名称:Recive_Task
函数作用:获取信号量(-1)
函数参数:无
函数返回值:无
****************************/
void Recive_Task(void *p) 
{
	BaseType_t Task_Ret = pdPASS;//定义一个创建信息返回值,默认为pdPASS
	while(1)
	{
		//获取二值信号量 xSemaphore,没获取到则一直等待
		Task_Ret = xSemaphoreTake(BinarySem_Handle,//二值信号量句柄
															portMAX_DELAY);	//等待时间
		if(Task_Ret == pdPASS)
		{
			printf("获取二值信号量成功\r\n");
			LED1_TOGGLE;
			BEEP_TOGGLE;
		}		
		vTaskDelay(500);//释放CPU
	}
}

/****************************
函数名称:Send_Task
函数作用:释放信号量(二值信号量+1)
函数参数:无
函数返回值:无
****************************/
void Send_Task(void *p) 
{
	BaseType_t Task_Ret = pdPASS;//定义一个创建信息返回值,默认为 pdPASS

	while(1)
	{
		if(!KEY1)	//如果按键按下
		{
			Task_Ret = xSemaphoreGive(BinarySem_Handle);//释放二值信号量
			if(Task_Ret == pdPASS)
				printf("释放二值信号量成功\r\n\r\n");
			else
				printf("释放二值信号量失败\r\n\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");
}

总结

其实我发现代码层面上,FreeRTOS有着自己一套的框架,不同信号量用不同的函数填充进去,代码还是很容易写的。之后再更新几篇理论,或者需要注意的要点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值