fix(ui/screenlink): 按键应答扣到按键后画面,反馈典型 250-450 ms 降至 70-135 ms
按键召唤答的是按键前的旧帧:uiTask 还没消化键答案就发走了,新画面 只能等下一次周期召唤(280 ms/轮)才带得出——真机反馈 250-450 ms 的 主构成(根因账本 docs/子系统设计/屏板链路设计说明.md §7.1)。 改动(用户批准范围 A+B+C;屏板固件未动,决策三不变): - sb_link:按键召唤改为只入队不起发;uiTask 同拍重绘并组帧成功后交 凭据(sb_link_key_rendered),TIM3 1 kHz 的 sb_link_ms_tick 以 ≤1 ms 放行新帧。140 ms 截止(SB_KEY_RESP_MAX_MS,+59.6 ms 线上 <205 ms 屏板放弃线)保底发旧帧,"一召一答"契约不破;线忙时同旧丢单、 不留扣件。起发两中断源(USART1 IDLE/TIM3)共用 sb_tx_kick, "判忙→占位"在 PRIMASK 临界区原子完成。 - ui_task:排空注键挪到组帧之前,注键→即派即绘→组帧同拍闭环; 组帧返回 BSP_OK 才交重绘凭据(BUSY 拍帧还没反映按键)。 - ui_port:注键单槽改 8 深环(连按不再互相覆盖,满丢最旧+计数); 新增 ui_port_service_keys:同拍 lv_indev_read + lv_refr_now, 省掉 indev ≤20 ms + 刷新 ≤20 ms 两段等待。 - ui_menu_view:菜单移动选中只失效新旧两行带(黄金参考零像素变化), 滚动/异常回退整框失效。 - simulator:窗口循环 sleep 扣除本轮已耗时(原先无条件睡满 lv_timer_handler 返回值,叠加 Windows Sleep 15.6 ms 粒度放大观感)。 - 串口 TX 上报新增 dfok/dfold(凭据放行新帧数/超时保底旧帧数): dfold 连涨 = uiTask 被饿 ≥140 ms 的直接现场证据。 验证:test/host/sb_link 164/164(新增 18 条:不立刻起发/凭据放行/ 140 ms 截止保底/忙时不留扣件/陈旧凭据不放行等边界);菜单 8 状态 + 内容页 66 张黄金像素 PASS;Keil @build 0 错误 0 警告(两次); BOM 99 文件无漂移、代码规范、doc-links 本次文件零问题、cppcheck PASS。 文档:屏板规划文档已被主干收编进设计说明,延迟账本落 docs/子系统设计/屏板链路设计说明.md §7.1,并同步 §4 口径、§8 接口、 §9.1 单测台账 146→164、§10 坑账本补条。 RAM 台账(分支不跑 --write,并行分支提交约定):本笔盖戳行 RW_IRAM1 94,336 B (72.0%) / RW_CCM 57,376 B (87.9%),较上一台账行 +4,400 B——为距上次台账构建以来分支累计差(含批 3 状态灯等未盖戳 提交),非全部本笔引入;本次自身增量按对象计为 ui_port.o +12 B (8 深键环+丢计数+indev 指针)与 sb_link/o 数十字节级。 gate: only mem-budget/mem-numbers pending lead ledger backfill (合并落主干后 Lead 统一 --write 回填受管区)。
This commit is contained in:
@@ -20,6 +20,9 @@
|
||||
* s_depth 决定,键回调 user_data=depth 冗余);根框装饰
|
||||
* (浅 V)+状态行改容器自绘(删 3 lv_line + 1 label 对象)
|
||||
* 2026-09-09 王建锋 "浅 V"装饰几何提取至共享 ui_deco 模块(不再本地重复定义)
|
||||
* 2026-10-30 王建锋 按键提速:view_apply_sel 选中移动且未滚动时
|
||||
* 只失效新旧两行竖带(lv_obj_invalidate_area),绘制量
|
||||
* 从整框降到 ~2/7;滚动/首建仍整框兜底
|
||||
*/
|
||||
|
||||
/* 头文件包含区 */
|
||||
@@ -320,14 +323,50 @@ static void view_scroll_to_sel(lv_obj_t *box, const menu_frame_t *f) {
|
||||
* 限定条件:该层框体已建
|
||||
* 函数说明:1. 行不是对象:选中只是数据,自绘回调绘制时定反色带/文字色
|
||||
* 2. 选中行滚入可见区(手动计算,无行对象可供 scroll_to_view)
|
||||
* 3. 失效框体:下一帧重绘
|
||||
* 3. 失效范围按改动面收敛(2026-10-30 按键提速 C):
|
||||
* · 选中变了且**没发生滚动** → 只有新旧两行外观变化,
|
||||
* 只脏这两行组成的竖带(根框 107 px 高、行高 15 px,绘制量
|
||||
* 从整框降到 ~2/7;自绘回调本就有 clip 剔除,带外行直接跳过)
|
||||
* · 发生滚动 / 首次应用(新旧同号)→ 整框失效兜底
|
||||
* 4. 失效区用绝对坐标,与自绘回调同一坐标框架
|
||||
* (content_coords 起算、减滚动偏移)
|
||||
*/
|
||||
static void view_apply_sel(uint8_t depth, uint8_t sel) {
|
||||
menu_frame_t *f = &s_frame[depth];
|
||||
menu_frame_t *f = &s_frame[depth];
|
||||
lv_obj_t *box = s_frame_box[depth];
|
||||
uint8_t sel_old = f->sel;
|
||||
int32_t sy_before = lv_obj_get_scroll_y(box);
|
||||
|
||||
f->sel = sel;
|
||||
view_scroll_to_sel(s_frame_box[depth], f); /* 选中行必在可见区内 */
|
||||
lv_obj_invalidate(s_frame_box[depth]); /* 重绘框体(反色带/文字色绘制时决定) */
|
||||
view_scroll_to_sel(box, f); /* 选中行必在可见区内 */
|
||||
|
||||
if ((sel_old != sel) && (lv_obj_get_scroll_y(box) == sy_before)) {
|
||||
lv_area_t ca;
|
||||
lv_area_t band;
|
||||
int32_t y_old;
|
||||
int32_t y_new;
|
||||
|
||||
lv_obj_get_content_coords(box, &ca);
|
||||
y_old = ca.y1 + (int32_t)sel_old * MENU_ROW_H - sy_before;
|
||||
y_new = ca.y1 + (int32_t)sel * MENU_ROW_H - sy_before;
|
||||
|
||||
band.x1 = ca.x1;
|
||||
band.x2 = ca.x2;
|
||||
band.y1 = (y_old < y_new) ? y_old : y_new;
|
||||
band.y2 = (y_old > y_new) ? y_old : y_new;
|
||||
band.y2 += (MENU_ROW_H - 1);
|
||||
if (band.y1 < ca.y1) {
|
||||
band.y1 = ca.y1; /* 旧选中行可能被框顶裁掉(级联框贴屏上沿时) */
|
||||
}
|
||||
if (band.y2 > ca.y2) {
|
||||
band.y2 = ca.y2; /* 同理框底 */
|
||||
}
|
||||
if (band.y1 <= band.y2) {
|
||||
lv_obj_invalidate_area(box, &band);
|
||||
return;
|
||||
}
|
||||
}
|
||||
lv_obj_invalidate(box); /* 兜底:有滚动或首次建立,整框重绘 */
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user