固件 0.1.17~0.1.18-c5:CH224A 的 PD 档位实时进遥测(pdmon)

原来只在启动时读一次(bringup.c),而多口充电器重新分配功率时 20 V 档的电流上限当场会变。

- 新模块 pdmon:每秒读 0x09(协议状态)+ 0x50(档位电流),只读;先试上次应答的支路(主干 / mux 通道 5)。
  档位变了(连续两拍一致、非 0)记 LOG_EV_PD_LIMIT,arg 2 = 运行中换档。只报不动,降载仍没人做。
- status 新增 "pd":{"st":..,"ma":..},这一拍没读到是 null(满配 1164 / 1536 字节,余量断言改成至少留 256)。
- 0.1.17 放在热管理任务里读,板 B 实测 safety.skipped 每秒涨 1(持锁撞上巡检的下一拍);
  0.1.18 挪进巡检任务(t_safety_step 之后、每 50 圈一次),skipped 不再涨。
- 测试:新增 test_pdmon(6 例),test_cmd 加 pd 断言;28 ctest 全绿。

板 B 已 OTA 到 0.1.18-c5(两次都是热重启,五路没断电),读到 st 0x88 / 3000 mA。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
zhou yang
2026-10-06 06:31:04 +08:00
共同撰写人 Claude Opus 5.5
父节点 ca7435242f
当前提交 489cd6a6f3
共修改 10 个文件,包含 352 行新增和 3 行删除
+51
查看文件
@@ -0,0 +1,51 @@
/* CH224A 运行期轮询(0.1.17):把充电器**此刻**给的 PD 档位放进遥测(status 的 `pd`)。
为什么不够用启动那一次(bringup.c 的 `pd_up()`):多口充电器在别的口插拔时会重新分配功率、
重发 Source_Capabilities,20 V 档的电流上限当场就变(板 B 实测过 5 A → 3.25 A → 3 A),
而 20 V 不一定掉、板子不一定重启 —— 只在启动读一次,面板上看到的就是旧档位。
做的事只有读:`0x09`(协议状态)和 `0x50`(档位电流)。**不写任何寄存器**(ch224a.h 那个框)。
读到的档位和上一次记进日志的不一样(连续两拍一致才算数,免得协商中途的瞬时值刷日志)
⇒ 记一条 `LOG_EV_PD_LIMIT`,arg = 2(运行中换档)。
⚠️ 和 bringup 一样只**报**不**动**:逼近上限的降载(§8.3)还没人做(HANDOFF)。
---- 线程 ----------------------------------------------------------------
`pdmon_poll()` 只在**巡检任务**里调,排在 `t_safety_step()` 之后、每 50 圈(1 s)一次,
一次 ≈ 选主干 + 两个单字节读。status 跨任务读快照,遥测无害(cmd.h 同一条)。
⚠️ 别挪到别的任务去:2026-10-06 板 B 实测放在热管理任务里时,它持锁的那一下正好撞上
巡检的下一拍,`skipped` 每秒整整涨 1(每秒有一圈五路都没读)。巡检自己读就没有人跟它抢。 */
#ifndef PDMON_H
#define PDMON_H
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* `LOG_EV_PD_LIMIT` 的 arg:0 = 启动时读到,1 = 启动时读不到 / 读到 0、按保守值(bringup.c),
2 = 运行中档位变了。⚠️ 冻结(上位机 protocol.py)。 */
#define PDMON_EV_ARG_CHANGED 2u
typedef struct {
bool ok; /* 上一拍读到了;false 时下面两个是最后一次读到的值 */
uint8_t status; /* 0x09 原值 */
uint32_t ma; /* 0x50 换算成 mA(没协商上 PD 时是 0) */
uint32_t polls;
uint32_t errors;
} pdmon_snap_t;
/* `boot_ma` = 启动时读到的档位(`bringup_report_t.pd_ma`,读不到是 0):换档事件拿它当基线。 */
void pdmon_init(uint32_t boot_ma);
/* 读一拍。先试上次应答的那条支路,不应答再试另一条(主干 / mux 通道 5,bringup.c `pd_up()` 的注释)。 */
void pdmon_poll(void);
void pdmon_get(pdmon_snap_t *out);
#ifdef __cplusplus
}
#endif
#endif /* PDMON_H */