固件 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]>
这个提交包含在:
@@ -524,6 +524,47 @@ static void test_power_off_drops_vbus_and_always_drops_the_efuse(void)
|
||||
TEST_ASSERT_TRUE(slot_vbus_is_on(2)); /* 影子如实留在 on(slot.h:倒向安全的一侧) */
|
||||
}
|
||||
|
||||
/* A15:只有「真的开成 / 关成了」才改意图(下次开机按它恢复);被拒的、判重命中的都不改。 */
|
||||
static int g_intent_n;
|
||||
static int g_intent_rail;
|
||||
static bool g_intent_on;
|
||||
static void intent_spy(void *ctx, int rail, bool on)
|
||||
{
|
||||
(void)ctx;
|
||||
g_intent_n++;
|
||||
g_intent_rail = rail;
|
||||
g_intent_on = on;
|
||||
}
|
||||
|
||||
static void test_power_records_intent_only_when_it_took_effect(void)
|
||||
{
|
||||
g_intent_n = 0;
|
||||
const cmd_env_t env = { .intent = intent_spy };
|
||||
cmd_init(&env);
|
||||
|
||||
ASSERT_HAS(send("{\"seq\":1,\"cmd\":\"power\",\"rail\":3,\"on\":true}"), "\"ok\":true");
|
||||
TEST_ASSERT_EQUAL_INT(1, g_intent_n);
|
||||
TEST_ASSERT_EQUAL_INT(3, g_intent_rail);
|
||||
TEST_ASSERT_TRUE(g_intent_on);
|
||||
|
||||
send("{\"seq\":1,\"cmd\":\"power\",\"rail\":3,\"on\":true}"); /* 判重命中:不再执行 */
|
||||
TEST_ASSERT_EQUAL_INT(1, g_intent_n);
|
||||
|
||||
set_present(4, false);
|
||||
ASSERT_HAS(send("{\"seq\":2,\"cmd\":\"power\",\"rail\":4,\"on\":true}"), "\"err\":\"empty\"");
|
||||
TEST_ASSERT_EQUAL_INT(1, g_intent_n);
|
||||
|
||||
ASSERT_HAS(send("{\"seq\":3,\"cmd\":\"power\",\"rail\":3,\"on\":false}"), "\"ok\":true");
|
||||
TEST_ASSERT_EQUAL_INT(2, g_intent_n);
|
||||
TEST_ASSERT_FALSE(g_intent_on);
|
||||
|
||||
/* 硬重启不是意图(那是事故处理),不许碰它。 */
|
||||
ASSERT_HAS(send("{\"seq\":4,\"cmd\":\"power\",\"rail\":1,\"on\":true}"), "\"ok\":true");
|
||||
ASSERT_HAS(send("{\"seq\":5,\"cmd\":\"power_cycle\",\"rail\":1}"), "\"ok\":true");
|
||||
TEST_ASSERT_EQUAL_INT(3, g_intent_n);
|
||||
cmd_init(NULL);
|
||||
}
|
||||
|
||||
/* 风扇:手动值只是下限,0 交回自动。 */
|
||||
static void test_fan_floor(void)
|
||||
{
|
||||
@@ -649,6 +690,7 @@ int main(void)
|
||||
RUN_TEST(test_reboots_are_logged_with_kind_and_link);
|
||||
RUN_TEST(test_vbus_needs_the_rail_powered);
|
||||
RUN_TEST(test_power_off_drops_vbus_and_always_drops_the_efuse);
|
||||
RUN_TEST(test_power_records_intent_only_when_it_took_effect);
|
||||
RUN_TEST(test_fan_floor);
|
||||
RUN_TEST(test_events_pages_with_contiguous_seqs);
|
||||
RUN_TEST(test_status_fits_and_reports_unknowns_as_null);
|
||||
|
||||
在新工单中引用
屏蔽一个用户