static TaskHandle_t xTaskWait = NULL; // 等待任务句柄
static TaskHandle_t xTaskGive = NULL; // 发送任务句柄

#define LOWTHREEBITS ( 1UL << 0UL )|( 1UL << 1UL )|( 1UL << 2UL )

// 等待直达任务通知的线程
void wait_task(void *param_t){
  uint32_t ulNotificationValue;   // 任务通知数据
  BaseType_t xResult;             // 任务通知是否已经挂起

  while(1){
    printf("[WAIT] 等待任务通知到达...\n");
    xResult = xTaskNotifyWait(0x00,                 // 在运行等待通知之前需要清零的位
                              0x00,                 // 在获取通知之后需要清零的位
                              &ulNotificationValue, // 记录任务通知的值
                              portMAX_DELAY);       // 等待超时时间
    if(xResult){
      // 如果正常等到了通知,则将受到的值打印出来。
      char bin_str[33];
      itoa(ulNotificationValue, bin_str, 2);
      printf("[WAIT] 收到任务通知:%s\n", bin_str);
    }else{
      printf("[WAIT] 任务通知等待超时!");
    }
  }
}

// 发送直达任务通知的线程
void give_task(void *param_t){
  pinMode(4, INPUT_PULLUP);
  BaseType_t xResult;

  while(1){
    if (digitalRead(4) == LOW) {
      xResult=xTaskNotify(xTaskWait, 0, eIncrement);     // eIncrement 方式每次对值进行+1操作
      // xResult=xTaskNotify(xTaskWait, 0, eNoAction);      // eNoAction 不设置任何值,只对通知进行一次挂起操作
      // xResult=xTaskNotify(xTaskWait, (1UL<<4UL), eSetBits); // eSetBits 表示要设置某些值为1,如果多次设置,不进行覆盖,而是进行 或 操作
      // xResult=xTaskNotify(xTaskWait, LOWTHREEBITS, eSetValueWithOverwrite );    // eSetValueWithOverwrite 将覆盖原来设置的值
      // xResult=xTaskNotify(xTaskWait, LOWTHREEBITS, eSetValueWithoutOverwrite);   // eSetValueWithoutOverwrite 表示如果之前的值已经被处理过了,则覆盖,如果没有被处理,则不进行覆盖,并返回发送失败

      printf("[GIVE] 任务通知发送:%s\n", xResult?"成功":"失败");
      vTaskDelay(100);
    }
    vTaskDelay(100);
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println("Hello, ESP32-S3!");
  printf("是否开启了直达任务通知: %s\n", configUSE_TASK_NOTIFICATIONS?"YES":"NO");
  printf("每个任务通知ID数量:%d\n", configTASK_NOTIFICATION_ARRAY_ENTRIES);

  // 启动两个线程
  xTaskCreate(wait_task, "WAIT", 10240, NULL, 1, &xTaskWait);
  xTaskCreate(give_task, "GIVE", 10240, NULL, 1, &xTaskGive);

  vTaskDelete(NULL);   // 自宫
}

void loop() {
  delay(100);
}
esp:0
esp:1
esp:2
esp:3
esp:4
esp:5
esp:6
esp:7
esp:8
esp:9
esp:10
esp:11
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:20
esp:21
esp:35
esp:36
esp:37
esp:38
esp:39
esp:40
esp:41
esp:42
esp:45
esp:46
esp:47
esp:48
esp:3V3.1
esp:3V3.2
esp:RST
esp:5V
esp:GND.1
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:GND.4
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r