固件 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 行删除
@@ -113,7 +113,8 @@ void sim_i2c_set_bus_time(bool on);
直接 HAL_ERR_ARG)。边界写成「个数」而不是「上限」,就是这么错的。 */
#define SIM_GPIO_PINS 49
/* 外部世界把某个**输入**脚拉成 level。对输出脚调用会 abort(那是总线打架)。 */
/* 外部世界把某个**输入**脚拉成 level。对输出脚调用会 abort(那是总线打架)。
可以在脚配置之前调:电平记着,配成输入的那一刻生效(压过内部上拉)。 */
void sim_gpio_drive(int pin, int level);
/* 该脚当前电平:输出脚 = 固件驱动的值,输入脚 = 外部驱动的值。没配过返回 -1。 */
@@ -127,6 +128,16 @@ uint32_t sim_gpio_writes(int pin);
「17 ms 上电时序」(A9)这类事,光看每个脚的终值和次数是看不出来的。 */
uint32_t sim_gpio_write_seq(int pin);
/* 该脚**最后一次 0→1** 时的虚拟时刻(µs),从没抬高过返回 0。
「五路上电错开 100 ms」(A15)要的是线上的时刻,不是被测代码自己报的时刻。 */
uint64_t sim_gpio_rise_us(int pin);
/* 每次 `hal_gpio_write()` 成功之后调一次(`sim_hal_reset()` 清掉)。
给测试扮演「外部世界对引脚的反应」用 —— 比如 eFuse 的 EN 一抬高,
那一路 PCA9555 上的 PGOOD 就跟着来(A15 的上电序列靠它才测得出「等 PG」)。 */
typedef void (*sim_gpio_hook_t)(int pin, int level);
void sim_gpio_set_hook(sim_gpio_hook_t fn);
/* ---------------- 74HC595 ×3 的 24 位链 ---------------- */
/* 按 datasheet 建模的假移位链,**只看线上真实发生的边**(SRCLK / RCLK 上升沿)。