固件 0.1.14~0.1.16-c5:Hub 按需启停(hubctl)、开机长按统一 5 s

Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
zhou yang
2026-10-04 19:24:31 +08:00
共同撰写人 Claude Opus 5.5
父节点 92f38c2328
当前提交 c41d1ec931
共修改 21 个文件,包含 764 行新增和 18 行删除
+36 -1
查看文件
@@ -16,6 +16,7 @@
#include "dac63204.h"
#include "evlog.h"
#include "hal_i2c.h"
#include "hubctl.h"
#include "hal_lock.h"
#include "hal_time.h"
#include "i2cbus.h"
@@ -189,7 +190,8 @@ static void test_cmd_numbers_are_frozen(void)
TEST_ASSERT_EQUAL_INT(12, CMD_NET);
TEST_ASSERT_EQUAL_INT(13, CMD_OTA); /* C2 */
TEST_ASSERT_EQUAL_INT(14, CMD_FLASH_MODE); /* 0.1.5 刷机模式 */
TEST_ASSERT_EQUAL_INT(15, CMD_COUNT);
TEST_ASSERT_EQUAL_INT(15, CMD_HUB); /* 0.1.14 Hub 按需启停 */
TEST_ASSERT_EQUAL_INT(16, CMD_COUNT);
TEST_ASSERT_EQUAL_INT(0, CMD_OK);
TEST_ASSERT_EQUAL_INT(1, CMD_ERR_PARSE);
@@ -590,6 +592,38 @@ static void test_fan_floor(void)
TEST_ASSERT_EQUAL_UINT16(0, t_thermal_floor());
}
/* 0.1.14 hub:改模式 / 保持窗口,两条链路都收;越界记事件、缺参数不记;
USB 链路上的任何一行都算一次「有人在用 USB」。 */
static void test_hub_command(void)
{
hubctl_init(HUB_MODE_AUTO, NULL, NULL, hal_time_now_ms());
const char *r = send_on(CMD_LINK_WIFI, "{\"seq\":1,\"cmd\":\"hub\",\"mode\":\"on\"}");
ASSERT_HAS(r, "\"ok\":true");
ASSERT_HAS(r, "\"hub\":{\"on\":true,\"mode\":\"on\"");
TEST_ASSERT_EQUAL_INT(HUB_MODE_ON, hubctl_mode());
r = send("{\"seq\":2,\"cmd\":\"hub\",\"mode\":\"auto\",\"min\":30}");
ASSERT_HAS(r, "\"mode\":\"auto\"");
ASSERT_HAS(r, "\"hold\":1800");
TEST_ASSERT_EQUAL_UINT32(1800, hubctl_hold_left_s(hal_time_now_ms()));
ASSERT_HAS(send("{\"seq\":3,\"cmd\":\"hub\",\"min\":241}"), "\"err\":\"range\"");
TEST_ASSERT_EQUAL_INT(1, count_events(LOG_EV_CMD_REJECT));
ASSERT_HAS(send("{\"seq\":4,\"cmd\":\"hub\",\"mode\":\"off\"}"), "\"err\":\"arg\"");
ASSERT_HAS(send("{\"seq\":5,\"cmd\":\"hub\"}"), "\"err\":\"arg\"");
TEST_ASSERT_EQUAL_INT(1, count_events(LOG_EV_CMD_REJECT));
ASSERT_HAS(send("{\"seq\":5,\"cmd\":\"hub\"}"), "\"dup\":true"); /* 会动东西 ⇒ 进判重窗口 */
ASSERT_HAS(send("{\"seq\":7,\"cmd\":\"hub\",\"min\":0}"), "\"hold\":0");
const hub_in_t idle = { .link_up = true };
TEST_ASSERT_EQUAL_INT(HUB_WHY_OFF, hub_decide(&idle, hal_time_now_ms() + 1));
/* USB 上来一行(哪怕是 status)⇒ 重新给一个 idle 窗口。 */
(void)send_on(CMD_LINK_USB, "{\"cmd\":\"status\"}");
TEST_ASSERT_EQUAL_INT(HUB_WHY_IDLE, hub_decide(&idle, hal_time_now_ms() + 1));
}
/* ---- 只读命令 ------------------------------------------------------------ */
/* events 分页:一次最多 CMD_EVENTS_MAX 条,逐条带序号,游标接得上;RAM 里的先落盘。 */
@@ -858,6 +892,7 @@ int main(void)
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_hub_command);
RUN_TEST(test_events_pages_with_contiguous_seqs);
RUN_TEST(test_status_fits_and_reports_unknowns_as_null);
RUN_TEST(test_small_output_buffer);