/** * OTA/表情包触发模块 - 不依赖 main_task,由 BLE 定时器回调直接启动 * 使用 xTaskCreate 动态创建任务(从堆分配栈),避免 PSRAM 不足导致 main_task 无法创建 */ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "event.h" #include "MQTT/mqtt.h" #include "config.h" #include "events_init.h" static const char *TAG = "ota_trigger"; #define OTA_TRIGGER_STACK 4096 /* 4KB 足够,xTaskCreate 从堆分配 */ static void ota_flow_task(void *arg) { ESP_LOGI(TAG, "OTA 流程任务启动"); if (is_system_sleeping) { ESP_LOGI(TAG, "OTA 收到时处于休眠,先唤醒系统"); toggle_sleep_mode(false); } if (!Get_MQTT_FLAG()) mqtt_main(); const TickType_t mqtt_wait_timeout = pdMS_TO_TICKS(60000); TickType_t wait_start = xTaskGetTickCount(); while (!Get_MQTT_FLAG()) { vTaskDelay(pdMS_TO_TICKS(500)); if ((xTaskGetTickCount() - wait_start) >= mqtt_wait_timeout) { ESP_LOGW(TAG, "等待 MQTT 超时,退出 OTA 流程"); vTaskDelete(NULL); return; } } if (Get_MQTT_FLAG()) { ESP_LOGI(TAG, "订阅 OTA 更新主题"); if (subscribe_ota() == ESP_OK) ESP_LOGI(TAG, "成功订阅 OTA 更新主题"); } vTaskDelete(NULL); } static void emoji_flow_task(void *arg) { char pack = (char)(uintptr_t)arg; char filename_emoji[64]; snprintf(filename_emoji, sizeof(filename_emoji), "icar/%c.zip", pack != '0' ? pack : 'A'); ESP_LOGI(TAG, "表情包下载流程启动: %s", filename_emoji); if (is_system_sleeping) { ESP_LOGI(TAG, "表情包下载时处于休眠,先唤醒系统"); toggle_sleep_mode(false); } if (!Get_MQTT_FLAG()) mqtt_main(); TickType_t wait_start = xTaskGetTickCount(); const TickType_t mqtt_wait_timeout = pdMS_TO_TICKS(60000); while (!Get_MQTT_FLAG()) { vTaskDelay(pdMS_TO_TICKS(500)); if ((xTaskGetTickCount() - wait_start) >= mqtt_wait_timeout) { ESP_LOGW(TAG, "等待 MQTT 超时,退出表情下载流程"); vTaskDelete(NULL); return; } } if (Get_MQTT_FLAG()) publish_json_download(filename_emoji); vTaskDelete(NULL); } void ota_trigger_start_ota(void) { BaseType_t ret = xTaskCreate(ota_flow_task, "ota_flow", OTA_TRIGGER_STACK, NULL, 5, NULL); if (ret != pdPASS) ESP_LOGE(TAG, "创建 OTA 流程任务失败"); else ESP_LOGI(TAG, "OTA 流程任务已创建"); } void ota_trigger_start_emoji(char pack) { BaseType_t ret = xTaskCreate(emoji_flow_task, "emoji_flow", OTA_TRIGGER_STACK, (void *)(uintptr_t)pack, 5, NULL); if (ret != pdPASS) ESP_LOGE(TAG, "创建表情包下载任务失败"); else ESP_LOGI(TAG, "表情包下载任务已创建"); }