|
|
@@ -24,13 +24,15 @@ FreeRTOS 已经有队列、信号量、事件标志组这些 IPC 机制,为什
|
|
|
|
|
|
### 基本原理
|
|
|
|
|
|
-每个 FreeRTOS 任务的 TCB(任务控制块)内部自带两个字段:
|
|
|
+每个 FreeRTOS 任务的 TCB 内部自带一组"通知"(Notifications),每个通知包含:
|
|
|
|
|
|
-- **`ulNotifiedValue`**:一个 32 位的通知值(可作计数器、位图、消息存储)
|
|
|
-- **`ucNotifyState`**:一个 8 位的通知状态(`taskNOT_WAITING_NOTIFICATION` / `taskWAITING_NOTIFICATION` / `taskNOTIFICATION_RECEIVED`)
|
|
|
+- **一个 32 位无符号整数**(可作计数器、位图、消息存储)
|
|
|
+- **一个通知状态**("待处理"或"非待定",标记是否有未读通知)
|
|
|
|
|
|
> `configTASK_NOTIFICATION_ARRAY_ENTRIES` 控制通知数组大小,默认 1。设为 N 时每个任务拥有 N 组独立通知值。FreeRTOS V10.4.0 之后支持此特性。
|
|
|
|
|
|
+**⚠ 注意:`xTaskNotifyGive()` 的本质**:查看源码发现 `xTaskNotifyGive()` 其实是一个**宏**,展开后等价于 `xTaskNotify(xTaskToNotify, 0, eIncrement)`。也就是说"信号量模式"在底层和"消息邮箱/事件组模式"使用的是同一个 `xTaskNotify()` 函数,只是 `eAction` 参数不同。三种模式的发送端完全可以统一理解为"调用 xTaskNotify 配上不同的 eAction 参数"。
|
|
|
+
|
|
|
**普通 IPC 的通信路径**:
|
|
|
```
|
|
|
任务 A → [创建队列/信号量对象] → 放入数据 → 队列/信号量 → 任务 B 取出数据
|
|
|
@@ -43,7 +45,7 @@ FreeRTOS 已经有队列、信号量、事件标志组这些 IPC 机制,为什
|
|
|
└── 不创建任何对象 ──┘
|
|
|
```
|
|
|
|
|
|
-这就是任务通知比队列/信号量快约 **45%** 的原因——省去了创建、操作、销毁内核对象的所有开销。
|
|
|
+这就是任务通知比队列/信号量**更轻量、更快**的原因——省去了创建、操作、销毁内核对象的所有开销。
|
|
|
|
|
|
### 通知的工作流程
|
|
|
|