其他分享
首页 > 其他分享> > FreeRTOS信号量相关API函数说明

FreeRTOS信号量相关API函数说明

作者:互联网

一、二值信号量

(1)创建二值信号量函数

// 函数说明:动态创建二值信号量(新版本)
// 参数:	无
// 返回值:  1.NULL:二值信号量创建失败  2.创建成功的二值信号量句柄
SemaphoreHandle_t   xSemaphoreCreateBinary(void)

// 函数说明:	动态创建二值信号量(旧版本)
// 参数:	xSemaphore:保存创建成功的二值信号量句柄
// 返回值:  1.NULL:二值信号量创建失败  2.其他值:二值信号量创建成功
SemaphoreHandle_t   vSemaphoreCreateBinary(SemaphoreHandle_t xSemaphore)

// 函数说明:静态创建二值信号量
// 参数:	pxSemaphoreBuffer: 指向一个StaticSemaphore_t 类型的变量,用来保存信号量结构体
// 返回值:  1.NULL:二值信号量创建失败  2.创建成功的二值信号量句柄
SemaphoreHandle_t   xSemaphoreCreateBinaryStatic(StaticSemaphore_t *pxSemaphoreBuffer)

(2)释放信号量函数

// 函数说明:释放信号量(任务中)
// 参数:	xSemaphore:要释放的信号量句柄
// 返回值:  1.pdPASS:释放信号量成功  2.errQUEUE_FULL:释放信号量失败
BaseType_t   xSemaphoreGive(xSemaphore)

// 函数说明:释放信号量(中断中)
// 参数:	1.xSemaphore:要释放的信号量句柄  2.pxHigherPriorityTaskWoken:标记退出此函数后是否进行任务切换
// 返回值:  1.pdPASS:释放信号量成功  2.errQUEUE_FULL:释放信号量失败
BaseType_t   xSemaphoreGiveFromISR(SemaphoreHandle_t   	xSemaphore,
									BaseType_t*			pxHigherPriorityTaskWoken)

(3)获取信号量函数

// 函数说明:获取信号量(任务中)
// 参数:	1.xSemaphore:要获取的信号量句柄 2.xBlockTime:阻塞时间
// 返回值:  1.pdPASS:获取信号量成功  2.pdFALSE:超时,获取信号量失败
BaseType_t   xSemaphoreTake(SemaphoreHandle_t   	xSemaphore,
							TickType_t				xBlockTime)

// 函数说明:获取信号量(中断中)
// 参数:	1.xSemaphore:要获取的信号量句柄  2.pxHigherPriorityTaskWoken:标记退出此函数后是否进行任务切换
// 返回值:  1.pdPASS:获取信号量成功  2.pdFALSE:获取信号量失败
BaseType_t   xSemaphoreTakeFromISR(SemaphoreHandle_t   	xSemaphore,
									BaseType_t*			pxHigherPriorityTaskWoken)

(4)删除信号量函数

// 函数说明:获取信号量(任务中)
// 参数:	1.xSemaphore:要删除的信号量句柄 
// 返回值:  无
void   vSemaphoreDelete(SemaphoreHandle_t   	xSemaphore)

(5)二值信号量操作实例
在开始任务中创建二值信号量;
在串口中断中释放信号量;(使用中断级释放信号量函数)
在任务函数中获取信号量,进行相关处理。

//声明二值信号量句柄(全局变量)
SemaphoreHandle_t BinarySemaphore;

//main函数
int main
{	/*
	*创建开始任务...
	*/
	vTaskStartScheduler();                    //开启任务调度
}

//开始任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();                      //进入临界区
	//创建二值信号量
	BinarySemaphore=xSemaphoreCreateBinary();
	/*
	*创建任务1、任务2...
	*/
	vTaskDelete(StartTask_Handler); //删除开始任务
	taskEXIT_CRITICAL();           //退出临界区
}

