Files
ESP32_COMM/main/core/system_boot.cpp
T
小龙虾 1b10f89d8c feat(main): 添加启动模块自检与汇总功能
- 新增 SystemBoot 类用于跟踪各模块初始化状态,提供位图标记与报告功能
- 在 main.cpp 中重构初始化流程,按顺序初始化各模块并记录状态
- 添加 system_boot.cpp 模块文件到构建配置
- CAN反馈任务增加冷启动延迟,避免与GD32初始化窗口冲突

refactor(ota): 优化OTA协调器线程安全机制

- 修改 lock()/unlock() 方法返回take结果,确保mutex正确释放
- 修复多任务并发时mutex死锁问题,避免vTaskPriorityDisinherit断言
- 统一finalize失败后的状态复位逻辑,确保协调器回到IDLE状态
- 优化忙状态超时检测与自愈机制

perf(boot): 优化冷启动时序与资源管理

- 简化README中冷启动优化说明,聚焦核心逻辑
- 优化BOD阈值设置为LVL5,改进电源稳定性
- 增加BLE OTA工作线程优先级,减少丢包情况
- 优化堆告警节流机制,在OTA期间降低告警频率

fix(relay): 改进GD32应用存活检测逻辑

- 调整GD32 APP存活验证时序,增加会话建立验证
- 修复HELLO建立session后未验证role的问题
- 优化FINISH后等待APP启动的静默时间与重试机制
- 统一GD32探测逻辑到OTA中继任务

refactor(server): 优化HTTP服务端内存与性能

- 使用静态缓冲区替代动态分配,减少堆碎片化风险
- 优化CAN批量发送期间暂停反馈任务的机制
- 调整BLE连接参数请求逻辑,提升传输性能
- 改进错误处理流程,避免堆紧张时的额外分配

bump(version): 更新固件版本至0.3.50

- 更新版本号从0.3.49到0.3.50
- 更新编译时间戳与Git哈希值
2026-07-17 02:02:36 +08:00

172 lines
4.7 KiB
C++

/**
* @file system_boot.cpp
* @brief 启动模块位图实现。
*/
#include "system_boot.h"
#include "monitor/debug_log.h"
#include <stdio.h>
#include <string.h>
namespace {
struct BootEntry {
uint32_t bit;
const char *name;
bool critical;
};
static const BootEntry kEntries[] = {
{ BOOT_NETIF, "netif", true },
{ BOOT_EVENT_LOOP, "event_loop", true },
{ BOOT_DEBUG_LOG, "debug_log", true },
{ BOOT_WIFI_EARLY, "wifi_early", true },
{ BOOT_HEALTH_MON, "health_mon", true },
{ BOOT_HEALTH_TASK, "health_task", true },
{ BOOT_CPU_STATS, "cpu_stats", false },
{ BOOT_PROTOCOL, "protocol", true },
{ BOOT_OTA_COORD, "ota_coord", true },
{ BOOT_SPI, "spi", true },
{ BOOT_OTA_RELAY_TASK, "ota_relay_task", true },
{ BOOT_WIFI_TASK, "wifi_task", true },
{ BOOT_BLE_TASK, "ble_task", true },
{ BOOT_CAN_LINK, "can_link", false },
{ BOOT_CAN_FB_TASK, "can_fb_task", false },
{ BOOT_OTA_VALID, "ota_mark_valid", false },
};
static uint32_t s_mask = 0U;
static void evaluate(bool *critical_ok, bool *all_ok, char *fail_list, size_t fail_cap)
{
*critical_ok = true;
*all_ok = true;
if (fail_list && fail_cap > 0U) {
fail_list[0] = '\0';
}
size_t fail_len = 0U;
for (size_t i = 0; i < sizeof(kEntries) / sizeof(kEntries[0]); ++i) {
const BootEntry &e = kEntries[i];
const bool ok = (s_mask & e.bit) != 0U;
if (ok) {
continue;
}
*all_ok = false;
if (e.critical) {
*critical_ok = false;
}
if (!fail_list || fail_cap == 0U) {
continue;
}
if (fail_len + 2U < fail_cap) {
if (fail_len > 0U) {
fail_list[fail_len++] = ',';
}
const char *p = e.name;
while (*p != '\0' && fail_len + 1U < fail_cap) {
fail_list[fail_len++] = *p++;
}
fail_list[fail_len] = '\0';
}
}
}
} // namespace
void SystemBoot::reset()
{
s_mask = 0U;
}
void SystemBoot::mark(SystemBootBit bit)
{
s_mask |= static_cast<uint32_t>(bit);
}
bool SystemBoot::report()
{
bool critical_ok = true;
bool all_ok = true;
char fail_list[192] = {0};
evaluate(&critical_ok, &all_ok, fail_list, sizeof(fail_list));
if (critical_ok && all_ok) {
DEBUG_INFO("BOOT", "init: OK (all modules)");
} else if (critical_ok) {
DEBUG_WARN("BOOT", "init: OK (critical), skipped/failed: %s",
fail_list[0] != '\0' ? fail_list : "?");
} else {
DEBUG_ERR("BOOT", "init: FAIL, modules: %s",
fail_list[0] != '\0' ? fail_list : "?");
}
return critical_ok;
}
int SystemBoot::appendStatusJson(char *buf, size_t cap, int offset)
{
if (!buf || cap == 0 || offset < 0 || (size_t)offset >= cap) {
return offset;
}
bool critical_ok = true;
bool all_ok = true;
char fail_list[192] = {0};
evaluate(&critical_ok, &all_ok, fail_list, sizeof(fail_list));
const char *summary;
if (critical_ok && all_ok) {
summary = "OK (all modules)";
} else if (critical_ok) {
summary = "OK (critical)";
} else {
summary = "FAIL";
}
int n = snprintf(buf + offset, cap - (size_t)offset,
",\"boot\":{\"critical_ok\":%s,\"all_ok\":%s,\"mask\":%lu,"
"\"summary\":\"%s\",\"failed\":\"%s\",\"modules\":[",
critical_ok ? "true" : "false",
all_ok ? "true" : "false",
(unsigned long)s_mask,
summary,
fail_list);
if (n < 0) {
return offset;
}
if (offset + n >= (int)cap) {
buf[cap - 1] = '\0';
return (int)(cap - 1);
}
offset += n;
for (size_t i = 0; i < sizeof(kEntries) / sizeof(kEntries[0]); ++i) {
const BootEntry &e = kEntries[i];
const bool ok = (s_mask & e.bit) != 0U;
n = snprintf(buf + offset, cap - (size_t)offset,
"%s{\"name\":\"%s\",\"ok\":%s,\"critical\":%s}",
i == 0 ? "" : ",",
e.name,
ok ? "true" : "false",
e.critical ? "true" : "false");
if (n < 0) {
return offset;
}
if (offset + n >= (int)cap) {
buf[cap - 1] = '\0';
return (int)(cap - 1);
}
offset += n;
}
n = snprintf(buf + offset, cap - (size_t)offset, "]}");
if (n < 0) {
return offset;
}
if (offset + n >= (int)cap) {
buf[cap - 1] = '\0';
return (int)(cap - 1);
}
return offset + n;
}