你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

将 framebuffer 保存为图片来检查内容

[复制链接]
STMCU小助手 发布时间:2022-8-7 18:34
1. 前言
- ^, S$ H( f7 ^' S4 U' w客户在做 GUI 项目开发时,会碰到许多显示相关的问题。而屏幕花屏是比较严重的问题,如果产品出现花屏,会严重影响使用体验。正常的 UI 显示,包括画图和将帧缓冲传输到屏幕两个过程。如果画图过程出错,那帧缓冲的内容就不对了,传输到屏幕后显示也不对。而如果画图过程正确,而传输过程出错,虽然帧缓冲的内容是对的,而屏幕接收到的数据出错了,那屏幕显示的内容自然也是错误的。因此在定位显示错乱、花屏等问题时,需要先判断是画图出错还是传输过程出错。本文会介绍一种方法,将帧缓冲内容导出并保存为图片,来判断帧缓冲内容是否正确。
# v5 q' a. U% [由于帧缓冲的内容为全部像素的 RGB 数据,在导出后需要借助其它工具将 RGB 数据转换为图片,方便在 PC 上直接查看。这里可以使用 python 的 pillow 包,将 RGB 转换为JPG 图片。而读取帧缓冲的过程可以借助 python 的 pyswd 包来实现。) @' w9 k, C' _# ^
2. 环境安装/ G" D* h' S# p& ~* A" N
本机环境:Windows10 64bit安装 python 3.9.0 (测试过 3.9.6 正常),检查系统环境变量,将 python 添加到 Path中。
- _. w" M  m  y, x* o3 u! @( f, S+ U  h3 G/ z
图1. 设置环境变量 ! ^9 l  s8 n7 R# @# ~% i! _. N
B`WY2`D4]IFD8_@8~F9BXXD.png
" A  N* l% I0 |. m! p; Q6 U! c% G6 h
( L8 C* H4 }6 G* V7 \; k
2.1. 安装 libusb
4 Z5 H# S5 o% K解压 libusb-1.0.24.7z,将 VS2019/MS64/dll/libusb-1.0.dll 拷贝到 python 安装目录,与 python.exe 相同目录
( p5 `4 W6 o% x% ?/ f) o2.2. 安装 pyusb0 D8 L+ ^- K6 m8 G
打开 powershell,输入 pip install pyusb-1.2.1-py3-none-any.whl
( a7 V6 N* h! t9 A0 R2.3. 安装 Pillow* {+ l6 b; F4 M" b
打开 powershell,输入 pip install Pillow-8.3.1-cp39-cp39-win_amd64.whl
5 d; U' x* \% `7 `  Z! v, r8 y- U2.4. 安装 pyswd
3 w( b8 o6 P( J2 T3 f; W  z解压 pyswd-1.0.0.zip,打开 powershell,进入 pyswd-1.0.0 目录,输入 python setup.py install 9 t6 q/ L7 h# l# C; d$ K
3 K4 B  b' V, `  o" I
3. 将帧缓冲保存为图片: |  M6 K! V7 X$ W/ q* a4 N
3.1. 读取帧缓冲
6 }" k* e3 }, f' ]* p3 C通过 pyswd,可以创建 stlink 对象连接到目标板,用 read_mem 函数来读取目标板内存。
1 y; }& k3 x- P3.2. 保存图片
1 K$ B8 g- A1 x- X* C( n* `从 Pillow 包导入 Image 类,创建图片对象,将 pyswd 读取的 framebuffer 数据填充到 image 对象中并保存实现代码如下,保存为 pyswd_rgb2jpg.py 文件。
5 _1 @- r% F) {. \( [, @
  1. #!/usr/bin/env python4 {, B9 k+ p* }1 Q7 Q& U. M/ A* T
  2. # pyswd_rgb2jpg.py fb_addr width hight bpp output_name
    6 l  T2 I+ w- z4 E' r
  3. # pyswd_rgb2jpg.py 0x20000090 390 390 3 abc.jpg7 Z2 ?/ m: ^3 ^% S
  4. import swd
    1 P. ?( m! D! m3 C/ S7 m
  5. from PIL import Image5 _7 {! U2 g: |) D6 M! n
  6. #from io import BytesIO4 E, c7 R6 T4 B( y8 K
  7. import sys" Z# X' L- y2 C! q5 T
  8. w = int(sys.argv[2]) #3904 O3 w8 t- v0 M& r
  9. h = int(sys.argv[3]) #390
    ! u2 K' ^" T) M2 K4 w, z
  10. bpp = int(sys.argv[4])
      Z, I7 b$ v% t9 [% Z% T# J" W
  11. size = w * h * bpp #RGB565/RGB888
      }2 ~& U1 V( \5 t. Q- T% Z
  12. fb_addr = int(sys.argv[1], 16) #hex
    9 N/ B  e" r: {4 a2 `
  13. dev = swd.Stlink(swd_frequency=1800000, logger=None)( H. r& m' z. L# Q0 s: N
  14. im_data = dev.read_mem(fb_addr, size)
    # S- M& ~, ~8 b6 w
  15. im_list = list(im_data)
    $ ?+ v; y" m+ ]% N# U' t' d
  16. ## test rgb565.dta file, RGB offset = 16! m% f- h: `' \; H) ^
  17. ## pyswd_rgb2jpg.py rgb565.dta 100 100 2 rgb565.jpg; n' ?7 f4 s6 ?
  18. #with open(sys.argv[1], 'rb') as f:
    8 S. V% B! r3 f/ t0 X
  19. # f.seek(16). g/ h' e/ V0 C  \% }" K$ P
  20. # data = f.read()
    2 N: `# d8 h8 ]8 e! }
  21. # #print(data)
    , T: h% D& p* d) t9 ^. E' N7 `
  22. #im_list = list(data)1 H/ K) @, F1 W
  23. im = Image.new("RGB", (w, h))& U+ M. X) o0 F( Z0 y
  24. if bpp == 3:7 E# [! K" `( ?
  25. for j in range(0, h):1 U& U/ {6 k1 `& D1 M3 C  v4 `
  26. for i in range(0, w):
    # a! T1 u2 a, ~7 r; n
  27. im.putpixel((i, j), (im_list[(w*j + i)*bpp + 2], im_list[(w*j + i)*bpp + 1], im_list[(w*j + i)*bpp]))+ b1 B" ?0 {  ?9 g/ Q4 a
  28. elif bpp == 2:
    3 Z6 y) A0 H- G+ J9 G
  29. for j in range(0, h):2 x' T# D! R  C3 ]( Z
  30. for i in range(0, w):0 x4 z3 J8 g9 m; x* F1 s( @* U& B
  31. r = im_list[(w*j + i)*bpp + 1] >> 3
    0 D3 l% z9 u# H+ ~  S. Z) x
  32. g = ((im_list[(w*j + i)*bpp + 1] & 0x07) << 3) | (im_list[(w*j + i)*bpp] >> 5): {- l/ c  ]. E+ Y6 U% d. F1 q5 P% \
  33. b = im_list[(w*j + i)*bpp] & 0x1f
    : i/ F) ]( j2 ~/ C2 i; u$ k  Z
  34. r = round((r * 255) / 31.0)
    4 Q( Z5 o/ r( H' e. `: E! }
  35. g = round((g * 255) / 63.0): j# W' ~5 W' Y/ I( U+ Z! Q
  36. b = round((b * 255) / 31.0)* @; ]- t! W$ Z) ~# O
  37. im.putpixel((i, j), (r, g, b))
    ( C/ I9 I  Q/ J, D  r3 g
  38. #print("%02x %02x %02x" %(r, g, b))
    ) I2 V1 S( d; B. t$ L. a+ f
  39. else:2 a" ]; h2 b6 B! `$ [* i$ V# L6 a
  40. print("bpp error")( l$ {7 D. Y+ v5 C
  41. im.save(sys.argv[5])
复制代码
$ Z6 {! A. X& v4 n
7 Z0 ?# Z' l+ K6 j
4. 测试及小结
9 A2 n" K' V# _! i在 L4R9-DK 板上进行了测试* d. @0 H( C+ J" h6 x7 M! x
(1) 无 GFXMMU 时,传给脚本的参数,宽和高为实际 LCD 的宽和高将 GUI 固件烧录到开发板后,屏幕正常显示。在工程 map 文件中,找到 framebuffer 地址。打开 powershell,执行 pyswd_rgb2jpg.py: # _+ p4 G/ l5 t4 ~1 ?
# N0 g& b7 U4 F) }" n2 p

4 A, I" R! p: m1 z/ ~ F`)6UW4Z3V)_YL)S0$P{Y@I.png
, e6 x: j! h6 J) s* Z7 l4 h, {: z1 D/ K7 W1 |
(2)开启 GFXMMU 时,framebuffer 对应为虚拟地址,传给脚本的参数中,图像的宽度要用GFXMMU 像素宽度
( n: E0 m& w$ l; P图4. L4R9-DK 开启 GFXMMU 测试
) |/ X; b2 @6 d( _6 c1 Z* w
' i2 ?( K) `  U
2 {( R3 h3 |5 o/ @- W) A$ r
  B1 }; Q" R6 F7 |* t( U* @
UEMC]VSX[13FK}J~7GK~3.png " T* V  @1 O7 C% b
4 o2 C+ p. X; M( B. y2 {

: O: v9 ^- u- ^; Y/ h- g* }完整版请查看:附件

' ~- w  K7 g+ o8 U  l; m1 D
$ |8 G$ p' q& |$ c

LAT1033 将framebuffer保存成图片来检查其内容是否正常_v1.0.pdf

下载

450.27 KB, 下载次数: 1

赞 收藏 评论0 发布时间:2022-8-7 18:34

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版