1. 前言/ r% y# I0 K$ Y* F, \# E b
客户在做 GUI 项目开发时,会碰到许多显示相关的问题。而屏幕花屏是比较严重的问题,如果产品出现花屏,会严重影响使用体验。正常的 UI 显示,包括画图和将帧缓冲传输到屏幕两个过程。如果画图过程出错,那帧缓冲的内容就不对了,传输到屏幕后显示也不对。而如果画图过程正确,而传输过程出错,虽然帧缓冲的内容是对的,而屏幕接收到的数据出错了,那屏幕显示的内容自然也是错误的。因此在定位显示错乱、花屏等问题时,需要先判断是画图出错还是传输过程出错。本文会介绍一种方法,将帧缓冲内容导出并保存为图片,来判断帧缓冲内容是否正确。% U! E7 e& h, X8 A$ c
由于帧缓冲的内容为全部像素的 RGB 数据,在导出后需要借助其它工具将 RGB 数据转换为图片,方便在 PC 上直接查看。这里可以使用 python 的 pillow 包,将 RGB 转换为JPG 图片。而读取帧缓冲的过程可以借助 python 的 pyswd 包来实现。 本机环境:Windows10 64bit) s; i7 U0 N: ~5 b1 r! ~) E
安装 python 3.9.0 (测试过 3.9.6 正常),检查系统环境变量,将 python 添加到 Path中。
5 n; k! `6 C: V- b1 n) c5 y
2 Z) L& z) |) E图1.设置环境变量 e/ L% W) c1 k
: T8 k( O h6 N2 B
0 T X3 U4 s4 l; u; M9 @8 r
0 ]) T/ `2 L% h
3. 将帧缓冲保存为图片
' d% j, n4 h! z7 ?: v) T6 F0 L, `3.1. 读取帧缓冲& l2 n( r$ [- [' _$ u
通过 pyswd,可以创建 stlink 对象连接到目标板,用 read_mem 函数来读取目标板内存。
% c/ o- N* \) b7 c$ ~ | c. k3.2. 保存图片. `: B f: g# R2 f
从 Pillow 包导入 Image 类,创建图片对象,将 pyswd 读取的 framebuffer 数据填充到 image 对象中并保存实现代码如下,保存为 pyswd_rgb2jpg.py 文件。& h1 \/ F% @6 @
) ~; H8 N, K7 q+ p6 {! ]; P! [& @& Q8 a/ b- X8 q
- #!/usr/bin/env python
4 B7 ~3 {, u8 O, e: W& i5 k6 F& n - # pyswd_rgb2jpg.py fb_addr width hight bpp output_name
_6 F/ y( a1 q4 V$ ]& O: n - # pyswd_rgb2jpg.py 0x20000090 390 390 3 abc.jpg7 F. ]% F) u2 l
- import swd/ x0 x% w9 [& n% R" R4 g4 e( `
- from PIL import Image
2 _8 Y$ n# E: C - #from io import BytesIO
% N2 N4 _$ F) O: Z& \, _1 Z - import sys
4 I: q$ q/ ~- M" k - w = int(sys.argv[2]) #390
+ Y1 \! `% W Z } - h = int(sys.argv[3]) #390* Q. I5 o3 ]/ h% w
- bpp = int(sys.argv[4])* ?) i& f% ` r" N/ K
- size = w * h * bpp #RGB565/RGB8887 b8 E8 a' }6 s
- fb_addr = int(sys.argv[1], 16) #hex
$ w8 H9 @2 _: Y9 ` - dev = swd.Stlink(swd_frequency=1800000, logger=None)+ ^, k4 k5 t8 R% k4 X
- im_data = dev.read_mem(fb_addr, size)
9 G8 i+ b. Q1 \' U - im_list = list(im_data)
( u' J; [2 Z3 y, B9 {8 Y( o2 z$ r - ## test rgb565.dta file, RGB offset = 16
2 n: o A& k8 A; h: c) J - ## pyswd_rgb2jpg.py rgb565.dta 100 100 2 rgb565.jpg( B% |, K8 G1 p0 `) A& F/ R
- #with open(sys.argv[1], 'rb') as f:% [+ n5 |6 f. l! C! l1 e+ ?0 \
- # f.seek(16)* X; ^2 T7 r6 n" m/ f: h$ j
- # data = f.read()
% b% ?* y* ^; c - # #print(data). n+ e6 s7 V& l/ p. q; z2 o9 `
- #im_list = list(data)
0 L, ^, F. }" E' s) A$ `, n5 w% ~8 r - im = Image.new("RGB", (w, h))& O, G: r$ w6 s0 x
- if bpp == 3:
* ~/ x+ O9 B) F - for j in range(0, h):9 D( i5 i8 }! z- b( T4 m+ v
- for i in range(0, w):
( g `. r" t7 U( J4 @ - im.putpixel((i, j), (im_list[(w*j + i)*bpp + 2], im_list[(w*j + i)*bpp + 1], im_list[(w*j + i)*bpp]))$ W. _+ n7 r( J0 Q6 H2 Y8 x
- elif bpp == 2:
: N4 y- k$ [1 v) p4 e0 Z - for j in range(0, h):
. I7 K. {5 Y2 q; J! s4 ^ Y, f - for i in range(0, w):8 g. Q5 y) \1 _+ P; I' f
- r = im_list[(w*j + i)*bpp + 1] >> 3- E- C; I# R6 A/ x/ _
- g = ((im_list[(w*j + i)*bpp + 1] & 0x07) << 3) | (im_list[(w*j + i)*bpp] >> 5)
% N% b3 ?' W3 { - b = im_list[(w*j + i)*bpp] & 0x1f
5 u. U5 m, X0 W - r = round((r * 255) / 31.0) [( o* `7 [! @, x4 U8 E
- g = round((g * 255) / 63.0)
# r6 g7 E4 M! }7 c( l - b = round((b * 255) / 31.0)1 \. ^4 U/ f/ k3 U' x# D9 b9 F+ T
- im.putpixel((i, j), (r, g, b))
+ g# a c$ V3 p$ i - #print("%02x %02x %02x" %(r, g, b))$ V; X1 d) W8 n% B0 t4 V
- else:1 l- v/ b8 w2 e9 C4 i( {
- print("bpp error")# |3 s# o( w- R3 T
- im.save(sys.argv[5])
复制代码 I' b E2 ~! C
完整版请查看:附件1 t& e5 p6 u- [8 y6 C/ y- h2 u: \
3 N7 U+ @& @ m. H# ]+ x$ x/ W- `
将framebuffer保存成图片来检查其内容是否正常_v1.0.pdf
(450.27 KB, 下载次数: 2)
|
学习学习