目录
一、任务通知
1、基本概念
FreeRTOS 从 V8.2.0 版本开始提供任务通知这个功能,每个任务都有 一个 32 位 的通知值,在大多数情况下,任务通知可以 替代二值信号量、计数信号量、事件组,也可以替代长度为 1 的队列(可以保存一个 32 位整数或指针值)。
相对于以前使用 FreeRTOS 内核通信的资源,必须创建队列、二进制信号量、计数信号量或事件组的情况,使用任务通知显然更灵活。按照 FreeRTOS 官方的说法,使用任务通知比通过信号量等 ICP 通信方式解除阻塞的任务要快 45%,并且更加省 RAM 内存空间(使用 GCC 编译器,-o2 优化级别),任务通知的使用无需创建队列。
想要使用任务通知,必须将 FreeRTOSConfig.h 中的宏定义 configUSE_TASK_NOTIFICATIONS 设置为 1,其实FreeRTOS 默认是为 1 的,所以任务通知是默认使能的。
FreeRTOS 提供以下几种方式发送通知给任务 :
- 发送通知给任务, 如果有通知未读,不覆盖通知值。
- 发送通知给任务,直接覆盖通知值。
- 发送通知给任务,设置通知值的一个或者多个位 ,可以当做事件组来使用。
- 发送通知给任务,递增通知值,可以当做计数信号量使用。
通过对以上任务通知方式的合理使用,可以在一定场合下替代 FreeRTOS 的信号量,队列、事件组等。
2、优势及限制
任务通知的优势:
- 效率更高:使用任务通知来发送事件、数据给某个任务时,效率更高。比队列、信号量、事件组都有大的优势。
- 更节省内存:使用其他方法时都要先创建对应的结构体,使用任务通知时无需额外创建结构体。
任务通知的限制:
- 不能发送数据给 ISR:ISR 并没有任务结构体,所以无法使用任务通知的功能给 ISR 发送数据。但是 ISR 可以使用任务通知的功能,发数据给任务。
- 数据只能给该任务独享
- 无法缓冲数据
- 无法广播给多个任务
- 如果发送受阻,发送方无法进入阻塞状态等待
3、通知状态和通知值
每个任务都有一个结构体:TCB(Task Control Block),里面有 2 个成员:
- 一个是 uint8_t 类型,用来表示通知状态
- 一个是 uint32_t 类型,用来表示通知值
typedef struct tskTaskControlBlock
{
......
/* configTASK_NOTIFICATION_ARRAY_ENTRIES = 1 */
volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
......
} tskTCB;
通知状态有 3 种取值:
taskNOT_WAITING_NOTIFICATION:任务没有在等待通知taskWAITING_NOTIFICATION:任务在等待通知taskNOTIFICATION_RECEIVED:任务接收到了通知,也被称为 pending(有数

最低0.47元/天 解锁文章
1549

被折叠的 条评论
为什么被折叠?



