2021-05-23 FREERTOS 任务通知—模拟二值信号量—模拟计数型信号量

任务通知—模拟二值信号量
描述:每一个任务都有一个32位的任务通知值,任务控制块中的成员变量ulnotifiedValue就是这个值。
任务通知时一个事件,某个任务因为等待接收事件而阻塞的话,则接收到任务通知之后则会解除阻塞。
**特点:**比普通二值信号量的解除阻塞时间快50%,减少了大量代码,减少了内存占用。
**缺点:**任务的接收通知只能是指定的一个任务接收,不能多个任务接收。
接收通知可以进入阻塞状态,发送通知不会进入阻塞状态。

**vTaskNotifyGiveFromISR();**发送通知 不带通知的值也不保留接收任务的通知值

void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken )

在这里插入图片描述
例子:

extern TaskHandle_t BATTERYTask_Handler;//任务句柄

void USART2_IRQHandler(void)                	//串口2中断服务程序
{
	BaseType_t xHigherPriorityTaskWoken;
	xHigherPriorityTaskWoken=pdFALSE;
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
  {
		RxBuffer2[RxCounter2++] = USART_ReceiveData(USART2);
		if(RxCounter2>7||RxBuffer2[7]==0xff)//判断结束标志 
			if(BATTERYTask_Handler!=NULL)
			{
				vTaskNotifyGiveFromISR(BATTERYTask_Handler,&xHigherPriorityTaskWoken);//通知到电池任务
			    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);		
			}
			//USART2_data(RxBuffer2,8);
			memset(RxBuffer2,0,8);
			RxCounter2=0;
	 }
  }

ulTaskNotifyTake() 任务通知接收
在这里插入图片描述

在这里插入图片描述返回值:任务通知值减少或者清零之前的值,例如pdTRUE则清零之后为0,清零之前大于等于1,pdFALSE则为减1之前的值。

void battery_task(void *pvParameters)//计数型信号量的验证
{	
	 u32 Notify_value=0;//任务通知
   while(1)
   {
		 Notify_value=ulTaskNotifyTake(pdTRUE,portMAX_DELAY);//读取任务通知的值,pdTRUE表示清零
		 if(Notify_value==1)//清零之前的值是否为1
		 {
 			//发送数据帧电量显示
 		  TxBuffer2[0]='S';
 		  TxBuffer2[1]=6;
 		 if(Battery_Update())
 			{
 			  adcdata = (float)Battery_AdcValue/65535.0f;  //16位精度
 			  adcdata *= 3.0f;   //参考电压
 			  adcdata *= 11;     //电路放大倍数
 			  adcdata *= 10;     //发送放大倍数
 			  temp = (u16)adcdata;
 			  TxBuffer2[2] = temp/10;
 			  TxBuffer2[3] = temp%10;
 			}
 			else
 			{
 			   while (DMA_GetFlagStatus(DMA2_Stream4,DMA_FLAG_TCIF4) == RESET){}
 		     tmp = AverageVal(ADC1ConvertedValue,5);	
 				 TxBuffer2[2] = tmp/nUNIT;//电量整数部分	
 			   TxBuffer2[3] = 10*(tmp%nUNIT)/nUNIT;//电量小数部分,精确到点后一位
 		  } 
 			  CRC_check(TxBuffer2,5);//校验和(注:校验和本身之前的所有数据之和)
 		    TxBuffer2[5]='E';
			  //vTaskList(InfoBuffer);							//获取所有任务的信息
 			  USART2_data(TxBuffer2,6);
		}
		 else 
        vTaskDelay(180);			    
 	 }
    	
}
 if(Notify_value==1)
	 {
	 }

//清零之前的值为发送通知的值,这个值会累加,例如串口发送的时间间隔为10ms,处理数据的时间为100ms,则任务通知的值会大于5小于10

模拟计数型信号量
模拟计数型信号量的特点与二值信号量两个函数一样,区别在于接收任务通知的时候只能用于一个函数,而且每次接收任务通知之后这个值减1.
直到这个值为0则进入阻塞状态。

Notify_value=ulTaskNotifyTake(pdFALSE,portMAX_DELAY);//读取任务通知的值,pdFALSE表示减1
vTaskNotifyGiveFromISR(BATTERYTask_Handler,&xHigherPriorityTaskWoken);//通知到电池任务 每次加1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值