freerots学习(十)任务通知

一、什么是任务通知?

FreeRTOS 从版本 V8.2.0 开始提供任务通知这个功能,每个任务都有一个 32 位的通知值。按照
FreeRTOS 官方的说法,使用消息通知比通过二进制信号量方式解除阻塞任务快 45% , 并且更加
省内存(无需创建队列)。
在大多数情况下,任务通知可以替代二值信号量、计数信号量、事件标志组,可以替代长度为 1
的队列(可以保存一个 32 位整数或指针值),并且任务通知速度更快、使用的 RAM 更少!

二、任务通知值的更新方式

FreeRTOS 提供以下几种方式发送通知给任务 :
(1)发送消息给任务,如果有通知未读, 不覆盖通知值(类似队列)
(2)发送消息给任务,直接覆盖通知值
(3)发送消息给任务,设置通知值的一个或者多个位(类似事件标志组)
(4)发送消息给任务,递增通知值(信号量)
通过对以上方式的合理使用,可以在一定场合下替代原本的队列、信号量、事件标志组等。

三、任务通知的优势和劣势

任务通知的优势

1. 使用任务通知向任务发送事件或数据,比使用队列、事件标志组或信号量快得多。
2. 使用其他方法时都要先创建对应的结构体,使用任务通知时无需额外创建结构体。

任务通知的劣势

1. 只有任务可以等待通知,中断服务函数中不可以,因为中断没有 TCB
2. 通知只能一对一,因为通知必须指定任务。
3. 等待通知的任务可以被阻塞, 但是发送消息的任务,任何情况下都不会被阻塞等待。
4. 任务通知是通过更新任务通知值来发送数据的,任务结构体中只有一个任务通知值,只能保
持一个数据。

四、任务通知相关 API 函数

1. 发送通知

2. 等待通知

等待通知 API 函数只能用在任务,不可应用于中断中!

五、实操

1. 模拟二值信号量
2. 模拟计数型信号量
3. 模拟事件标志组
4. 模拟邮箱

六、Cubmax配置

创建两个任务即可

七、代码实现

二值和计数型信号量

/* USER CODE BEGIN Header_recive_fun */
/**
  * @brief  Function implementing the recive_task thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_recive_fun */
void recive_fun(void *argument)
{
  /* USER CODE BEGIN recive_fun */
  /* Infinite loop */
	uint32_t res = 0;
  for(;;)
  {
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==RESET)
		{
			osDelay(20);
			while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==RESET);
			osDelay(20);
			printf("KEY2 press down\r\n");
			
//			if(ulTaskNotifyTake(pdTRUE,portMAX_DELAY))
//			{
//					printf("recive succuse %d\r\n",res);
//			}
			res=ulTaskNotifyTake(pdFALSE,portMAX_DELAY);
			if(res)
			{
					printf("recive succuse %d\r\n",res);
			}
			
			else{
				printf("recive error\r\n");
			}
			
			
		}
  }
  /* USER CODE END recive_fun */
}

/* USER CODE BEGIN Header_send_fun */
/**
* @brief Function implementing the send_task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_send_fun */
void send_fun(void *argument)
{
  /* USER CODE BEGIN send_fun */
  /* Infinite loop */
  for(;;)
  {
		if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==RESET)
		{
			osDelay(20);
			while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==RESET);
			osDelay(20);
			
			printf("KEY1 press down\r\n");
			
			xTaskNotifyGive(recive_taskHandle);
			
			printf("send succuse\r\n");
			
		}
  }
  /* USER CODE END send_fun */
}


八、运行效果

模拟计数型信号量

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值