请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
STMCU小助手 发布时间:2022-8-7 18:34
1. 前言$ s0 G. Z0 b3 ~9 I
客户在做 GUI 项目开发时,会碰到许多显示相关的问题。而屏幕花屏是比较严重的问题,如果产品出现花屏,会严重影响使用体验。正常的 UI 显示,包括画图和将帧缓冲传输到屏幕两个过程。如果画图过程出错,那帧缓冲的内容就不对了,传输到屏幕后显示也不对。而如果画图过程正确,而传输过程出错,虽然帧缓冲的内容是对的,而屏幕接收到的数据出错了,那屏幕显示的内容自然也是错误的。因此在定位显示错乱、花屏等问题时,需要先判断是画图出错还是传输过程出错。本文会介绍一种方法,将帧缓冲内容导出并保存为图片,来判断帧缓冲内容是否正确。8 E: W% f' S* `
由于帧缓冲的内容为全部像素的 RGB 数据,在导出后需要借助其它工具将 RGB 数据转换为图片,方便在 PC 上直接查看。这里可以使用 python 的 pillow 包,将 RGB 转换为JPG 图片。而读取帧缓冲的过程可以借助 python 的 pyswd 包来实现。0 d1 M5 I3 u% F: Q+ y! T3 `' g
2. 环境安装
% c" k/ n' i: m. D, {4 [4 S# [ 本机环境:Windows10 64bit安装 python 3.9.0 (测试过 3.9.6 正常),检查系统环境变量,将 python 添加到 Path中。4 Q# i. e# r6 q+ z5 v/ Q+ R
+ v4 \1 h" m0 K  w
图1. 设置环境变量
3 A. s+ m! z7 ] B`WY2`D4]IFD8_@8~F9BXXD.png & b: m4 t1 {1 G( I* n
; j. F( `; x5 G5 j3 T
6 J( C7 m: `# c: b6 d
2.1. 安装 libusb8 a' O% C0 w" b+ F" Q
解压 libusb-1.0.24.7z,将 VS2019/MS64/dll/libusb-1.0.dll 拷贝到 python 安装目录,与 python.exe 相同目录
3 Y! q0 {( J* l- L2.2. 安装 pyusb
$ y4 g5 C; M# j' y$ O# ?打开 powershell,输入 pip install pyusb-1.2.1-py3-none-any.whl
8 f. B% o1 {* q. t( a; j. l) c2.3. 安装 Pillow
% ^2 W# [0 G) B; w打开 powershell,输入 pip install Pillow-8.3.1-cp39-cp39-win_amd64.whl' E* e" h" g; H
2.4. 安装 pyswd
6 a! V' N' }# W# P* ~/ y解压 pyswd-1.0.0.zip,打开 powershell,进入 pyswd-1.0.0 目录,输入 python setup.py install
$ \( C7 D0 N  b% L! g
; A7 E3 k) k# N* G8 G$ _5 l+ f* K
3. 将帧缓冲保存为图片
: t$ p1 V* W( P3.1. 读取帧缓冲' n$ A$ w; z* f& q
通过 pyswd,可以创建 stlink 对象连接到目标板,用 read_mem 函数来读取目标板内存。
2 F& u" l" s8 l. |3.2. 保存图片$ p3 @& k8 h8 m7 k3 z8 O
从 Pillow 包导入 Image 类,创建图片对象,将 pyswd 读取的 framebuffer 数据填充到 image 对象中并保存实现代码如下,保存为 pyswd_rgb2jpg.py 文件。 0 \% {- _7 ?: P$ H; _
  1. #!/usr/bin/env python# W" [0 a1 u, u& N2 H
  2. # pyswd_rgb2jpg.py fb_addr width hight bpp output_name
    2 c# _. Q# c) L) @+ {/ C
  3. # pyswd_rgb2jpg.py 0x20000090 390 390 3 abc.jpg, a4 ~7 Z6 ]+ h$ \* Q
  4. import swd) w5 R' a" x# K8 Y1 |/ t" a
  5. from PIL import Image$ _- J& b; S4 t: U7 m
  6. #from io import BytesIO
    8 @) m' `9 n) O: G, @$ v
  7. import sys
    . R* H5 d/ F4 R8 L' ^
  8. w = int(sys.argv[2]) #390
    9 B9 @" z( s5 _. K: H4 Z, Q
  9. h = int(sys.argv[3]) #390* t: b# `; F9 ?  [5 C
  10. bpp = int(sys.argv[4])
    * F& @; E4 R0 ~
  11. size = w * h * bpp #RGB565/RGB888
    8 [( k( f. s5 N8 z
  12. fb_addr = int(sys.argv[1], 16) #hex# m/ [% G# f, O6 X, Y- M
  13. dev = swd.Stlink(swd_frequency=1800000, logger=None)! S4 g- f; g& p9 D# J' L
  14. im_data = dev.read_mem(fb_addr, size)" V5 R+ @( q8 j$ ]( n0 a
  15. im_list = list(im_data)- I% z  Q, E8 j! C
  16. ## test rgb565.dta file, RGB offset = 16
    $ f6 c0 K& i7 M0 Q% A2 U
  17. ## pyswd_rgb2jpg.py rgb565.dta 100 100 2 rgb565.jpg
    ! @! A4 s# d7 Y, Y' q
  18. #with open(sys.argv[1], 'rb') as f:
    . h% l4 J  d4 Y2 Y
  19. # f.seek(16). i3 C9 W6 ]" \/ w3 C
  20. # data = f.read()
    % U+ E9 }) }( Z7 D2 A$ u$ t% O& w
  21. # #print(data)6 A* X7 L4 o1 E8 h
  22. #im_list = list(data)' l; y8 Z; c/ f3 j4 i& {3 R
  23. im = Image.new("RGB", (w, h))& {9 X9 \  h! E5 b8 w) Z9 y" q" L
  24. if bpp == 3:+ K- t  j1 [, Q
  25. for j in range(0, h):& i( p3 ?+ R" p' z9 l. `6 P
  26. for i in range(0, w):
    1 W+ g8 n6 j: ~1 m- R( j! h
  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]))% g( b7 n1 j3 ~  c1 q
  28. elif bpp == 2:
    3 {' j9 L% ?' o9 \/ C
  29. for j in range(0, h):
    & i# k9 t7 K4 f2 R1 m) {6 g' y
  30. for i in range(0, w):9 j- q2 P2 g6 Q6 N6 k3 R1 ~
  31. r = im_list[(w*j + i)*bpp + 1] >> 35 j& R5 b' G3 H! a! t, C
  32. g = ((im_list[(w*j + i)*bpp + 1] & 0x07) << 3) | (im_list[(w*j + i)*bpp] >> 5)4 y% h. r2 X+ M# @8 C
  33. b = im_list[(w*j + i)*bpp] & 0x1f
    . u/ N5 b5 Q) m" u
  34. r = round((r * 255) / 31.0)6 j- q- }9 _: y+ p" H
  35. g = round((g * 255) / 63.0)- l6 l; y6 O' Y/ ^3 ]) }
  36. b = round((b * 255) / 31.0)
    7 R: V# J  Q0 N  K+ N5 l; @
  37. im.putpixel((i, j), (r, g, b))
    + A4 ]  c* c1 R& y0 k7 c
  38. #print("%02x %02x %02x" %(r, g, b))* ?7 @. Z$ Q! I
  39. else:
    8 Z/ `9 A8 I- n& d
  40. print("bpp error")( X. f: X$ Q. T6 A
  41. im.save(sys.argv[5])
复制代码
5 E! d5 Q, O; s. }" }6 e! ^
! ?* @" b, v" [2 ^4 f; a, {
4. 测试及小结5 C3 W1 i# `. c0 z
在 L4R9-DK 板上进行了测试
0 W7 @* [! Q3 M8 n3 T4 P, q(1) 无 GFXMMU 时,传给脚本的参数,宽和高为实际 LCD 的宽和高将 GUI 固件烧录到开发板后,屏幕正常显示。在工程 map 文件中,找到 framebuffer 地址。打开 powershell,执行 pyswd_rgb2jpg.py:
4 P  \  `! k/ w' F+ _% w6 R0 t
4 x' o; d/ G# z; s' U9 t  H0 c
3 `0 D, W8 O% k, o; V/ K F`)6UW4Z3V)_YL)S0$P{Y@I.png * i) x; C$ w3 N5 c0 x+ I! K* {3 T

" `* z( ~4 J2 U; j(2)开启 GFXMMU 时,framebuffer 对应为虚拟地址,传给脚本的参数中,图像的宽度要用GFXMMU 像素宽度' n' }& M* t8 t/ t$ U
图4. L4R9-DK 开启 GFXMMU 测试
9 E* H  J  U9 }3 o0 j# O+ i" W, x! F3 P6 L$ k3 R$ y
2 Q3 ^0 t1 Z9 K: M4 {, v+ X
5 i* l& v$ V9 E7 R5 P) e4 u
UEMC]VSX[13FK}J~7GK~3.png 4 W8 d) E  z( D$ D/ b: O
: b+ X. ^1 t& h( o0 f/ G6 M

) `% y$ w0 v1 n4 I4 e完整版请查看:附件

! y. |9 B! t- j+ [3 L- M! a2 M4 j) W$ H7 U  @* e8 j/ C" L

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

下载

450.27 KB, 下载次数: 1

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

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版