当前位置: 代码迷 >> 综合 >> 从0到1学习FreeRTOS:FreeRTOS 内核应用开发:(二十三)任务通知 NO.1 基本概念
  详细解决方案

从0到1学习FreeRTOS:FreeRTOS 内核应用开发:(二十三)任务通知 NO.1 基本概念

热度:78   发布时间:2023-12-16 14:08:53.0

从0到1学习FreeRTOS:FreeRTOS 内核应用开发:(二十三)任务通知 NO.1 基本概念

 

一、任务通知的基本概念:

       每个任务都有一个 32 位的通知值,在大多数情况下,任务通知可以替代二值信号量、计数信号量、事件组, 也可以替代长度为 1 的队列(可以保存一个 32 位整数或指针值) 。
       相对于以前使用 FreeRTOS 内核通信的资源,必须创建队列、二进制信号量、计数信号量或事件组的情况,使用任务通知显然更灵活。 按照 FreeRTOS 官方的说法,使用任务通知比通过信号量等 ICP 通信方式解除阻塞的任务要快 45%,并且更加省 RAM 内存空间(使用 GCC 编译器, -o2 优化级别) ,任务通知的使用无需创建队列。 想要使用任务通知,必须将 FreeRTOSConfig.h 中的宏定义 configUSE_TASK_NOTIFICATIONS 设置为 1,其实FreeRTOS 默认是为 1 的, 所以任务通知是默认使能的。
       FreeRTOS 提供以下几种方式发送通知给任务

  •  发送通知给任务, 如果有通知未读,不覆盖通知值。
  •  发送通知给任务,直接覆盖通知值。
  •  发送通知给任务,设置通知值的一个或者多个位 ,可以当做事件组来使用。
  •  发送通知给任务,递增通知值,可以当做计数信号量使用。

通过对以上任务通知方式的合理使用,可以在一定场合下替代 FreeRTOS 的信号量,队列、事件组等。
当然, 凡是都有利弊,不然的话 FreeRTOS 还要内核的 IPC 通信机制干嘛, 消息通知虽然处理更快, RAM 开销更小,但也有以下限制 

  •  只能有一个任务接收通知消息, 因为必须指定接收通知的任务。。
  •  只有等待通知的任务可以被阻塞, 发送通知的任务,在任何情况下都不会因为发送失败而进入阻塞态。

二、任务通知的运作机制:

       顾名思义,任务通知是属于任务中附带的资源, 所以在任务被创建的时候,任务通知也被初始化的,那是因为任务通知的数据结构包含在任务控制块中,只要任务存在,任务通知数据结构就已经创建完毕,可以直接使用
       如果任务在等待的通知暂时无效,任务会根据用户指定的阻塞超时时间进入阻塞状态我们可以将等待通知的任务看作是消费者;其它任务和中断可以向等待通知的任务发送通知,发送通知的任务和中断服务函数可以看作是生产者,当其他任务或者中断向这个任务发送任务通知,任务获得通知以后,该任务就会从阻塞态中解除,这与 FreeRTOS 中内核的其他通信机制一致。
总结:

  • 无需创建;
  • 中断/任务均能发送通知;
  • 只有在任务中可以等待通知,而不允许在中断中等待通知。

三、任务通知的数据结构:

#if( configUSE_TASK_NOTIFICATIONS == 1 )

   volatile uint32_t ulNotifiedValue; 任务通知的值, 可以保存一个 32 位整数或指针值。

   volatile uint8_t ucNotifyState; 任务通知状态, 用于标识任务是否在等待通知。

#endif