固件 0.1.14~0.1.16-c5:Hub 按需启停(hubctl)、开机长按统一 5 s
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -16,6 +16,7 @@
|
||||
#include "hal_i2c.h"
|
||||
#include "hal_lock.h"
|
||||
#include "hal_time.h"
|
||||
#include "hubctl.h"
|
||||
#include "i2cbus.h"
|
||||
#include "ina226.h"
|
||||
#include "pca9555.h"
|
||||
@@ -231,6 +232,7 @@ static void task_actuator(void *arg)
|
||||
cmd_msg_t m;
|
||||
for (;;) {
|
||||
cmd_chgmode_tick(hal_time_now_ms()); /* 刷机模式到期清理 + 记事件(chgmode.h:只在本任务写) */
|
||||
hubctl_tick(hal_time_now_ms()); /* Hub 按需启停(hubctl.h:只在本任务写)。空闲时 ≤100 ms 一拍 */
|
||||
const TickType_t t = pdMS_TO_TICKS(t_actuator_step());
|
||||
/* ⚠️ `CONFIG_FREERTOS_HZ=100` ⇒ 一个 tick 是 10 ms,`pdMS_TO_TICKS(5)`
|
||||
是 **0**,而「等 0 tick」只是查一眼就回来 —— 那会让这个中优先级任务
|
||||
@@ -342,6 +344,43 @@ static void want_save(void *ctx, int rail, bool on)
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Hub 模式的持久化(0.1.14,hubctl.h)-------------------------------------
|
||||
同一个命名空间,一个字节。新板 / 读不到 = AUTO(用户 2026-09-29 定:默认按需)。 */
|
||||
#define HUB_KEY "hub_mode"
|
||||
|
||||
static uint8_t hub_mode_load(void)
|
||||
{
|
||||
nvs_handle_t h;
|
||||
uint8_t v = HUB_MODE_AUTO;
|
||||
if (nvs_open(WANT_NS, NVS_READONLY, &h) == ESP_OK) {
|
||||
if (nvs_get_u8(h, HUB_KEY, &v) != ESP_OK || v >= HUB_MODE_COUNT) {
|
||||
v = HUB_MODE_AUTO;
|
||||
}
|
||||
nvs_close(h);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static void hub_mode_save(void *ctx, hub_mode_t mode)
|
||||
{
|
||||
(void)ctx;
|
||||
if (hub_mode_load() == (uint8_t)mode) {
|
||||
return; /* 没变就不写 flash */
|
||||
}
|
||||
nvs_handle_t h;
|
||||
esp_err_t e = nvs_open(WANT_NS, NVS_READWRITE, &h);
|
||||
if (e == ESP_OK) {
|
||||
e = nvs_set_u8(h, HUB_KEY, (uint8_t)mode);
|
||||
if (e == ESP_OK) {
|
||||
e = nvs_commit(h);
|
||||
}
|
||||
nvs_close(h);
|
||||
}
|
||||
if (e != ESP_OK) {
|
||||
ESP_LOGW(TAG, "Hub 模式没存进 NVS:%s(这次照样生效)", esp_err_to_name(e));
|
||||
}
|
||||
}
|
||||
|
||||
static void log_report(const bringup_report_t *r)
|
||||
{
|
||||
ESP_LOGI(TAG, "启动:降级位 0x%02x,空槽 0x%02x,盲跑 0x%02x,PCA 失联 0x%02x,PD %u mA → 上限 %u mW",
|
||||
@@ -441,6 +480,12 @@ void app_main(void)
|
||||
ESP_LOGE(TAG, "风扇起不来:%s —— 没有主动散热", hal_err_str(err));
|
||||
}
|
||||
|
||||
/* Hub 按需启停(0.1.14)。放开 `HUB_RST#`、启动算一次「需要」⇒ 至少 HUB_IDLE_MS 之后才可能关。
|
||||
必须在执行器任务起来之前:它的第一拍就会调 `hubctl_tick()`。 */
|
||||
hubctl_init((hub_mode_t)hub_mode_load(), hub_mode_save, NULL, hal_time_now_ms());
|
||||
ESP_LOGI(TAG, "Hub 模式 %s(无人用 USB %u 分钟后按住复位)", hub_mode_str(hubctl_mode()),
|
||||
(unsigned)(HUB_IDLE_MS / 60000u));
|
||||
|
||||
/* 执行器:PG 从巡检的快照里取,本任务自己不碰 I²C(t_actuator.h 开头那一段)。
|
||||
⚠️ 必须在 `spawn(TASK_SAFETY, ...)` 之前:判据要关路时会先 `t_actuator_abort()`,
|
||||
而没 init 的执行器只会直接返回,那时序列还在跑,电关掉几秒又会被抬回来。 */
|
||||
|
||||
在新工单中引用
屏蔽一个用户