2026-07-15 02:23:25 +08:00
|
|
|
|
/*
|
2026-04-27 00:42:26 +08:00
|
|
|
|
* ESP32-C3FH4 OTA 中继 - 程序入口
|
2026-05-31 03:20:26 +08:00
|
|
|
|
*
|
2026-07-17 02:02:36 +08:00
|
|
|
|
* 初始化顺序(每位成功后 SystemBoot::mark=1,末尾统一 report):
|
|
|
|
|
|
* 1. 冷启动延时
|
|
|
|
|
|
* 2. netif / event_loop / debug_log
|
|
|
|
|
|
* 3. wifi earlyInit
|
|
|
|
|
|
* 4. health_mon + task
|
|
|
|
|
|
* 5. cpu_stats(可选)
|
|
|
|
|
|
* 6. protocol / ota_coord
|
|
|
|
|
|
* 7. spi init + L0 本机自检 → mark spi;HELLO 对端轻检 → mark can_link(非关键)
|
|
|
|
|
|
* 8. ota_relay / wifi_ota / ble_ota 任务
|
|
|
|
|
|
* 9. can_fb 任务(依赖 spi L0)
|
|
|
|
|
|
* 10. ota_mark_valid(可选)
|
|
|
|
|
|
* 11. SystemBoot::report()
|
2026-04-27 00:42:26 +08:00
|
|
|
|
*/
|
|
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
|
|
|
|
#include "freertos/task.h"
|
2026-04-28 01:06:17 +08:00
|
|
|
|
#include "esp_system.h"
|
|
|
|
|
|
#include "esp_netif.h"
|
2026-05-05 03:28:44 +08:00
|
|
|
|
#include "esp_event.h"
|
2026-06-14 17:10:24 +08:00
|
|
|
|
#include "esp_ota_ops.h"
|
2026-04-27 00:42:26 +08:00
|
|
|
|
|
2026-07-17 02:02:36 +08:00
|
|
|
|
#include "system_boot.h"
|
2026-04-27 02:34:47 +08:00
|
|
|
|
#include "monitor/health_monitor.h"
|
2026-07-16 01:24:12 +08:00
|
|
|
|
#include "monitor/cpu_stats.h"
|
2026-04-27 02:34:47 +08:00
|
|
|
|
#include "relay/ota_relay.h"
|
2026-06-17 02:18:42 +08:00
|
|
|
|
#include "ota/ota_coordinator.h"
|
2026-04-27 02:34:47 +08:00
|
|
|
|
#include "transport/spi_master.h"
|
|
|
|
|
|
#include "server/wifi_ota.h"
|
|
|
|
|
|
#include "server/ble_ota.h"
|
|
|
|
|
|
#include "transport/protocol.h"
|
|
|
|
|
|
#include "monitor/debug_log.h"
|
2026-06-14 17:10:24 +08:00
|
|
|
|
#include "app_config.h"
|
2026-06-22 01:53:16 +08:00
|
|
|
|
#include "ota/esp32_ota_core.h"
|
2026-06-29 01:51:44 +08:00
|
|
|
|
#include "monitor/can_feedback_task.h"
|
2026-07-26 20:40:16 +08:00
|
|
|
|
#include "monitor/motor_ota_relay.h"
|
2026-04-27 00:42:26 +08:00
|
|
|
|
|
2026-07-17 02:02:36 +08:00
|
|
|
|
/** @brief 创建关键任务;成功返回 true。 */
|
|
|
|
|
|
static bool createCriticalTask(TaskFunction_t entry, const char *name,
|
2026-07-16 23:00:15 +08:00
|
|
|
|
uint32_t stack, UBaseType_t prio)
|
|
|
|
|
|
{
|
2026-07-17 02:02:36 +08:00
|
|
|
|
return xTaskCreatePinnedToCore(entry, name, stack, NULL, prio, NULL, 0) == pdPASS;
|
2026-07-16 23:00:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-07-17 02:02:36 +08:00
|
|
|
|
* @brief 程序主入口:按模块初始化并汇总结果。
|
2026-05-05 04:48:31 +08:00
|
|
|
|
*/
|
2026-04-27 02:34:47 +08:00
|
|
|
|
extern "C" void app_main(void)
|
2026-04-27 00:42:26 +08:00
|
|
|
|
{
|
2026-07-17 02:02:36 +08:00
|
|
|
|
SystemBoot::reset();
|
2026-05-05 03:28:44 +08:00
|
|
|
|
|
2026-07-17 02:02:36 +08:00
|
|
|
|
/* 上电/欠压复位后短延时再初始化子系统 */
|
2026-07-17 00:24:09 +08:00
|
|
|
|
{
|
|
|
|
|
|
esp_reset_reason_t rr = esp_reset_reason();
|
|
|
|
|
|
if (rr == ESP_RST_POWERON || rr == ESP_RST_BROWNOUT) {
|
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(200));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-22 01:53:16 +08:00
|
|
|
|
Esp32OtaCore::initMutex();
|
2026-06-14 17:10:24 +08:00
|
|
|
|
|
2026-07-17 02:02:36 +08:00
|
|
|
|
if (esp_netif_init() == ESP_OK) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_NETIF);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (esp_event_loop_create_default() == ESP_OK) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_EVENT_LOOP);
|
|
|
|
|
|
}
|
2026-05-05 03:28:44 +08:00
|
|
|
|
|
2026-05-31 03:20:26 +08:00
|
|
|
|
DebugLog::instance().init();
|
2026-07-17 02:02:36 +08:00
|
|
|
|
SystemBoot::mark(BOOT_DEBUG_LOG);
|
2026-05-05 03:28:44 +08:00
|
|
|
|
|
2026-07-17 02:02:36 +08:00
|
|
|
|
/* earlyInit:true=已启动 STA 连接流程;false=将走 AP */
|
2026-07-16 23:00:15 +08:00
|
|
|
|
const bool wifi_early_started_sta = WifiOta::instance().earlyInit();
|
2026-07-17 02:02:36 +08:00
|
|
|
|
SystemBoot::mark(BOOT_WIFI_EARLY);
|
2026-05-05 03:28:44 +08:00
|
|
|
|
|
2026-05-31 03:20:26 +08:00
|
|
|
|
HealthMonitor::instance().init();
|
2026-07-17 02:02:36 +08:00
|
|
|
|
SystemBoot::mark(BOOT_HEALTH_MON);
|
2026-04-27 00:42:26 +08:00
|
|
|
|
|
2026-07-17 02:02:36 +08:00
|
|
|
|
if (createCriticalTask(HealthMonitor::taskEntry, "health_mon",
|
|
|
|
|
|
TASK_STACK_HEALTH_MON, configMAX_PRIORITIES - 4)) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_HEALTH_TASK);
|
|
|
|
|
|
}
|
2026-04-27 02:34:47 +08:00
|
|
|
|
|
2026-07-16 01:24:12 +08:00
|
|
|
|
CpuStats::instance().start();
|
2026-07-17 02:02:36 +08:00
|
|
|
|
SystemBoot::mark(BOOT_CPU_STATS);
|
2026-07-16 01:24:12 +08:00
|
|
|
|
|
2026-05-31 03:20:26 +08:00
|
|
|
|
Protocol::instance().init();
|
2026-07-17 02:02:36 +08:00
|
|
|
|
SystemBoot::mark(BOOT_PROTOCOL);
|
2026-04-27 00:42:26 +08:00
|
|
|
|
|
2026-06-17 02:18:42 +08:00
|
|
|
|
OtaCoordinator::instance().init();
|
2026-06-22 01:53:16 +08:00
|
|
|
|
OtaCoordinator::instance().setBleCoexListener(&WifiOta::instance());
|
2026-07-17 02:02:36 +08:00
|
|
|
|
SystemBoot::mark(BOOT_OTA_COORD);
|
2026-06-17 02:18:42 +08:00
|
|
|
|
|
2026-07-17 02:02:36 +08:00
|
|
|
|
bool spi_l0_ok = false;
|
2026-07-16 23:00:15 +08:00
|
|
|
|
{
|
|
|
|
|
|
esp_err_t ret = SpiMaster::instance().init();
|
2026-07-17 02:02:36 +08:00
|
|
|
|
if (ret == ESP_OK && SpiMaster::instance().selfTestL0()) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_SPI);
|
|
|
|
|
|
spi_l0_ok = true;
|
|
|
|
|
|
/* 对端轻检:GD32 可能仍在启动延时,失败不拉垮关键启动 */
|
|
|
|
|
|
if (SpiMaster::instance().selfTestPeerL0()) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_CAN_LINK);
|
|
|
|
|
|
}
|
2026-07-16 23:00:15 +08:00
|
|
|
|
}
|
2026-06-14 17:10:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-17 02:02:36 +08:00
|
|
|
|
if (createCriticalTask(OtaRelay::taskEntry, "ota_relay",
|
|
|
|
|
|
TASK_STACK_OTA_RELAY, configMAX_PRIORITIES - 2)) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_OTA_RELAY_TASK);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (createCriticalTask(WifiOta::taskEntry, "wifi_ota",
|
|
|
|
|
|
TASK_STACK_WIFI_OTA, configMAX_PRIORITIES - 3)) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_WIFI_TASK);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (createCriticalTask(BleOta::taskEntry, "ble_ota",
|
|
|
|
|
|
TASK_STACK_BLE_OTA, configMAX_PRIORITIES - 3)) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_BLE_TASK);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* CAN 反馈依赖 SPI 本机 L0 */
|
|
|
|
|
|
if (spi_l0_ok && startCanFeedbackTask()) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_CAN_FB_TASK);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-26 20:40:16 +08:00
|
|
|
|
motorOtaRelayInit();
|
|
|
|
|
|
|
2026-07-17 02:02:36 +08:00
|
|
|
|
if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) {
|
|
|
|
|
|
SystemBoot::mark(BOOT_OTA_VALID);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-02 17:37:19 +08:00
|
|
|
|
/* ★ banner 文案必须包含「启动」,前端 polling.js 靠
|
|
|
|
|
|
* /OTA Relay .*启动/ 匹配本行判定 ESP32 重启完成(阶段 6)。 */
|
|
|
|
|
|
DEBUG_INFO("MAIN", "ESP32-C3 OTA Relay %s 启动, heap=%lu, wifi_early=%s",
|
2026-07-17 02:02:36 +08:00
|
|
|
|
FW_VERSION,
|
|
|
|
|
|
(unsigned long)esp_get_free_heap_size(),
|
|
|
|
|
|
wifi_early_started_sta ? "STA" : "AP/other");
|
|
|
|
|
|
|
|
|
|
|
|
const bool critical_ok = SystemBoot::report();
|
|
|
|
|
|
|
|
|
|
|
|
if (!critical_ok) {
|
|
|
|
|
|
DEBUG_ERR("MAIN", "critical init FAIL, restart in 3s");
|
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(3000));
|
|
|
|
|
|
esp_restart();
|
|
|
|
|
|
}
|
2026-05-31 19:09:11 +08:00
|
|
|
|
}
|