1. 前言0 s6 @2 w( z# K4 v. {2 p
客户在做 GUI 项目开发时,会碰到许多显示相关的问题。而屏幕花屏是比较严重的问题,如果产品出现花屏,会严重影响使用体验。正常的 UI 显示,包括画图和将帧缓冲传输到屏幕两个过程。如果画图过程出错,那帧缓冲的内容就不对了,传输到屏幕后显示也不对。而如果画图过程正确,而传输过程出错,虽然帧缓冲的内容是对的,而屏幕接收到的数据出错了,那屏幕显示的内容自然也是错误的。因此在定位显示错乱、花屏等问题时,需要先判断是画图出错还是传输过程出错。本文会介绍一种方法,将帧缓冲内容导出并保存为图片,来判断帧缓冲内容是否正确。3 P* s8 C0 X/ U* }8 V
由于帧缓冲的内容为全部像素的 RGB 数据,在导出后需要借助其它工具将 RGB 数据转换为图片,方便在 PC 上直接查看。这里可以使用 python 的 pillow 包,将 RGB 转换为JPG 图片。而读取帧缓冲的过程可以借助 python 的 pyswd 包来实现。 本机环境:Windows10 64bit5 v$ _9 B5 ?! N% h1 @/ |! F# a% }
安装 python 3.9.0 (测试过 3.9.6 正常),检查系统环境变量,将 python 添加到 Path中。2 e8 f% U3 Z* W. F, A$ V
) D( N6 v8 \( m2 v$ ?! R' j" z
图1.设置环境变量5 Y- F2 E4 _9 C
, o2 Z9 J1 ?7 L g) [
; p6 I1 P; a; N: [) {8 a1 C; ` $ X! }" t$ P- V2 k: L+ K6 w/ x, `
3. 将帧缓冲保存为图片' f. c: R3 R0 O* C
3.1. 读取帧缓冲* M8 p$ |: L! d6 e
通过 pyswd,可以创建 stlink 对象连接到目标板,用 read_mem 函数来读取目标板内存。
! ]* R7 k2 S' m# H( v* }3.2. 保存图片
. ~. _# U4 e. F) q& i, c8 a1 i% Z$ a从 Pillow 包导入 Image 类,创建图片对象,将 pyswd 读取的 framebuffer 数据填充到 image 对象中并保存实现代码如下,保存为 pyswd_rgb2jpg.py 文件。3 j, o: F2 M/ O
4 ]. p0 f, |; `1 F1 [. o& f7 i( R0 e. P" x7 P9 [6 |
- #!/usr/bin/env python
) W7 k9 e4 L6 E$ E9 e; y2 p - # pyswd_rgb2jpg.py fb_addr width hight bpp output_name3 b& j0 }& u4 _+ J# [: |0 s
- # pyswd_rgb2jpg.py 0x20000090 390 390 3 abc.jpg( m* Q! I: N$ i2 J# N* O
- import swd
" o. l" m; _4 \9 }" }. ]! Q6 Z7 D$ V - from PIL import Image% g# `! M7 q' f! d9 u5 {; s0 q
- #from io import BytesIO
( e; g5 ~7 V/ N4 O: b) M6 o - import sys: I+ G* k( g. _6 H. }$ u1 p3 {
- w = int(sys.argv[2]) #390
4 {* X6 V9 _. k) q - h = int(sys.argv[3]) #390, c' A! b# [3 K7 J5 x
- bpp = int(sys.argv[4])# H( S @3 x8 n% ~
- size = w * h * bpp #RGB565/RGB888/ ]" Y6 a+ r* m8 K1 l5 q' G& j
- fb_addr = int(sys.argv[1], 16) #hex# B# F& V! f; R5 O7 u
- dev = swd.Stlink(swd_frequency=1800000, logger=None)
5 L* T' F# a! G5 [7 ~! A2 z - im_data = dev.read_mem(fb_addr, size)
/ T5 i, m3 L. G6 _+ t! S - im_list = list(im_data)# ~! h& V9 J% t: G3 ?
- ## test rgb565.dta file, RGB offset = 16) d( r% n. U( X3 b* S
- ## pyswd_rgb2jpg.py rgb565.dta 100 100 2 rgb565.jpg
3 Y# ]3 p7 C1 Z9 ?: x1 a7 X( k - #with open(sys.argv[1], 'rb') as f:
& i9 {5 x2 \+ K - # f.seek(16)
7 m5 v' _( a. r: s - # data = f.read(), J9 e1 C, M8 t: k
- # #print(data)
! t1 M1 T& k* I' R4 c% o0 k" s - #im_list = list(data)1 G7 ]! u' P0 h* H; l
- im = Image.new("RGB", (w, h))2 g/ M' Y1 E+ j! c6 u
- if bpp == 3:
8 H7 F/ e. ?" P/ r$ j, A- C - for j in range(0, h):
" b) Y5 h9 P3 w. \7 m# Q - for i in range(0, w):
8 @$ U$ z# l! } - im.putpixel((i, j), (im_list[(w*j + i)*bpp + 2], im_list[(w*j + i)*bpp + 1], im_list[(w*j + i)*bpp])); o# \# j6 j. m; v0 F0 z; ^
- elif bpp == 2:
, j8 T) S+ W8 Z - for j in range(0, h):
8 x, F+ a( V R! r* J - for i in range(0, w):
# a3 l1 u% g, B; [9 C3 M - r = im_list[(w*j + i)*bpp + 1] >> 3
. y- K+ s; K3 T8 ` - g = ((im_list[(w*j + i)*bpp + 1] & 0x07) << 3) | (im_list[(w*j + i)*bpp] >> 5)
' c' j. a1 ~; `5 g1 C6 b - b = im_list[(w*j + i)*bpp] & 0x1f+ X( H) O9 g6 l$ T# w* U7 G
- r = round((r * 255) / 31.0)
( S- ^" h8 l! F3 T _2 i - g = round((g * 255) / 63.0)+ i6 e. K( d/ a% ]! D2 }
- b = round((b * 255) / 31.0)
: z8 S7 m, n2 u - im.putpixel((i, j), (r, g, b))
' ?6 c/ n, B9 v. V - #print("%02x %02x %02x" %(r, g, b))' H1 ~* U+ D0 b- s% H% [
- else:2 M5 c2 R; v& q6 r
- print("bpp error")' y' A: X9 i3 l- F; k
- im.save(sys.argv[5])
复制代码 ?* H& p9 a1 t+ N
完整版请查看:附件
+ ?- x, ?0 a- D8 X: x- K: P
, n2 S' K& C4 r, V
将framebuffer保存成图片来检查其内容是否正常_v1.0.pdf
(450.27 KB, 下载次数: 2)
|
学习学习