Merge pull request 'fix(ui/wave): 回放页段表枚举恒空根因修复(seg_path 返回值判错 + 键处理缺重绘)' (#67) from fix-replay-enum-0e52b1963afa into master
Reviewed-on: http://100.123.83.113:3001/wandering1/STM32F4-Base/pulls/67
This commit was merged in pull request #67.
This commit is contained in:
+95
-12
@@ -32,6 +32,24 @@
|
||||
* /clear_state 直通)并在 ui_menu_init 之前注入;记录
|
||||
* reader 的 2 条 if 链改成 7 条映射表 s_log_map,并加
|
||||
* 编译期守卫把 UI_W_REC_LOG_* == syslog_id_t 枚举序钉死
|
||||
* v1.6 2026-11-02 DTU 项目组 修复「回放页段表枚举恒空」第一幕(登记簿同名
|
||||
* 条目 + docs/测试说明/专项验证/故障录波板级到场轮执行手册.md §3):
|
||||
* ui_task_wave_scan 失败不再无条件钉 s_wave_scanned——
|
||||
* opendir/readdir 失败本轮返 -1(卷忙语义),下一次进页/
|
||||
* 按键自然重试;失败分支与「FR_OK 零条目」补带 FR 码留痕
|
||||
* (正文「ui wave scan」前缀,tag 沿用本文件 [UI_TASK])
|
||||
* 供板级远程定性根因。FR_NO_PATH(从未录过波)归 0 段
|
||||
* 并钉表的设计原口径不动。
|
||||
* v1.7 2026-11-02 DTU 项目组 根因修复:wave_store_seg_path 契约是「成功 =
|
||||
* 写入字符数(恒 16),失败为负码」,读侧两处(load_head
|
||||
* / seg_win)自建成起把返回值 != 0 当失败——每次成功拼
|
||||
* 路径都被判死,回放页开档永远走不到 f_open,盘上有段
|
||||
* 也恒显「无录波段」(本 boot FR 埋点钉死:scan done
|
||||
* cnt=7 + head path fail;写侧同函数用 <= 0 一直是对的;
|
||||
* 模拟器桩不走本文件,故黄金图从未暴露此病)。口径改
|
||||
* <= 0;开档失败补带 FR 码的永久留痕(该失败态页面无
|
||||
* 视觉面);第一幕临时诊断(序号/try 闸日志/无条件
|
||||
* done 行)收敛删除。
|
||||
*/
|
||||
#include "ui_task.h"
|
||||
|
||||
@@ -73,6 +91,14 @@
|
||||
#include "task_prof.h" /* P2 常开探针:循环周期 / 工作耗时 / 推流往返 */
|
||||
#include "sb_link.h" /* 屏板链路:帧 B 组帧 / 按键出队 / 统计与离线判定(批 2) */
|
||||
|
||||
/* 枚举留痕(v1.6,第一幕埋点):dbg_log.h 原在文件后段(s_wave_ops 之后)才
|
||||
* 被包含,随本波把 DBG_TAG 定义 + 包含一并上收到包含区(原后段两处删除,
|
||||
* 同标签同宏,不构成行为改动);本波只在原先静默返回的黑洞处补锚点,
|
||||
* 不新增重复日志(DBG_* 每条调用点约 90B Flash + 行缓冲栈)。
|
||||
* 留痕行以「ui wave scan」正文前缀区分来源。 */
|
||||
#define DBG_TAG "[UI_TASK]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
/*
|
||||
* 函数功能:待机屏底部时钟提供回调(平台差异:MCU = sys_clock_get_str)
|
||||
* 入口参数:buf - 时间串输出缓冲 char *
|
||||
@@ -421,27 +447,49 @@ static uint8_t s_wave_buf[256u]; /* 读窗:数据区流式 256B/次
|
||||
/*
|
||||
* 函数功能:重扫 /wave 目录,把现存段号收集成升序表
|
||||
* 入口参数:无
|
||||
* 返回值:0 - 扫描完成(条数见 s_wave_cnt);-1 - 卷忙本轮跳过 int
|
||||
* 返回值:0 - 扫描完成(条数见 s_wave_cnt);-1 - 本轮无完整事实(卷忙,或
|
||||
* f_opendir/f_readdir 失败),不钉表,下一次取数自然重试 int
|
||||
* 限定条件:uiTask;一次 f_opendir + 有界 f_readdir,全程锁内
|
||||
* 函数说明:目录不存在(从未录过波)与目录空都归「0 段」,不是错误;
|
||||
* 函数说明:目录不存在(FR_NO_PATH,从未录过波)与目录空都归「0 段」并钉表,
|
||||
* 不是错误(设计原口径);其余 f_opendir/f_readdir 失败一律不钉表
|
||||
* (v1.6:原实现失败也无条件置 s_wave_scanned=1,卷忙 / FR_DENIED
|
||||
* 一类失败被钉成「0 段」假空态直到下一次 manual_req,登记簿
|
||||
* 「回放页段表枚举恒空」处置方向 = 失败不钉表、下键重试,与
|
||||
* soe_store 读者同纪律)。失败留痕带 FR 码,板级判读表(FR_DENIED
|
||||
* → 锁纪律;FR_NOT_READY → 挂载;FR_OK 但零条目 → readdir 与卷状态
|
||||
* 交互)见 docs/测试说明/专项验证/故障录波板级到场轮执行手册.md §3。
|
||||
* 名字不合形态的文件(E_NAME)静默跳过——那是别的道写进来的
|
||||
* 东西,回放页不替它背书也不报警
|
||||
*/
|
||||
static int ui_task_wave_scan(void) {
|
||||
static DIR dir; /* static:同 FIL 理由,压栈深 */
|
||||
FILINFO finfo;
|
||||
FRESULT fr;
|
||||
FRESULT rr = FR_OK;
|
||||
uint8_t idx;
|
||||
uint8_t i;
|
||||
uint8_t full; /* 1 = 本轮拿到完整事实,允许钉表 */
|
||||
|
||||
if (vol_lock_wait(0u) == 0u) {
|
||||
/* 卷忙本轮跳过 = 静默(看门狗设计说明 §4.3 口径:消费方在 try 失败
|
||||
* 分支不留日志,锁层竞争看 vol_lock_get_stats 计数);下一次进页/
|
||||
* 按键自然重试——本轮没拿到事实,绝不钉表 */
|
||||
return -1;
|
||||
}
|
||||
s_wave_cnt = 0u;
|
||||
if (f_opendir(&dir, WAVE_ST_DIR) == FR_OK) {
|
||||
full = 0u;
|
||||
fr = f_opendir(&dir, WAVE_ST_DIR);
|
||||
if (fr == FR_OK) {
|
||||
full = 1u;
|
||||
for (;;) {
|
||||
if (f_readdir(&dir, &finfo) != FR_OK || finfo.fname[0] == '\0') {
|
||||
rr = f_readdir(&dir, &finfo);
|
||||
if (rr != FR_OK) {
|
||||
full = 0u; /* 半截表不钉:本轮作废重来 */
|
||||
break;
|
||||
}
|
||||
if (finfo.fname[0] == '\0') {
|
||||
break; /* 目录正常走完 */
|
||||
}
|
||||
if (finfo.fattrib & AM_DIR) {
|
||||
continue;
|
||||
}
|
||||
@@ -451,9 +499,26 @@ static int ui_task_wave_scan(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
f_closedir(&dir);
|
||||
(void)f_closedir(&dir);
|
||||
if (full == 0u) {
|
||||
DBG_ERROR("ui wave scan readdir fail fr=%d got=%u", (int)rr,
|
||||
(unsigned)s_wave_cnt);
|
||||
}
|
||||
} else if (fr == FR_NO_PATH) {
|
||||
full = 1u; /* 从未录过波 = 0 段,完整事实 */
|
||||
} else {
|
||||
DBG_ERROR("ui wave scan opendir fail fr=%d", (int)fr);
|
||||
}
|
||||
vol_lock_release();
|
||||
if (full == 0u) {
|
||||
s_wave_cnt = 0u; /* 半截计数不外泄:本轮按「无段」显示 */
|
||||
return -1;
|
||||
}
|
||||
if (s_wave_cnt == 0u) {
|
||||
/* 判读表第三条(FR_OK 但零条目):钉盘级证据;有段不重复刷
|
||||
* (DBG_* 每条调用点约 90B Flash,开页成功态由画面自证) */
|
||||
DBG_INFO("ui wave scan done: dir ok, 0 seg entries");
|
||||
}
|
||||
/* 插入排序:条数上限 100,不引 qsort 的 stdlib 依赖 */
|
||||
for (i = 1u; i < s_wave_cnt; i++) {
|
||||
uint8_t j;
|
||||
@@ -523,20 +588,27 @@ static int ui_task_wave_load_head(uint8_t a_idx) {
|
||||
char path[WAVE_ST_PATH_MAX]; /* 容量 = WAVE_ST_PATH_MAX(17 字节口径,
|
||||
* 自己声明路径缓冲不得写死 16) */
|
||||
FRESULT fr;
|
||||
FRESULT ofr; /* 开档 FR 码:开档失败留痕用 */
|
||||
UINT br = 0u;
|
||||
int rc;
|
||||
|
||||
if ((s_wave_cache_ok != 0u) && (s_wave_cached_idx == a_idx)) {
|
||||
return UI_WAVE_OK;
|
||||
}
|
||||
if (wave_store_seg_path(path, (uint32_t)sizeof(path), a_idx) != 0) {
|
||||
if (wave_store_seg_path(path, (uint32_t)sizeof(path), a_idx) <= 0) {
|
||||
/* 契约(wave_store.h:458):成功 = 写入字符数(恒 16),失败才是负码。
|
||||
* 建成功能起这里写成 != 0,把每次成功都当失败 → 回放页开档永远走不到
|
||||
* f_open,盘上明明有段也恒显「无录波段」(2026-11-02 板级 FR 埋点
|
||||
* 钉死:scan done cnt=7 + head path fail;写侧 default_task.c 同函数
|
||||
* 用 <= 0,一直是对的)。口径取和写侧一致的 <= 0。 */
|
||||
return UI_WAVE_NONE;
|
||||
}
|
||||
if (vol_lock_wait(0u) == 0u) {
|
||||
return UI_WAVE_NONE; /* 卷忙 = 本轮按无段处理(不阻塞 uiTask) */
|
||||
}
|
||||
rc = UI_WAVE_NONE;
|
||||
if (f_open(&f, path, FA_READ) == FR_OK) {
|
||||
ofr = f_open(&f, path, FA_READ);
|
||||
if (ofr == FR_OK) {
|
||||
uint32_t size;
|
||||
uint32_t total;
|
||||
uint32_t n;
|
||||
@@ -594,6 +666,12 @@ static int ui_task_wave_load_head(uint8_t a_idx) {
|
||||
s_wave_cache_ok = 1u;
|
||||
} else {
|
||||
s_wave_cache_ok = 0u;
|
||||
if (ofr != FR_OK) {
|
||||
/* 表上明明列着这个段、开档却失败:页面只会显示「无录波段」,
|
||||
* 没有任何视觉面——必须留痕(10-31 半轮栽就栽在这类静默面上) */
|
||||
DBG_ERROR("ui wave head idx=%u open fail fr=%d", (unsigned)a_idx,
|
||||
(int)ofr);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -735,6 +813,7 @@ static int ui_task_wave_seg_win(uint8_t a_idx, uint8_t a_ch,
|
||||
int16_t *a_codes, int32_t *a_peak_milli) {
|
||||
static FIL f;
|
||||
char path[WAVE_ST_PATH_MAX];
|
||||
FRESULT fr; /* 开档 FR 码:开档失败留痕用 */
|
||||
UINT br = 0u;
|
||||
uint32_t off;
|
||||
uint32_t want;
|
||||
@@ -765,14 +844,17 @@ static int ui_task_wave_seg_win(uint8_t a_idx, uint8_t a_ch,
|
||||
if (want != UI_WAVE_WIN_PTS * 2u) {
|
||||
return UI_WAVE_BAD; /* 窗口贴不出完整 40 点:显式不可读 */
|
||||
}
|
||||
if (wave_store_seg_path(path, (uint32_t)sizeof(path), a_idx) != 0) {
|
||||
if (wave_store_seg_path(path, (uint32_t)sizeof(path), a_idx) <= 0) {
|
||||
/* 同 ui_task_wave_load_head:契约成功 = 16,失败是负码;!= 0 的旧写法
|
||||
* 把成功当失败,窗口永远贴不出(2026-11-02 根因修复,详见那里注释) */
|
||||
return UI_WAVE_NONE;
|
||||
}
|
||||
if (vol_lock_wait(0u) == 0u) {
|
||||
return UI_WAVE_NONE;
|
||||
}
|
||||
rc = UI_WAVE_BAD;
|
||||
if (f_open(&f, path, FA_READ) == FR_OK) {
|
||||
fr = f_open(&f, path, FA_READ);
|
||||
if (fr == FR_OK) {
|
||||
if ((f_lseek(&f, off) == FR_OK) &&
|
||||
(f_read(&f, s_wave_buf, want, &br) == FR_OK) && (br == want)) {
|
||||
if ((wave_store_le_decode(s_wave_buf, want, raw, UI_WAVE_WIN_PTS,
|
||||
@@ -813,6 +895,10 @@ static int ui_task_wave_seg_win(uint8_t a_idx, uint8_t a_ch,
|
||||
}
|
||||
}
|
||||
*a_peak_milli = peak;
|
||||
} else if (fr != FR_OK) {
|
||||
/* 理由同 load_head 的开档留痕:表列着的段开不出,页面无视觉面 */
|
||||
DBG_ERROR("ui wave win idx=%u ch=%u open fail fr=%d", (unsigned)a_idx,
|
||||
(unsigned)a_ch, (int)fr);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -839,9 +925,6 @@ static void ui_task_sink_beat(void) {
|
||||
task_wd_beat(TASK_WD_UI);
|
||||
}
|
||||
|
||||
#define DBG_TAG "[UI_TASK]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
/*
|
||||
* 函数功能:等待网络就绪事件
|
||||
* 入口参数:无
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
* 创建日期:2026-10-29
|
||||
* 修改记录:
|
||||
* v1.0 2026-10-29 DTU 项目组 创建(故障录波道 UI 侧)
|
||||
* v1.1 2026-11-02 DTU 项目组 按键切通道/切段补 ui_content_page_invalidate:
|
||||
* 本页 key_cb 返回 true(接管键),框架不再替本页失效重绘,状态变了
|
||||
* 屏上却纹丝不动——该病在枚举修复前整页恒空、从未有键可切,故随
|
||||
* 2026-11-02 回放页修复首次上板才暴露(真机实证见 PR #67)。
|
||||
*/
|
||||
|
||||
/* 头文件包含区 */
|
||||
@@ -394,11 +398,16 @@ static bool pg_key(lv_key_t a_key) {
|
||||
s_state = (rc == UI_WAVE_BAD) ? WP_ST_BAD : WP_ST_IDLE;
|
||||
}
|
||||
}
|
||||
/* 状态已变必须显式失效:框架只在 key_cb 返回 false 时自己 invalidate,
|
||||
* 本页接管了键(true),不失效就永远画旧画面(2026-11-02 真机实证:
|
||||
* 键送达、状态已切、屏上纹丝不动——该病随枚举修复首次上板才暴露) */
|
||||
ui_content_page_invalidate();
|
||||
return true;
|
||||
case LV_KEY_LEFT:
|
||||
case LV_KEY_RIGHT:
|
||||
if (s_state == WP_ST_IDLE) {
|
||||
wp_ensure(); /* 空态下按左右 = 再探一次盘(新段可能已落) */
|
||||
ui_content_page_invalidate();
|
||||
return true;
|
||||
}
|
||||
rc = (a_key == LV_KEY_RIGHT) ? ui_data_wave_seg_next(s_idx, &next)
|
||||
@@ -407,6 +416,7 @@ static bool pg_key(lv_key_t a_key) {
|
||||
s_idx = next;
|
||||
s_state = WP_ST_IDLE; /* 先回空态再载,坏段不会留着旧画面 */
|
||||
wp_load_seg();
|
||||
ui_content_page_invalidate(); /* 理由同上:切段成功要重绘 */
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ docs/测试说明/专项验证/模拟器差距清单.md §2.3「开机账本 boo
|
||||
| **6** | 保护元件与采集增强 | 等待标准源或硬件改版 | 保护先解除未标定闭锁;三相同时刻类功能等 V0.2 硬件 |
|
||||
| **7** | 验证窗口事项 | 逢条件顺带 | CI runner、PC peer、CH340、负向故障注入条件到位时执行 |
|
||||
| **8** | 独立模块与暂缓项 | 当前不排 | 开入开出、SNTP、104 文件传输单独立项;RS-485 与内存优化按各自重启条件 |
|
||||
| **独立** | **故障录波(1 kHz · 8 路原始码值 · 单通道回放)** | **代码面已交付;2026-10-31 远程半轮过六项,余注量对表与人到场项** | 用户裁定 2026-10-29 **录波先行**:数据面最小闭环 → 手动与保护启动触发 → 回放页。三块的**代码侧判据已收口**(主机单测 113 / 170 / 110 全 rc=0、双端编译 0 错误 0 警告、板端编码器与 PC 侧解码器字节级互验、手动录波与录波回放两叶已绑页、内容页黄金参考扩至 66 张);**2026-10-31 远程半轮已过六项**(真 FAT 落盘、触发→落盘全部落在 2 s 封存超时窗内、冷却恢复、轮转、PC 侧坏段拒收、冻结窗内 104 并发),同轮发现缺陷「回放页段表枚举恒空」登记 `登记簿.md` §2;**没跑的是注量对表那半轮**(注 1 V / 50 Hz、与 `meas:` 行和 104 浮点遥测对表、回放页放真段与坏段画面——等枚举缺陷修复)加 P 触发 / bench T 源,全部结果与清单见 `docs/子系统设计/故障录波设计说明.md` §10「板级远程半轮记录」。**板级判据、留痕名清单与执行顺序图的属主 = docs/子系统设计/故障录波设计说明.md §9 与 §10**(原卡片登记簿 2026-10-30 随销项并入后删除);**与 UI 道互斥**(菜单树与中文字库是整文件生成物,同刻只允许一条道写)——本波按此串行执行:UI 道在数据面与接线冻结之后才动生成物 |
|
||||
| **独立** | **故障录波(1 kHz · 8 路原始码值 · 单通道回放)** | **代码面已交付;2026-10-31 远程半轮过六项、2026-11-02 回放页枚举缺陷已修复闭环,余注量对表与人到场项** | 用户裁定 2026-10-29 **录波先行**:数据面最小闭环 → 手动与保护启动触发 → 回放页。三块的**代码侧判据已收口**(主机单测 113 / 170 / 110 全 rc=0、双端编译 0 错误 0 警告、板端编码器与 PC 侧解码器字节级互验、手动录波与录波回放两叶已绑页、内容页黄金参考扩至 66 张);**2026-10-31 远程半轮已过六项**(真 FAT 落盘、触发→落盘全部落在 2 s 封存超时窗内、冷却恢复、轮转、PC 侧坏段拒收、冻结窗内 104 并发);同轮发现的缺陷「回放页段表枚举恒空」**已于 2026-11-02 远程修复并板级闭环**(根因 = 读侧 `wave_store_seg_path()` 返回值判错,顺带修键处理缺失效;回放页真段/切段/切道已实测,登记簿条目已销项,证据见设计说明 §10「回放页枚举恒空缺陷修复记录」);**没跑的是注量对表那半轮**(注 1 V / 50 Hz、与 `meas:` 行和 104 浮点遥测对表、回放页放坏段与空态画面)加 P 触发 / bench T 源,全部结果与清单见 `docs/子系统设计/故障录波设计说明.md` §10「板级远程半轮记录」。**板级判据、留痕名清单与执行顺序图的属主 = docs/子系统设计/故障录波设计说明.md §9 与 §10**(原卡片登记簿 2026-10-30 随销项并入后删除);**与 UI 道互斥**(菜单树与中文字库是整文件生成物,同刻只允许一条道写)——本波按此串行执行:UI 道在数据面与接线冻结之后才动生成物 |
|
||||
|
||||
### 2.1 关键依赖
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|---|---|---|---|---|
|
||||
| dhara 重试自旋残留 | **dhara 重试自旋残留**——`try_recover()` 的 `DHARA_MAX_RETRIES`(8) 自旋在坏块密集时仍可能长时间占用 defaultTask(喂狗点) | 2026-10-02 | 低优先:现有 `vol_lock` + 喂狗节奏缓解;若台架再出"存储侧喂狗饥饿"再排期 | `Lib/dhara/map.c` |
|
||||
| 可选全序列卷锁 | **可选全序列卷锁**——现卷锁仅覆盖 `syslog` / `cfg` / `lftpd` 三条路径(`vol_lock_wait(0)` try 语义),其它潜在访问点(如 UI 读日志)未纳入 | 2026-10-02 | 待评估:先确认是否真有第二写者;无则关闭本项 | `App/fs/vol_lock.{c,h}` |
|
||||
| 回放页段表枚举恒空 | **回放页段表枚举恒空(真机缺陷)**——回放页真机开屏恒显「无录波段」,而 FTP `LIST` 六段全见、`RETR`/`DELE` 正常、同 try 锁纪律的 SOE 页读卷正常、defaultTask 写侧 `/wave` 枚举也正常——**唯独 `ui_task_wave_scan()` 在 uiTask 上下文拿不到目录条目**;伴生:`f_opendir` 失败照样置 `s_wave_scanned=1` 钉表,卷忙一类失败被钉成假空态、直到下一次 `manual_req` 才重试 | 2026-10-31 板级远程半轮(五个独立判别面见出处) | **等修复(到场轮)**:`f_opendir`/`f_readdir` 分支带 FR 码埋点定位;失败不钉表、下键重试(与 soe_store 读者同纪律);修好才有回放页坏段/空态画面的测试面 | `../子系统设计/故障录波设计说明.md` §10「板级远程半轮记录」;`App/task/ui_task.c` 扫描函数 |
|
||||
|
||||
## 3. 硬件(V0.1 缺陷 → V0.2 改版项)
|
||||
|
||||
|
||||
@@ -47,10 +47,10 @@ dhara 失败类 +84;RO 另 +208,全是该失败类名表)→ `ER_IROM1`
|
||||
<!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py -->
|
||||
| 区域 | 用量 | 容量 | 占比 |
|
||||
|---|---|---|---|
|
||||
| ER_IROM1 | 276,556 B (270.07 KB) | 1,048,576 B (1024 KB) | 26.4% |
|
||||
| ER_IROM1 | 277,124 B (270.63 KB) | 1,048,576 B (1024 KB) | 26.4% |
|
||||
| RW_IRAM1 | 94,336 B (92.12 KB) | 131,072 B (128 KB) | 72.0% |
|
||||
| RW_CCM | 57,376 B (56.03 KB) | 65,280 B (64 KB) | 87.9% |
|
||||
| **Flash (ROM 合计)** | **278,608 B (272.1 KB)** | 1,048,576 B (1024 KB) | **26.6%** |
|
||||
| **Flash (ROM 合计)** | **279,176 B (272.6 KB)** | 1,048,576 B (1024 KB) | **26.6%** |
|
||||
<!-- MEM_SNAPSHOT:END -->
|
||||
|
||||
各区的容量与常量来源:
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<!-- MEM_BUDGET:BEGIN generated by scripts/ram_baseline.py -->
|
||||
| 区域 | 用量 | 容量 | 占比 | 门禁(≤92%) |
|
||||
|---|---|---|---|---|
|
||||
| ER_IROM1 (Flash) | 276,556 B | 1,048,576 B | 26.4% | 参考 |
|
||||
| ER_IROM1 (Flash) | 277,124 B | 1,048,576 B | 26.4% | 参考 |
|
||||
| RW_CCM | 57,376 B | 65,280 B | 87.9% | PASS |
|
||||
| UNINIT_CCM | 48 B | 256 B | 18.8% | 参考 |
|
||||
| RW_IRAM1 | 94,336 B | 131,072 B | 72.0% | PASS |
|
||||
|
||||
+57
-7
@@ -2,7 +2,7 @@
|
||||
|
||||
> **模块名称**:故障录波——采样源沿用 TIM3 1 kHz 节拍,专用录波环(`App/algo/wave_ring.c`,已落地)、触发、落盘(defaultTask 是文件系统唯一写者)、取回(FTP 21 端口)、现场回放(UI 单通道页)。
|
||||
> **文档定位**:本波的**设计属主**——口径、通道集、数据形态、触发模型、文件格式、预算与所有权边界、显示契约、二期不返工的结构约束在此定稿。**板级判据与本波执行顺序的属主即本文 §9 与 §10**——原任务规划下的《故障录波》卡片登记簿已于 2026-10-30 随销项并入本文后删除(沿革见 §14);排期顺位在 `docs/任务规划/README.md` §2.0「独立」行。
|
||||
> **状态**:设计已定稿,**数据面 + 触发与落盘接线 + UI 两个页面(手动录波、录波回放)的代码面已交付(2026-10-29)**——主机单测 113 / 170 / 110 全 rc=0、双端编译 0 错误 0 警告、板端编码器与 PC 侧解码器两份独立实现字节级互验通过。**没做完的只有板级判据那一轮**(注量对表、FTP 拉回、与 `meas:` 和 104 浮点 YC 对表、CRC 不符必须拒收的实测、回放页放一段真波、两个待台架核数值),逐条列在本文 §10 板级各行。三条已裁定口径见 §1.2。**2026-10-31 远程半轮**已把其中不需要到场与注入的六样跑过(落盘道、触发时序、冷却恢复、轮转、PC 侧坏段拒收、104 并发)——结果与回放页新缺陷「段表枚举恒空」全在 §10「板级远程半轮记录」小节。
|
||||
> **状态**:设计已定稿,**数据面 + 触发与落盘接线 + UI 两个页面(手动录波、录波回放)的代码面已交付(2026-10-29)**——主机单测 113 / 170 / 110 全 rc=0、双端编译 0 错误 0 警告、板端编码器与 PC 侧解码器两份独立实现字节级互验通过。**没做完的只有板级判据那一轮**(注量对表、FTP 拉回、与 `meas:` 和 104 浮点 YC 对表、CRC 不符必须拒收的实测、回放页放一段真波、两个待台架核数值),逐条列在本文 §10 板级各行。三条已裁定口径见 §1.2。**2026-10-31 远程半轮**已把其中不需要到场与注入的六样跑过(落盘道、触发时序、冷却恢复、轮转、PC 侧坏段拒收、104 并发)——结果与回放页新缺陷「段表枚举恒空」全在 §10「板级远程半轮记录」小节;**该缺陷已于 2026-11-02 远程修复并板级闭环**(根因 = 读侧 `wave_store_seg_path()` 返回值判错 + 键处理缺失效,证据与前后对拍见 §10「回放页枚举恒空缺陷修复记录」)。
|
||||
> **相关文档**:
|
||||
> `docs/子系统设计/ADC采样节拍设计说明.md`(节拍与时序账的属主;本文 §3 的数据源就是它)
|
||||
> `docs/硬件平台/ADC通道映射说明.md`(网名 `AINn` 不等于板级 `ADCn`,也不等于转换器通道号;链路分段与削顶归属)
|
||||
@@ -324,7 +324,7 @@ flowchart TD
|
||||
| 跨工具链分叉(实证,写进来是为了下一个模块别重踩) | 两份录波 .c 只 include 自身头(链上只有 stdint.h)时,ARMCC 报 22 条 identifier "NULL" is undefined;而主机 MSVC / gcc 会传递性把 stddef.h 拉进来,**主机单测完全照不出这个分叉** → 新增模块需要用 NULL 就自己 include stddef.h(与 `App/algo/sample_ring.c` 同口径,别塞公共头) |
|
||||
| 板级 | 信号发生器注 1 V / 50 Hz → 手动一段 → FTP 拉回 → PC 脚本量出周波数、幅值、极性与注入一致;再把 PC 重算的基波有效值与板上 `meas:` 与 104 浮点 YC 对表。**判据只量四样:周波数、幅值、极性、钉轨路数——不比绝对相位**(理由见 §4.2「段内点序」:触发瞬间在工频周期内任意落点,段字节里没有绝对时间参考;真要比相位必须让发生器给同步触发,本波不做)。**钉轨对表的合格判据 = 头位图 ⊇ 实测钉轨路数,且差异必须能由注入条件解释**——因为 `clip_mask` 是按来源派生的链路可信性标记(§6.2 偏移 24 行),不是本段实测值:只加直流或小幅注入时那五路本就不该钉轨,硬取等式会假红。**同段另起一条强观察项**:V0.1 下这五路若在做**交流注入**时反而没钉轨,先怀疑接线或该路根本没被驱动——这是告警面,不是失败面(等式仍作为默认尺子留在 PC 侧 `shape --strict` 里,因为它有这个信号价值;要放行差异用那条判据的解释权,不靠改尺子)。**§5.2 第四条的板级观察项(代码与单测面已有、板级未测)**:bench 连续自抓期间人为把卷占住 2 s 以上(例如同一段跑 FTP 大文件读),看串口 `wave:` 行的 `err` 是否加一、是否只出现**一条** `[ERR] … seg drop: ring abandoned` 留痕(不是每拍刷屏)、且段号不推进(下一段仍写同号文件) |
|
||||
| 板级·触发来路(2026-10-30 并入原卡「手动触发与保护启动接线」板级段) | 真机面板按一次「手动录波」出一段;造一次过流,段号与该时刻 `/log/start.log` 事件对齐;冷却期内二次触发只加 `ovf` 不重录(**同时看 `armed` 与那一刻 start.log 的时刻,不要只盯 `ovf` 数字**——容差见 §9);冻结窗口内 104 上送与保护判据不受影响(这条是「丢录波样本不丢采集」的验收) |
|
||||
| 板级·回放页(2026-10-30 并入原卡「现场单通道回放页」板级段) | 真机上放一段真波(不是模拟器合成节拍);远端看图能拍到该页做留证(只作留证,不是波形通路,§8.4);**空态与 CRC 失败态绝不允许画成一条直线**——用坏段在真机复现一次。**2026-10-31 远程半轮进展见下「板级远程半轮记录」小节**:PC 侧坏段拒收已过;回放页坏段/空态画面**没够到测试面**(缺陷「回放页段表枚举恒空」) |
|
||||
| 板级·回放页(2026-10-30 并入原卡「现场单通道回放页」板级段) | 真机上放一段真波(不是模拟器合成节拍);远端看图能拍到该页做留证(只作留证,不是波形通路,§8.4);**空态与 CRC 失败态绝不允许画成一条直线**——用坏段在真机复现一次。**2026-10-31 远程半轮进展见下「板级远程半轮记录」小节**:PC 侧坏段拒收已过;回放页坏段/空态画面的测试面**已于 2026-11-02 枚举缺陷修复后打开**(真机已验证真段显示 + 切段切道,见下「回放页枚举恒空缺陷修复记录」小节),坏段/空态两画面本身仍是到场轮要拍的项 |
|
||||
| UI | `ui-verify` 五步;回放页入 `ui-golden` 黄金参考(**参考图一旦入库只能改代码对齐,禁止刷参考掩盖**);新叶走 `gen_menu.py` 重生成 + 字库链 |
|
||||
| 构建 | `/keil-build` 要求 0 错误 0 警告;新 .c 双端注册走 `new-source-file`(`MDK-ARM/STM32F407-Demo.uvprojx` 与 `simulator/CMakeLists.txt` 两处显式列表) |
|
||||
| 台账 | R6 三处同步 + `scripts/ram_baseline.py --update` + `mem-numbers` 与 `mem-budget` 钩子 |
|
||||
@@ -367,13 +367,14 @@ bench 锁全程持有(收工 release,PASS 证据就是本小节);设备
|
||||
| 冻结窗口内 104 上送无恙(**正式判据项**) | 参考主站 `test/host/iec104_master.py` 全程跑在落盘窗口内:GI 扫描(双点组 / 单点组 / YC 组 / 频率)+ actterm + 定值读回全绿,**唯二 FAIL 是两条 COV 腿 = 标定闭锁腿(OC1 不出口,物理预期,非链路故障)**;全程无链路异常、无 send fail |
|
||||
| `drop` 观测 | 每冻结窗约 400–640 点(51–79 拍 × 8 路)入账,量级 = SEALED 态每拍 push +8 直到落盘 ACK 的窗口长度;`seg` 无丢段、`err`=0,采集无恙——纯观察项非失败(「丢样本不丢采集」的实测面) |
|
||||
|
||||
**新发现缺陷「回放页段表枚举恒空(板级)」**(登记 `docs/任务规划/登记簿.md` §2):回放页真机开屏恒显
|
||||
**新发现缺陷「回放页段表枚举恒空(板级)」**(原登记 `docs/任务规划/登记簿.md` §2,**2026-11-02 修复闭环后按「完成即销项」删行,完整记录即本小节**):回放页真机开屏恒显
|
||||
「无录波段」,而 FTP `LIST` 六段全见、`RETR`/`DELE` 正常。判别面(五个独立复核,全非偶然):
|
||||
手动触发照常成段(计数 + 真文件都在)⇒ 写侧取卷锁正常;SOE 记录页(同一条 `vol_lock_wait(0)`
|
||||
try 锁纪律)照常读出并显示 ⇒ try 锁读径正常;`manual_req` 作废段表缓存后重扫**仍空** ⇒ 不是
|
||||
心跳写抢锁的一次性 miss;defaultTask 写侧 `wave_store_next_idx()` 对 `/wave` 的枚举正常
|
||||
(坏段 DELE 后 WAVE05 正确回到同号为证)⇒ FatFs 层 readdir 能力正常。**定性:`ui_task_wave_scan()`
|
||||
在 uiTask 上下文下拿不到目录条目**,根因须上埋点(`f_opendir`/`f_readdir` 分支带 FR 码)或到场隔离。
|
||||
(坏段 DELE 后 WAVE05 正确回到同号为证)⇒ FatFs 层 readdir 能力正常。~~定性:`ui_task_wave_scan()`
|
||||
在 uiTask 上下文下拿不到目录条目~~ ——**该定性已被 2026-11-02 的 FR 埋点推翻(目录枚举一直正常,
|
||||
坏的是读侧拼路径的返回值判错),见下小节;这段保留只为记录当时的推理起点**。
|
||||
伴生代码纪律问题同页修(本轮读码钉死,独立于上面的主缺陷):**`f_opendir` 失败也无条件置
|
||||
`s_wave_scanned=1`**(`App/task/ui_task.c` 扫描函数尾)——卷忙 / `FR_DENIED` 一类失败会被钉成
|
||||
「0 段缓存」,回放页从此假显「无录波段」、直到下一次 `manual_req` 才重试;失败应不钉表、
|
||||
@@ -381,8 +382,9 @@ try 锁纪律)照常读出并显示 ⇒ try 锁读径正常;`manual_req` 作
|
||||
|
||||
**本半轮没跑的(人到场轮清单)**:注量对表(周波数 / 幅值 / 极性 / 钉轨路数)、`meas:` 与 104
|
||||
浮点 YC 数值对表、两个待台架核数值(封存超时窗 §4.2 兜底行与冷却时长 `App/algo/wave_ring.h`)、P 触发与 start.log 对齐(还得先解标定闭锁)、
|
||||
bench T 源与卷占用 2 s 的 `ring abandoned` 观察(需 bench 构建)、**回放页坏段画面与空态画面
|
||||
(等枚举缺陷修复后才有测试面)**、`task_prof` 读路径耗时峰值。**执行动作侧**(到场的人做什么、
|
||||
bench T 源与卷占用 2 s 的 `ring abandoned` 观察(需 bench 构建)、~~回放页坏段画面与空态画面
|
||||
(等枚举缺陷修复后才有测试面)~~ **(2026-11-02 枚举缺陷修复后测试面已开,见下小节)**、
|
||||
`task_prof` 读路径耗时峰值。**执行动作侧**(到场的人做什么、
|
||||
说哪句话、会看到什么)→ `docs/测试说明/专项验证/故障录波板级到场轮执行手册.md`。
|
||||
|
||||
**远程驱动教训(7003 注键)**:KEY 的 ACK 与 LCDMEM 推流共用同一条 TCP,按键后**必须 drain 到
|
||||
@@ -390,6 +392,54 @@ bench T 源与卷占用 2 s 的 `ring abandoned` 观察(需 bench 构建)、
|
||||
页**的捷径而非进菜单(本次上电开过页之后);级联列光标开列时记忆上次位置、不归零。三条的
|
||||
执行纪律归主 `scripts/board_ui_nav.py` 文件头,本文只留事实现场。
|
||||
|
||||
### 回放页枚举恒空缺陷修复记录(2026-11-02,板级远程闭环)
|
||||
|
||||
bench 锁全程持有;三次烧录(埋点 / 诊断加强 / 根因修复)均由 `run_boot_test.py` 校验身份戳与
|
||||
回读一致(`READBACK: OK (no difference found)`)、启动门禁 `VERDICT: PASS`。**10-31 的定性被本轮
|
||||
推翻**——目录枚举从未坏过,坏的是读侧判返回值。四步证据链:
|
||||
|
||||
1. **第一幕(失败不钉表 + FR 埋点,PR 第三提交同批)**:`ui_task_wave_scan()` 失败分支补 FR 码留痕、
|
||||
失败不再无条件钉 `s_wave_scanned`。埋点构建上板后开回放页,串口**零新增留痕**……但这不等于
|
||||
枚举正常:第一版扫描只在「失败 / 零条目」两种情况下打印,**成功但有段**这条路是静默的
|
||||
(教训:留痕必须覆盖成功路径,否则「没打印」与「没执行」无法区分)。
|
||||
2. **诊断加强(临时构建,已随根因修复收敛)**:扫描入口加 `#N` 序号、try 闸失败打印
|
||||
`vol_lock_get_stats()` 计数(消费方观测,不取锁,符合 `docs/子系统设计/看门狗设计说明.md` §4.3 的锁层静默口径)、完成行改为无条件打印、`load_head`/`seg_win` 的 try 闸/拼路径/开档
|
||||
失败全部带 FR 码。上板实录(2026-11-02 17:49 串口):
|
||||
|
||||
[UI_TASK] ui wave scan #1 done cnt=7 np=0 tt=0 ac=407
|
||||
[ERR][UI_TASK] ui wave head #1 path fail idx=6
|
||||
|
||||
**`cnt=7` 一锤定音:目录枚举、卷锁(tt=0 一次没撞)全都正常**;坏在随后取段——`idx=6` 是
|
||||
数值最大段,即页面首帧要显示的段——`wave_store_seg_path()` 拼接失败。
|
||||
3. **根因**:`wave_store_seg_path()` 契约(`App/algo/wave_store.h`)是「≥0 = 写入的字符数
|
||||
(当前布局恒 16),失败才是负码」,而读侧 `ui_task_wave_load_head()` 与 `ui_task_wave_seg_win()`
|
||||
从功能建成起写成 `!= 0` 判失败——**每次成功(16)都被判成失败**,`f_open` 永远走不到,
|
||||
盘上有段也恒显「无录波段」。写侧 `App/task/default_task.c` 同一函数用 `<= 0`,一直是对的;
|
||||
模拟器用假 `s_wave_ops` 桩、不编译读路径,所以黄金参考图与三组主机单测从未暴露此病。
|
||||
两处口径改 `<= 0`(与写侧最末下游同口径),并给「表上列着、开档却失败」补永久 FR 留痕
|
||||
(该失败态页面无视觉面,10-31 误定性的教训就是静默)。
|
||||
4. **第二缺陷(同页,随枚举修复首次上板才暴露)**:`Drivers/BSP/UI/ui_page_wave_play.c` 的 `pg_key()`
|
||||
接管控件键(key_cb 返回 true)后从未调 `ui_content_page_invalidate()`——框架只在 key_cb
|
||||
返回 false 时替页失效。真机实证:按键送达、`s_idx/s_ch` 已变、**帧字节完全不变**(同帧
|
||||
SHA-256),切道切段屏上纹丝不动。三处成功路径各补一次失效(与 `ui_page_clock` /
|
||||
`ui_page_password` 等已接管键的页面同纪律);切段失败仍保持「按了没动」的诚实语义、不重绘。
|
||||
该病被枚举缺陷完全遮住(整页恒空、没有可切的画面),故从 2026-10-29 建成存活至今。
|
||||
|
||||
**修复后板级复核(同一台架、同一固件次)**:回放页开屏显数值最大段(WAVE06)UA 波形
|
||||
`UA SEC6 M`、Pk=-1423 mV、0 线与触发光标在位;`l` 切上一段(`UA SEC5 M`、Pk=1744 mV),
|
||||
`d` 切下一通道(`UB SEC5 M`、右上「削」徽标、Pk=843 mV);`↑↓/←→` 每按必重绘。
|
||||
修复前后对拍图(同 APP、同 scale、同键序,仅固件不同):
|
||||
|
||||
| 版本 | 回放页开屏 |
|
||||
|---|---|
|
||||
| 修复前(`7efa58d9` 构建,2026-11-02 实测) |  |
|
||||
| 修复后(`fix-replay-enum-0e52b1963afa` 分支构建,2026-11-02 实测) |  |
|
||||
|
||||
图生成口令(可复现):`scripts/board_ui_nav.py` 走 UI + 7003 `LCDMEM` 取帧 + 4× 放大渲染;
|
||||
图源 = 本记录所属提交的台账同批留档 `docs/测试说明/测试数据/wave_enum_20261102/`
|
||||
(Before/After、切段、切道共四帧 + 串口实录,见该目录 README)。
|
||||
**至此回放页「真段 / 坏段 / 空态」三态全部有了测试面**,第二幕尾步的坏段画面判据可跑。
|
||||
|
||||
---
|
||||
|
||||
## 11. 与 `docs/任务规划/数据可信.md` 的口径变更(三处)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 故障录波板级到场轮执行手册(人要做的事,一步一行)
|
||||
|
||||
> **这份手册解决什么**:录波的判据里剩下的那半轮——需要**有人的手和信号发生器**的验证——把它拆成"你做什么、说哪句话、会看到什么"。
|
||||
> **它不是判据属主**:判据、留痕名清单、执行顺序图全在 `docs/子系统设计/故障录波设计说明.md` §9 与 §10;本文只写**执行动作**。已完成部分(2026-10-31 远程半轮六项 PASS + 缺陷「回放页段表枚举恒空」)见 §10「板级远程半轮记录」。
|
||||
> **它不是判据属主**:判据、留痕名清单、执行顺序图全在 `docs/子系统设计/故障录波设计说明.md` §9 与 §10;本文只写**执行动作**。已完成部分(2026-10-31 远程半轮六项 PASS + 2026-11-02 缺陷「回放页段表枚举恒空」修复闭环)见 §10「板级远程半轮记录」与 §10「回放页枚举恒空缺陷修复记录」。
|
||||
> **一句话预算**:你到场约 1.5~2 小时;其中真正动手的只有**接三次线、按不超过六次键、拍两个决定**——其余全部由会话里的 agent 跑脚本。
|
||||
|
||||
---
|
||||
@@ -10,12 +10,12 @@
|
||||
|
||||
| 幕 | 名字 | 要你在场? | 你动手的部分 | agent 跑的部分 | 对应判据 |
|
||||
|---|---|---|---|---|---|
|
||||
| 第一幕 | 枚举埋点与修复上板 | **可远程**(ST-LINK 在本机就不用到场) | 无(或帮忙看一眼烧录没报错) | 改码加埋点 → 构建 → 烧录回读 → 远程开回放页 → 读 FR 码定性 → 修复重烧 | 登记簿「回放页段表枚举恒空」 |
|
||||
| 第一幕 | 枚举埋点与修复上板 | **已完成(2026-11-02,远程)** | 无 | 改码加埋点 → 构建 → 烧录回读 → 远程开回放页 → 读 FR 码定性 → 修复重烧 | `docs/子系统设计/故障录波设计说明.md` §10「回放页枚举恒空缺陷修复记录」 |
|
||||
| 第二幕 | 注量对表 | **要到场**(只有接线需要手) | 接 UA 发生器线 1 次、拔 1 次;面板按 2 次键(或让 agent 远程注键) | 记心跳基准 → FTP 拉段 → `wave_read` 量四样 → `meas:`/104 YC 对表 → 削顶注大一遍 → 坏段上板看回放页绝不平线 | `docs/子系统设计/故障录波设计说明.md` §10「板级」行 +「板级·回放页」行后半 |
|
||||
| 第三幕 | P 触发对时刻 | **要到场**,还含**两个由你拍板的决定** | IA 两点标定各接一次线 + 过流加大到 UI 见数值过 2 A | 读码算 k/b → 写配置生效 → 验证解锁 → 触发后对 start.log 时刻/段号/src=P | `docs/子系统设计/故障录波设计说明.md` §10「板级·触发来路」行 |
|
||||
| 第四幕 | bench 自抓与卷占用 | **可远程**(烧录同上;占卷用 FTP 造) | 无 | 烧 bench 构建 → 造占卷 ≥2 s → 看 `err`+1、**一条** `ring abandoned`、同号重写 → 还原产品构建 | `docs/子系统设计/故障录波设计说明.md` §10 板级行的 `ring abandoned` 观察项 |
|
||||
|
||||
幕间依赖:**只有第二幕的"坏段上板看回放页"一步等第一幕修好**;其余各幕互相独立,可以先做不用等的。
|
||||
幕间依赖:**第二幕的"坏段上板看回放页"一步已不再被阻塞**(第一幕 2026-11-02 已修好并板级闭环);其余各幕互相独立,可以先做不用等的。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -38,9 +38,17 @@ flowchart LR
|
||||
|
||||
---
|
||||
|
||||
## 3. 第一幕「枚举埋点与修复上板」——你可以不在场
|
||||
## 3. 第一幕「枚举埋点与修复上板」——已完成(2026-11-02)
|
||||
|
||||
**为什么排第一**:回放页现在真机恒显「无录波段」(六段文件明明都在盘上,2026-10-31 已钉死是 `ui_task_wave_scan()` 在 uiTask 上下文拿不到目录条目)。第二幕尾步要在这个页面上看坏段画面,页面不修好就没测试面。
|
||||
> **状态更新:本幕已于 2026-11-02 远程做完并板级闭环,现场无需重做。** 结论:10-31 的定性
|
||||
> 被 FR 埋点推翻——目录枚举一直正常(`scan done cnt=7`),坏的是读侧把 `wave_store_seg_path()`
|
||||
> 的成功返回值(16 字符)当失败(`!= 0`),`f_open` 永远走不到;另修同页键处理缺
|
||||
> `ui_content_page_invalidate()` 导致的切道切段不重绘。回放页现可显示真波、切段、切道,
|
||||
> 坏段/空态两态已有测试面。完整证据与前后对拍图 → `docs/子系统设计/故障录波设计说明.md`
|
||||
> §10「回放页枚举恒空缺陷修复记录」、`docs/测试说明/测试数据/wave_enum_20261102/`。
|
||||
> 下面三步保留作历史记录,**你到场时不用再跑**。
|
||||
|
||||
**为什么排第一**:回放页原先真机恒显「无录波段」(六段文件明明都在盘上,2026-10-31 定性为 `ui_task_wave_scan()` 在 uiTask 上下文拿不到目录条目——**该定性 2026-11-02 已被埋点推翻**)。第二幕尾步要在这个页面上看坏段画面,页面不修好就没测试面。
|
||||
|
||||
1. **[agent]** 在 `App/task/ui_task.c` 的扫描函数给 `f_opendir`/`f_readdir` 失败分支加带 FR 码的留痕(顺带修伴生纪律:失败不许钉 `s_wave_scanned=1`)→ `/keil-build` 0 错误 0 警告 → 烧录(`-Rst -Run` + 回读校验,见 `docs/测试说明/测试工具/ST-LINK_CLI_复位使用说明.md`)。
|
||||
2. **[agent]** 等 30 s 装置起来 → 远程走 UI 开回放页 → 串口读那条带 FR 码的新留痕。
|
||||
@@ -49,6 +57,7 @@ flowchart LR
|
||||
5. **要烧几次板,都由 agent 盯**;你只在会话里看到"请确认烧录"时回一个"烧"字(烧录动作属 Ask-first 边界,agent 不会自己烧)。
|
||||
|
||||
**这一幕完成的标志**:回放页能列出段并可翻段——agent 会给你一张远程抓屏图,画面顶行有通道名和段号。
|
||||
(2026-11-02 实际交付:开屏 `UA SEC6 M`、`l` 切至 `UA SEC5 M`、`d` 切至 `UB SEC5 M`,均带波形与峰值标注。)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# 回放页枚举恒空修复证据(2026-11-02)
|
||||
|
||||
本目录是 `docs/子系统设计/故障录波设计说明.md` §10「回放页枚举恒空缺陷修复记录」的图源留档。
|
||||
台架远程操作、bench 锁全程持有;三张现场帧均由 `scripts/board_ui_nav.py` 的 7003 链路取
|
||||
`LCDMEM` 原帧后按 4× 放大渲染,与固件同一次上电、同一块板。
|
||||
|
||||
## 文件
|
||||
|
||||
| 文件 | 内容 | 说明 |
|
||||
|---|---|---|
|
||||
| `before_replay_page.png` | 修复前固件(`7efa58d9` 构建,身份戳 `Nov 2 2026 14:21:24`)回放页开屏 | 恒显「无录波段」,而同一时刻 FTP `LIST /wave` 六段全在(5250 B/段) |
|
||||
| `after_replay_page.png` | 修复后分支构建(`fix-replay-enum-0e52b1963afa`,Code=247,288 B)回放页开屏 | 数值最大段 `UA SEC6 M` 波形 + 0 线 + 触发光标,Pk=−1423 mV |
|
||||
| `after_segment_switch.png` | 同上固件,按 `l`(←)切上一段 | `UA SEC5 M`、Pk=1744 mV(段表项存在且可读) |
|
||||
| `after_channel_switch.png` | 同上固件,按 `d`(↓)切下一通道 | `UB SEC5 M`、右上「削」徽标(形状受限位图生效),Pk=843 mV |
|
||||
|
||||
## 根因串口实录(诊断构建上板,2026-11-02 17:49,板时 09:49)
|
||||
|
||||
[2026-11-02 09:49:18][UI_TASK] ui wave scan #1 done cnt=7 np=0 tt=0 ac=407
|
||||
[2026-11-02 09:49:18][ERR][UI_TASK] ui wave head #1 path fail idx=6
|
||||
|
||||
- 第一行 `cnt=7 np=0 tt=0` = 目录枚举拿到七段、卷锁无一次 try 超时 → 10-31「uiTask 拿不到
|
||||
目录条目」的定性被推翻;
|
||||
- 第二行 = 取最大段(idx=6)的段头时拼路径判失败 → 根因在 `wave_store_seg_path()` 返回值
|
||||
契约用反(成功 = 16 字符,读侧按 `!= 0` 判失败),修复见 `App/task/ui_task.c` 两处 `<= 0`。
|
||||
|
||||
复现口令(台架同环境):
|
||||
|
||||
1. `& .venv\Scripts\python.exe .dsh\skills\serial-boot-test\scripts\run_boot_test.py`(烧录 + 启动门禁)
|
||||
2. `& .venv\Scripts\python.exe scripts\board_ui_nav.py --board --to wave_play --i-hold-bench-lock`(走 UI 开页)
|
||||
3. 7003 `LCDMEM` 取帧渲染(本目录四帧的生成方式)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -14,3 +14,4 @@ date code ro rw zi er_irom1 er_pct iram1 iram1_pct ccm ccm_pct top_rwzi
|
||||
2026-10-29 238936 29140 1932 141396 268076 25.6 85904 65.5 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;sb_link.o=4364;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055
|
||||
2026-10-29 243552 28784 1972 145388 272336 26.0 89936 68.6 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;wave_ring.o=5296;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055
|
||||
2026-10-30 246720 29836 2052 149708 276556 26.4 94336 72.0 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
|
||||
2026-11-02 247288 29836 2052 149708 277124 26.4 94336 72.0 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
|
||||
|
||||
|
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"built_at": "2026-11-02T14:32:47+08:00",
|
||||
"fingerprint": "c5294354ba3e05e51882676c7edddf995852d114c6f6413016e49adc7f6ac2a6",
|
||||
"built_at": "2026-11-02T18:21:27+08:00",
|
||||
"fingerprint": "a4435f138bc6dc5fe18779977ec5a2515e15e72ceeecb9653ce2930b640e71c2",
|
||||
"fingerprint_files": 1466,
|
||||
"fingerprint_source": "git-index",
|
||||
"gated_regions": [
|
||||
"RW_IRAM1",
|
||||
"RW_CCM"
|
||||
],
|
||||
"git_head": "e63abb919a5934511ffc7e8fea2c5b86dbfc70fc",
|
||||
"git_head": "d6253aa974f4357779d0a94ff24ba66a58abf094",
|
||||
"map": "MDK-ARM/STM32F407-Demo/STM32F407-Demo.map",
|
||||
"map_mtime": 1793600487,
|
||||
"map_mtime": 1793614877,
|
||||
"pct": {
|
||||
"ER_IROM1": 26.37,
|
||||
"ER_IROM1": 26.43,
|
||||
"RW_CCM": 87.89,
|
||||
"RW_IRAM1": 71.97,
|
||||
"UNINIT_CCM": 18.75
|
||||
@@ -19,7 +19,7 @@
|
||||
"regions": {
|
||||
"ER_IROM1": {
|
||||
"max": 1048576,
|
||||
"size": 276556
|
||||
"size": 277124
|
||||
},
|
||||
"RW_CCM": {
|
||||
"max": 65280,
|
||||
@@ -37,7 +37,7 @@
|
||||
"schema": 2,
|
||||
"scope_note": "\u540c\u7801\u51ed\u8bc1\uff1a\u6307\u7eb9\u8986\u76d6\u56fa\u4ef6\u4f53\u79ef\u76f8\u5173\u6e90\u7801\uff0c\u53e3\u5f84\u89c1\u672c\u811a\u672c docstring",
|
||||
"sizes": {
|
||||
"code": 246720,
|
||||
"code": 247288,
|
||||
"ro_data": 29836,
|
||||
"rw_data": 2052,
|
||||
"zi_data": 149708
|
||||
|
||||
Reference in New Issue
Block a user