From 03f175e7ba39f46625b57008bee22d9554e5f813 Mon Sep 17 00:00:00 2001 From: Wanderingss <1624155937@qq.com> Date: Mon, 21 Sep 2026 03:50:54 +0800 Subject: [PATCH] =?UTF-8?q?I1=20=E7=BB=98=E5=88=B6=E7=BC=93=E5=86=B2?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E5=86=99=E5=85=A5=20ui=5Fport.h=20=E5=B9=B6?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E4=BD=99=E6=8A=A4=E6=A0=8F=EF=BC=8C?= =?UTF-8?q?=E5=8F=96=E5=B8=A7=E7=AB=AF=E8=A1=A5=E9=98=B2=E5=9B=9E=E5=BD=92?= =?UTF-8?q?=E6=B3=A8=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Drivers/BSP/UI/ui_net_sink_backend_mcu.c | 5 ++++- Drivers/BSP/UI/ui_port.c | 18 ++++-------------- Drivers/BSP/UI/ui_port.h | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Drivers/BSP/UI/ui_net_sink_backend_mcu.c b/Drivers/BSP/UI/ui_net_sink_backend_mcu.c index feddb7c6..7d42cb3d 100644 --- a/Drivers/BSP/UI/ui_net_sink_backend_mcu.c +++ b/Drivers/BSP/UI/ui_net_sink_backend_mcu.c @@ -20,7 +20,10 @@ * out_size - out 容量(字节) * 返回值:0 - 成功,-1 - 参数或帧缓冲无效 * 限定条件:ui_port_init() 已成功 - * 函数说明:帧缓冲本就是 1bpp(布局与协议一致),直接整帧拷贝 + * 函数说明:帧缓冲本就是 1bpp 且**已是纯像素**(无 palette),直接整帧拷贝。 + * 注意:不要改成直接读 LVGL 绘制缓冲 g_ui_draw_buf——那是索引色 + * [palette 8B][pixel data] 布局(见 ui_port.h),首 8 字节是调色板, + * 直接拷会让推流画面整体错位 8 字节;flush 回调已跳过 palette 写入本缓冲。 */ int ui_net_sink_get_lcdmem(uint8_t *out, uint32_t out_size) { const uint8_t *fb; diff --git a/Drivers/BSP/UI/ui_port.c b/Drivers/BSP/UI/ui_port.c index 631230eb..dd1e1fa8 100644 --- a/Drivers/BSP/UI/ui_port.c +++ b/Drivers/BSP/UI/ui_port.c @@ -15,18 +15,9 @@ /* 160x160 1bpp 帧 = 3200 字节 */ static uint8_t g_ui_fbuf[UI_FB_SIZE]; -/* LVGL 9.3 索引色(I1)绘制缓冲的真实布局 = [palette 8B][pixel data stride*h]: - * - lv_draw_buf_create() 按 stride*h + palette 分配; - * - lv_draw.c:497 → lv_draw_buf_goto_xy() 取绘制指针时先 += palette; - * - lv_refr.c get_max_row() 也从 data_size 里扣掉 palette 才当可用像素。 - * 但 lv_display_set_buffers()/lv_draw_buf_init() 的容量校验只看 stride*h(不含 palette), - * 所以"只给 stride*h 字节"会被静默接受 → 末 8 个像素字节写到缓冲之外 - * (2026-09-21 金丝雀实测:越界 n=8,且 flush 回调收到的首地址前 8 字节是 palette)。 - * 本端口据此按 stride*h + palette 提供缓冲,flush 时跳过 palette 取真实像素。 - * UI_DRAW_BUF_GUARD 只给后续 LVGL 版本差异留余量,不再依赖它吸收越界。 */ -#define UI_DRAW_BUF_PALETTE ((uint32_t)LV_COLOR_INDEXED_PALETTE_SIZE(LV_COLOR_FORMAT_I1) * 4u) -#define UI_DRAW_BUF_GUARD 32 -static uint8_t g_ui_draw_buf[UI_FB_SIZE + UI_DRAW_BUF_PALETTE + UI_DRAW_BUF_GUARD]; +/* 绘制缓冲:I1 索引色布局 = [palette 8B][pixel data],尺寸与取像素偏移的完整说明见 + * ui_port.h 中 UI_DRAW_BUF_PALETTE / UI_DRAW_BUF_SIZE 注释(含越界与整帧错位的历史成因)。 */ +static uint8_t g_ui_draw_buf[UI_DRAW_BUF_SIZE]; /* 单键缓冲:菜单无需多键队列,仅保存最近一次待处理键 */ static volatile uint8_t g_pending_key = 0; @@ -109,8 +100,7 @@ int ui_port_init(void) { return -1; } lv_display_set_color_format(disp, LV_COLOR_FORMAT_I1); - lv_display_set_buffers(disp, g_ui_draw_buf, NULL, - UI_FB_SIZE + UI_DRAW_BUF_PALETTE, + lv_display_set_buffers(disp, g_ui_draw_buf, NULL, UI_DRAW_BUF_SIZE, LV_DISPLAY_RENDER_MODE_FULL); lv_display_set_flush_cb(disp, ui_flush_cb); diff --git a/Drivers/BSP/UI/ui_port.h b/Drivers/BSP/UI/ui_port.h index 786737ae..64fff365 100644 --- a/Drivers/BSP/UI/ui_port.h +++ b/Drivers/BSP/UI/ui_port.h @@ -22,6 +22,25 @@ extern "C" { #define UI_SCREEN_H 160 #define UI_FB_SIZE ((UI_SCREEN_W * UI_SCREEN_H) / 8) +/* + * LVGL 索引色(I1)绘制缓冲布局 = [palette][pixel data](2026-09-21 台架实证; + * 改本端口或升级 LVGL 版本前必读): + * - lv_draw_buf_create() : 尺寸 = stride*h + LV_COLOR_INDEXED_PALETTE_SIZE(cf)*4 + * - lv_draw_buf_goto_xy()/lv_draw.c : 取绘制指针时 data += palette(像素不从缓冲首址开始) + * - lv_refr get_max_row() : 从 data_size 里扣掉 palette 才当可用像素 + * 但 lv_display_set_buffers()/lv_draw_buf_init() 的容量校验**只看 stride*h(不含 palette)**, + * 故"只给 stride*h"会被静默接受;实测两种后果: + * 1) 末 palette 个像素字节写到缓冲之外(金丝雀实测越界 8B,曾打脏紧邻 .bss 的 + * s_frame_box[0] 指针 → 野指针 HardFault); + * 2) flush 回调收到的首地址含 palette,照原样整帧拷贝会让推流画面整体错位 8B。 + * 规则:绘制缓冲按 UI_DRAW_BUF_SIZE 提供、上报 LVGL 的尺寸也用 UI_DRAW_BUF_SIZE; + * flush 取像素必须 color_p + UI_DRAW_BUF_PALETTE。 + * 注:此处用字面量 8(I1 = 2 色 x 4 字节)以免头文件依赖 lvgl.h;ui_port.c 已按 + * LV_COLOR_INDEXED_PALETTE_SIZE(LV_COLOR_FORMAT_I1)*4 核对一致。 + */ +#define UI_DRAW_BUF_PALETTE 8u +#define UI_DRAW_BUF_SIZE (UI_FB_SIZE + UI_DRAW_BUF_PALETTE) + /* 远端按键码(与 DTU-HMI key.h 保持一致) */ #define UI_KEY_UP 0x02 #define UI_KEY_DOWN 0x40