固件 A15:启动顺序 + 降级矩阵(bringup.{h,c},已上板)

- 启动序列从 app_main.c 拆进 main/bringup.{h,c},宿主机可测:
  bringup_devices()(§10.9 第 1~4 步)→ 起 t_safety → bringup_power_restore()(第 5~6 步)
- 六片 INA226 写 Config/Calibration(之前没做,电流恒 0);输入侧 0x43 登记对调接
- 按「意图」逐路上电、错开 100 ms、每路等 PG 500 ms,等不到关回去并记 LOG_EV_PG_TIMEOUT(17)
- 意图只由 power 命令改(cmd_env_t.intent → NVS phonerail/rail_want)
- §10.10 逐行降级:INA/DAC/PCA9555/mux/PRSNT#/CH224A;mux 失联时不碰主干
- BOOT 事件 arg = 复位原因;HUB_RST# 仍只在上电复位时脉冲
- rail_volt_init() 一片失败不再放弃另一片;CH224A 主干 / 通道 5 两处都找
- sim:sim_gpio_rise_us / sim_gpio_set_hook,sim_gpio_drive 可在配置前调
- test_bringup.c 24 例 + test_cmd 意图 1 例,共 425 例全绿;版本 0.1.0-a15
- rack:事件表加 17 PG_TIMEOUT(已部署)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
zhou yang
2026-09-27 13:24:17 +08:00
共同撰写人 Claude Opus 5.5
父节点 da6af4ef1c
当前提交 c85eec53e6
共修改 24 个文件,包含 1479 行新增和 201 行删除
+7 -4
查看文件
@@ -437,7 +437,9 @@ static hal_err_t format_all(void)
return HAL_OK;
}
hal_err_t evlog_init(void)
hal_err_t evlog_init(void) { return evlog_init_ex(0); }
hal_err_t evlog_init_ex(uint8_t boot_arg)
{
/* RAM 侧无条件清干净:真板上这里刚上电,宿主机上这条让 `sim_hal_reboot()`
之后的行为和真重启一致(statics 在进程里是活着的)。 */
@@ -465,7 +467,7 @@ hal_err_t evlog_init(void)
if (err != HAL_OK) {
/* 没有分区。**不 abort、不影响入队**:日志是排查手段,不是安全链
(evlog.h 上面那段)。事件照进 RAM,只是没人能把它们写下去。 */
evlog_put(0, LOG_EV_BOOT, 0, 0, 0);
evlog_put(0, LOG_EV_BOOT, boot_arg, 0, 0);
return err;
}
@@ -474,7 +476,7 @@ hal_err_t evlog_init(void)
if (g.sector_bytes < 2u * sizeof(evlog_rec_t) ||
(g.sector_bytes % sizeof(evlog_rec_t)) != 0u || g.sectors < 2u) {
s_have_store = false;
evlog_put(0, LOG_EV_BOOT, 0, 0, 0);
evlog_put(0, LOG_EV_BOOT, boot_arg, 0, 0);
return HAL_ERR_STATE;
}
s_sector_bytes = g.sector_bytes;
@@ -525,7 +527,7 @@ hal_err_t evlog_init(void)
/* §10.7「上电从 0 计」⇒ 时间戳会跳回去。没有这一条的话,重启前后的记录
在时间轴上互相穿插,而日志里看不出重启发生过。 */
evlog_put(0, LOG_EV_BOOT, 0, 0, 0);
evlog_put(0, LOG_EV_BOOT, boot_arg, 0, 0);
return s_have_store ? HAL_OK : HAL_ERR_STATE;
}
@@ -569,6 +571,7 @@ const char *evlog_ev_str(log_ev_t ev)
case LOG_EV_MUX_LOST: return "mux失联全断";
case LOG_EV_SLOT_EMPTY: return "刀片不在位";
case LOG_EV_PD_LIMIT: return "PD限功率";
case LOG_EV_PG_TIMEOUT: return "上电等不到PG";
case LOG_EV_COUNT: break;
}
return "?";