//任务1 函数
void DataProcess_task(void *pvParameters)
{
	BaseType_t err=pdFALSE;
	while(1)
	{if(BinarySemaphore!=NULL)  //二值信号量创建成功
	{
		err=xSemaphoreTake(BinarySemaphore,portMAX_DELAY);//获取信号量
		if(err==pdTRUE)//获取信号量成功
		{
			/*
			*进行相关操作
			*/
		}
	}
	else if(err==pdFALSE)  //二值信号量创建失败
	{
		vTaskDelay(10);            //延时10ms,也就是10个时钟节拍
	}
}

//释放二值信号量
void USART1_IRQHandler(void)                               //串口1中断服务程序
{
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
	{
		/*
		*串口接收相关操作
		*/
	}
	if((USART_RX_STA&0x8000)&&(BinarySemaphore!=NULL))//串口接收完成&&二值信号量创建成功
	{
		//释放二值信号量
		xSemaphoreGiveFromISR(BinarySemaphore,&xHigherPriorityTaskWoken);(1)
		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的话进行一次任务切换
	}
}

二、计数型信号量

(1)创建计数型信号量函数

// 函数说明:动态创建计数型信号量
// 参数:	1.uxMaxCount:计数信号量最大计数值,当信号量值等于此值的时候释放信号量就会失败。
//			2.uxInitialCount:计数信号量初始值。
// 返回值:  1.NULL:计数型信号量创建失败  2.其他值:创建成功的计数型信号量句柄
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, 
											UBaseType_t uxInitialCount )

// 函数说明:静态创建二值信号量
// 参数:	1.uxMaxCount:计数信号量最大计数值,当信号量值等于此值的时候释放信号量就会失败。
//			2.uxInitialCount:计数信号量初始值。
//			3.pxSemaphoreBuffer:指向一个StaticSemaphore_t类型的变量,用来保存信号量结构体。
// 返回值:  1.NULL:计数型信号量创建失败  2.其他值:创建成功的计数型信号量句柄
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, 
												UBaseType_t uxInitialCount, 
												StaticSemaphore_t *pxSemaphoreBuffer )

(2)释放 和 获取 计数型信号量函数

//同二值信号量!!!

(3)计数型信号量实例

//声明计数型信号量句柄(全局变量)
SemaphoreHandle_t CountSemaphore;//计数型信号量

//开始任务函数
void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();                      //进入临界区
	
	//创建计数型信号量(开始任务中)
	CountSemaphore=xSemaphoreCreateCounting(255,0);
	
	/*
	*创建任务1、任务2...
	*/
	vTaskDelete(StartTask_Handler); //删除开始任务
	taskEXIT_CRITICAL();           //退出临界区
}

//释放计数型信号量任务函数
void SemapGive_task(void *pvParameters)
{	u8 semavalue;
	while(1)
	{
		/*
		*其他操作...
		*/
		if(CountSemaphore!=NULL)   //计数型信号量创建成功
		{
			err=xSemaphoreGive(CountSemaphore);//释放计数型信号量
			if(err==pdFALSE)
			{printf("信号量释放失败!!!\r\n");}
			semavalue=uxSemaphoreGetCount(CountSemaphore);//获取计数型信号量值			  
			LCD_ShowxNum(155,111,semavalue,3,16,0);//显示信号量值
		}
	}
}

//获取计数型信号量任务函数
void SemapTake_task(void *pvParameters)
{
	u8 num;
	u8 semavalue;
	while(1)
	{
		xSemaphoreTake(CountSemaphore,portMAX_DELAY); //等待数值信号量
		num++;
		semavalue=uxSemaphoreGetCount(CountSemaphore); //获取数值信号量值
		LCD_ShowxNum(155,111,semavalue,3,16,0);         //显示信号量值
		LCD_Fill(6,131,233,313,lcd_discolor[num%14]);  //刷屏
		LED1=!LED1;
		vTaskDelay(1000);                             //延时1s,也就是1000个时钟节拍
	}
}

三、事件

四、任务通知

标签:函数,FreeRTOS,创建,void,信号量,计数,API,二值
来源: https://blog.csdn.net/weixin_43928734/article/details/110259734