|
@@ -89,6 +89,9 @@ FreeRTOS 已经有队列、信号量、事件标志组这些 IPC 机制,为什
|
|
|
| `ulTaskNotifyTake()` | `xClearCountOnExit`, `xTicksToWait` | 接收通知(信号量模式),返回通知值 |
|
|
| `ulTaskNotifyTake()` | `xClearCountOnExit`, `xTicksToWait` | 接收通知(信号量模式),返回通知值 |
|
|
|
| `xTaskNotify()` | `xTaskToNotify`, `ulValue`, `eAction` | 发送通知(带值),eAction 控制写/OR/覆写行为 |
|
|
| `xTaskNotify()` | `xTaskToNotify`, `ulValue`, `eAction` | 发送通知(带值),eAction 控制写/OR/覆写行为 |
|
|
|
| `xTaskNotifyWait()` | `ulBitsToClearOnEntry`, `ulBitsToClearOnExit`, `pulNotificationValue`, `xTicksToWait` | 接收通知(带值),可获取通知值和清除指定位 |
|
|
| `xTaskNotifyWait()` | `ulBitsToClearOnEntry`, `ulBitsToClearOnExit`, `pulNotificationValue`, `xTicksToWait` | 接收通知(带值),可获取通知值和清除指定位 |
|
|
|
|
|
+| `xTaskNotifyIndexed()` | `xTaskToNotify, uxIndex, ulValue, eAction` | 写目标任务通知数组指定元素 |
|
|
|
|
|
+| `xTaskNotifyWaitIndexed()` | `uxIndex, ...` | 阻塞读本任务通知数组指定元素 |
|
|
|
|
|
+| `ulTaskNotifyTakeIndexed()` | `uxIndex, ...` | 信号量模式取通知数组指定元素 |
|
|
|
| `xTaskNotifyFromISR()` | 同上+ISR 版本 | 中断中发送通知 |
|
|
| `xTaskNotifyFromISR()` | 同上+ISR 版本 | 中断中发送通知 |
|
|
|
| `vTaskNotifyGiveFromISR()` | `xTaskToNotify`, `pxHigherPriorityTaskWoken` | 中断中发送(信号量模式) |
|
|
| `vTaskNotifyGiveFromISR()` | `xTaskToNotify`, `pxHigherPriorityTaskWoken` | 中断中发送(信号量模式) |
|
|
|
|
|
|
|
@@ -268,12 +271,109 @@ void task2(void *pvParameters)
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+### 实验4:xTaskNotifyIndexed — 通知数组 1对多 (P19)
|
|
|
|
|
+
|
|
|
|
|
+**需求**:KEY1 → task2 通知数组[0] = 10,KEY2 → task2 通知数组[1] = 20,KEY3 → task3 通知数组[0] = 99。每个任务通过 `xTaskNotifyWaitIndexed(index)` 阻塞读取指定数组元素。
|
|
|
|
|
+
|
|
|
|
|
+**原理**:`configTASK_NOTIFICATION_ARRAY_ENTRIES = 3` 使每个任务的 TCB 中有一个长度 3 的 `uint32_t` 通知数组。`xTaskNotifyIndexed(task, index, ...)` 本质是**写 task->notifications[index]**,`xTaskNotifyWaitIndexed(index, ...)` 本质是**阻塞读 task->notifications[index]**。
|
|
|
|
|
+
|
|
|
|
|
+**代码来源:**`22_EX_TaskNotify/Core/Src/freertos_demo.c`
|
|
|
|
|
+
|
|
|
|
|
+```c
|
|
|
|
|
+/* configTASK_NOTIFICATION_ARRAY_ENTRIES = 3 使每个任务拥有 3 个通知数组元素 */
|
|
|
|
|
+
|
|
|
|
|
+void task1(void *const pvParameters)
|
|
|
|
|
+{
|
|
|
|
|
+ uint8_t key = 0;
|
|
|
|
|
+ BaseType_t res = 0;
|
|
|
|
|
+ while (1)
|
|
|
|
|
+ {
|
|
|
|
|
+ key = Key_Detect();
|
|
|
|
|
+ if (key == KEY1_PRESS)
|
|
|
|
|
+ {
|
|
|
|
|
+ /* xTaskNotifyIndexed = 写 task2 通知数组[0] = 10(覆写) */
|
|
|
|
|
+ res = xTaskNotifyIndexed(
|
|
|
|
|
+ task2_handle, 0, 10, eSetValueWithOverwrite
|
|
|
|
|
+ );
|
|
|
|
|
+ if (res == pdPASS)
|
|
|
|
|
+ printf("task1: task2->通知数组[0] = 10\r\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (key == KEY2_PRESS)
|
|
|
|
|
+ {
|
|
|
|
|
+ /* xTaskNotifyIndexed = 写 task2 通知数组[1] = 20(覆写) */
|
|
|
|
|
+ res = xTaskNotifyIndexed(
|
|
|
|
|
+ task2_handle, 1, 20, eSetValueWithOverwrite
|
|
|
|
|
+ );
|
|
|
|
|
+ if (res == pdPASS)
|
|
|
|
|
+ printf("task1: task2->通知数组[1] = 20\r\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (key == KEY3_PRESS)
|
|
|
|
|
+ {
|
|
|
|
|
+ /* xTaskNotifyIndexed = 写 task3 通知数组[0] = 99(覆写) */
|
|
|
|
|
+ res = xTaskNotifyIndexed(
|
|
|
|
|
+ task3_handle, 0, 99, eSetValueWithOverwrite
|
|
|
|
|
+ );
|
|
|
|
|
+ if (res == pdPASS)
|
|
|
|
|
+ printf("task1: task3->通知数组[0] = 99\r\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ vTaskDelay(500);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void task2(void *const pvParameters)
|
|
|
|
|
+{
|
|
|
|
|
+ uint32_t notify_value = 0;
|
|
|
|
|
+ BaseType_t res = 0;
|
|
|
|
|
+ while (1)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("task2阻塞等待通知数组[0]...\r\n");
|
|
|
|
|
+
|
|
|
|
|
+ /* xTaskNotifyWaitIndexed(0) = 阻塞读通知数组[0],出口清零 */
|
|
|
|
|
+ res = xTaskNotifyWaitIndexed(
|
|
|
|
|
+ 0, 0x00000000, 0xffffffff, ¬ify_value, portMAX_DELAY
|
|
|
|
|
+ );
|
|
|
|
|
+ if (res == pdTRUE)
|
|
|
|
|
+ printf("task2: 通知数组[0] = %ld\r\n", notify_value);
|
|
|
|
|
+
|
|
|
|
|
+ printf("task2阻塞等待通知数组[1]...\r\n");
|
|
|
|
|
+
|
|
|
|
|
+ /* xTaskNotifyWaitIndexed(1) = 阻塞读通知数组[1],出口清零 */
|
|
|
|
|
+ res = xTaskNotifyWaitIndexed(
|
|
|
|
|
+ 1, 0x00000000, 0xffffffff, ¬ify_value, portMAX_DELAY
|
|
|
|
|
+ );
|
|
|
|
|
+ if (res == pdTRUE)
|
|
|
|
|
+ printf("task2: 通知数组[1] = %ld\r\n", notify_value);
|
|
|
|
|
+
|
|
|
|
|
+ vTaskDelay(200);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void task3(void *const pvParameters)
|
|
|
|
|
+{
|
|
|
|
|
+ uint32_t notify_value = 0;
|
|
|
|
|
+ BaseType_t res = 0;
|
|
|
|
|
+ while (1)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("task3阻塞等待通知数组[0]...\r\n");
|
|
|
|
|
+
|
|
|
|
|
+ /* xTaskNotifyWaitIndexed(0) = 阻塞读通知数组[0],出口清零 */
|
|
|
|
|
+ res = xTaskNotifyWaitIndexed(
|
|
|
|
|
+ 0, 0x00000000, 0xffffffff, ¬ify_value, portMAX_DELAY
|
|
|
|
|
+ );
|
|
|
|
|
+ if (res == pdTRUE)
|
|
|
|
|
+ printf("task3: 通知数组[0] = %ld\r\n", notify_value);
|
|
|
|
|
+
|
|
|
|
|
+ vTaskDelay(200);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
### 关键配置
|
|
### 关键配置
|
|
|
|
|
|
|
|
```c
|
|
```c
|
|
|
/* FreeRTOSConfig.h */
|
|
/* FreeRTOSConfig.h */
|
|
|
#define configUSE_TASK_NOTIFICATIONS 1 /* 使能任务通知(默认已使能) */
|
|
#define configUSE_TASK_NOTIFICATIONS 1 /* 使能任务通知(默认已使能) */
|
|
|
-#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 /* 通知数组大小,v10.4起支持多通知 */
|
|
|
|
|
|
|
+#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 /* 通知数组大小,v10.4起支持多通知。实验1-3用1,实验4用3 */
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
## 核心函数速查表
|
|
## 核心函数速查表
|