固件 0.1.5~0.1.13-c5:刷机模式、多组 WiFi、热插拔初始化、总线锁误判、硬重启断 VBUS
- 0.1.5/0.1.6:刷机模式(flash_mode,最多 2 路,60 分钟可加钟)——窗口内顶高按 4450 mV 绝对值判、不断 VBUS - 0.1.7/0.1.8:反灌断 VBUS 阈值放宽到 -300 mA(adb reboot bootloader 过渡实测 -208 mA) - 0.1.9:WiFi 最多存 4 组,连不上轮换;NVS v1 自动迁移并双写(OTA 回滚仍能上网) - 0.1.10:热插拔进来的刀片重新初始化 PCA9555 + INA226(否则 VBUS 常开、电流恒读 0) - 0.1.11:i2cbus 嵌套检测改看本任务持锁(原全局标志让 key 随机回 busy、vbus 随机回 io) - 0.1.12:硬重启先断 VBUS,开机校验通过 60 s 后再接回(否则假重启 / 误判没开机 / 进关机充电) - 0.1.13:这一路被安全判据断电时一并退出刷机模式(事件 21 arg 254) 26 ctest 全绿;新增用例均先在旧代码上确认变红。板 B 已 OTA 到 0.1.13-c5 并实测。 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
这个提交包含在:
+57
-7
@@ -18,9 +18,20 @@ void netcfg_init(const netcfg_t *loaded, netcfg_save_fn save, netcfg_changed_fn
|
||||
if (loaded != NULL) {
|
||||
s_cfg = *loaded;
|
||||
}
|
||||
/* 从 flash 读回来的东西不可信:强制收尾,免得一个没带 0 的字段把后面的读穿。 */
|
||||
s_cfg.ssid[NETCFG_SSID_MAX] = '\0';
|
||||
s_cfg.pass[NETCFG_PASS_MAX] = '\0';
|
||||
/* 从 flash 读回来的东西不可信:强制收尾,免得一个没带 0 的字段把后面的读穿;
|
||||
空位挤到末尾(「有效的就是 [0, n)」是 count / 轮换的前提)。 */
|
||||
int n = 0;
|
||||
for (int i = 0; i < NETCFG_WIFI_N; i++) {
|
||||
netcfg_wifi_t w = s_cfg.wifi[i];
|
||||
w.ssid[NETCFG_SSID_MAX] = '\0';
|
||||
w.pass[NETCFG_PASS_MAX] = '\0';
|
||||
if (w.ssid[0] != '\0') {
|
||||
s_cfg.wifi[n++] = w;
|
||||
}
|
||||
}
|
||||
for (int i = n; i < NETCFG_WIFI_N; i++) {
|
||||
memset(&s_cfg.wifi[i], 0, sizeof(s_cfg.wifi[i]));
|
||||
}
|
||||
s_cfg.uri[NETCFG_URI_MAX] = '\0';
|
||||
s_cfg.user[NETCFG_USER_MAX] = '\0';
|
||||
s_cfg.mpass[NETCFG_MPASS_MAX] = '\0';
|
||||
@@ -90,6 +101,25 @@ static hal_err_t commit(const netcfg_t *next)
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
int netcfg_wifi_count(const netcfg_t *cfg)
|
||||
{
|
||||
int n = 0;
|
||||
while (n < NETCFG_WIFI_N && cfg->wifi[n].ssid[0] != '\0') {
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int netcfg_wifi_find(const netcfg_t *cfg, const char *ssid)
|
||||
{
|
||||
for (int i = 0; i < netcfg_wifi_count(cfg); i++) {
|
||||
if (strcmp(cfg->wifi[i].ssid, ssid) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
hal_err_t netcfg_set_wifi(const char *ssid, const char *pass)
|
||||
{
|
||||
if (!netcfg_wifi_ok(ssid, pass)) {
|
||||
@@ -97,10 +127,30 @@ hal_err_t netcfg_set_wifi(const char *ssid, const char *pass)
|
||||
}
|
||||
netcfg_t next;
|
||||
netcfg_get(&next);
|
||||
memset(next.ssid, 0, sizeof(next.ssid));
|
||||
memset(next.pass, 0, sizeof(next.pass));
|
||||
strcpy(next.ssid, ssid);
|
||||
strcpy(next.pass, pass);
|
||||
int i = netcfg_wifi_find(&next, ssid);
|
||||
if (i < 0) {
|
||||
i = netcfg_wifi_count(&next);
|
||||
if (i >= NETCFG_WIFI_N) {
|
||||
return HAL_ERR_STATE; /* 满了:先删一组。不悄悄挤掉最老的 —— 那可能正是唯一连得上的 */
|
||||
}
|
||||
}
|
||||
memset(&next.wifi[i], 0, sizeof(next.wifi[i]));
|
||||
strcpy(next.wifi[i].ssid, ssid);
|
||||
strcpy(next.wifi[i].pass, pass);
|
||||
return commit(&next);
|
||||
}
|
||||
|
||||
hal_err_t netcfg_del_wifi(const char *ssid)
|
||||
{
|
||||
netcfg_t next;
|
||||
netcfg_get(&next);
|
||||
const int i = ssid != NULL ? netcfg_wifi_find(&next, ssid) : -1;
|
||||
if (i < 0) {
|
||||
return HAL_ERR_ARG;
|
||||
}
|
||||
const int n = netcfg_wifi_count(&next);
|
||||
memmove(&next.wifi[i], &next.wifi[i + 1], (size_t)(n - 1 - i) * sizeof(next.wifi[0]));
|
||||
memset(&next.wifi[n - 1], 0, sizeof(next.wifi[0]));
|
||||
return commit(&next);
|
||||
}
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户