ESP32 RTOS 任务同步与消息通信篇概述
概述
在 RTOS 系统中,任务之间、任务和中断服务之间必然需要交互信息,以此来完成整体的系统功能。
交互信息的目的可以是协调程序运行的先后顺序(称为任务同步),也可能是传递一块数据(称为消息通信)。总之在这样一个交互信息的过程中,有生产数据的一方,被称为“生产者“,有获取数据的一方,被称为”消费者“:
为了满足任务之间、任务与中断之间交互信息的需求,RTOS 中提供了很多适合各个场景的组件,从本小节开始,我们将介绍各个组件典型的用法和示例。
最简单的通信-全局变量
全局变量(比如,全局的 int 变量、数组、结构体、内存块)可以充当消息传递的组件,在任务之间传递数据。
全局变量虽然可以传递数据,但却不能实现类似任务通知超时等待的机制。因为生产者在对全局变量更新后,并不能自动通知使用该全局变量的消费者。除非消费者主动轮询该全局变量,否则无法获取更新。
RTOS 中提供了信号量、事件组、队列等机制可以实现延时等待、通知更新的目的,因此比全局变量的功能更为强大,我们将在后续的章节中逐一介绍它们。
示例解析
示例中通过将任务1的内部变量 task1_flag 的值拷贝到全局变量 global_count 中,使得任务2能够知晓任务1中 task_flag1 的值。并针对 task_flag1 的值运行不同的程序(提取其最高位的数值)。
示例输出:
Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, Minimum free heap size: 295356 bytes
TASK2: get task1_flag=5, high_bit_val=5
TASK1: give sem, flag=5
TASK2: get task1_flag=5, high_bit_val=5
TASK1: give sem, flag=10
TASK2: get task1_flag=10, high_bit_val=1
TASK1: give sem, flag=15
TASK2: get task1_flag=15, high_bit_val=1
TASK2: get task1_flag=15, high_bit_val=1
TASK1: give sem, flag=20
TASK2: get task1_flag=20, high_bit_val=2
讨论
当不需要超时机制、通知机制的前提下,且传输的数据量不大时,采用全局变量可以实现任务之间数据通信的情况。
总结
1)RTOS 中提供了很多用于任务与任务之间、任务与中断之间交互信息的组件。通常更新数据的一方称为生产者、使用数据的一方称为消费者。
2)交互信息的目的可以是同步、或者传递数据。
2)全局变量(包括全局的 int 变量、数组、结构体、内存块)可以实现简单的信息交互,但没有实现超时检测、更新通知的机制。
资源链接
1)Learning-FreeRTOS-with-esp32 系列博客介绍
2)对应示例的 code 链接 (点击直达代码仓库)
3)下一篇:使用二值信号量实现任务间单向同步