LVGL 之将位图 bin 数据存储在外部 Nor Flash

关键字 :LVGLImageImg

 一、 概述

一般将图片数据存储到外部 Nor Flash 的常用方法包含(但不限于)以下几种(这里讨论的均为 bitmap 位图):

        ① 将图片数据转为 C 数组添加到代码中,在代码的链接文件中分配 RO 数组存储范围为外部 Flash。

             优:该方法操作简单方便,图片数据随代码一起烧录,可直接调用图片数据

             缺:需要对应外部 Flash 的烧录算法,每次下载 MCU 代码时会重复烧录图片数据,特别是图片较多时会导致每次下载代码很慢

        ② 将图片数据转为 .bin 文件并以文件形式存储在外部 Flash 的文件系统中。

             优:图片管理清晰明了,方便增删改查,下载 MCU 代码时,无需重复写入图片数据

             缺:需要添加文件系统,文件数据需先读取到 ram 中转再调用

        ③ 将图片数据转为 .bin 文件,并将 .bin 单独烧录到外部 Flash 中,在 MCU 这边通过访问对应地址的方式调用图片数据

             优:无需外部 Flash 对应下载算法,可直接调用图片数据,下载 MCU 代码时,无需重复烧录图片数据

             缺:通过地址调用图片数据,需要在代码中记下各图片数据起始地址

今天我们讨论的是方案 ③ 的实现步骤,接下来以 NXP LPC5536 + Winbond W25Q64 的 QSPI Flash 为例介绍,LPC5536 有片内 Flash,片外 QSPI Flash 通过 FlexSPI 接口连接至 MCU。

 

二、 将图片转换为 bin 文件


将图片转换为 bin 文件,如果有多个图片,转换完后需要合并为一个 bin 文件。这里可以用 LVGL 官方转换工具,也可以用

 NXP 提供的 GUI Guider 工具;有多张图片时,前者每张图片会生成一个 bin,需要自己找工具(如 JFlash 等)合并为一个 bin 文件,后者会直接生成一个总的 bin 文件。

2.1 方法一:LVGL 官方转换工具


在线工具网址:https://lvgl.io/tools/imageconverter,打开网页后如下图。



图 1. 在线转换工具的使用

如上图,我们选择了三个图片,为了适配屏,输出颜色格式选择了交换红蓝的 RGB565 Swap,各参数选择完后点击 Convert 即可转换,转换完成后会得到 3 个 .bin 文件, 如下图所示。



图 2. 转换完成的 .bin

为了方便烧录 Flash,需要自己找工具合并为一个 bin 文件,这里用的是 JFlash,不过 JFlash 需要一个个加上去合并,有点麻烦,大家也可以自己找工具合并,记得记下每个图片在合并后 .bin 中的起始地址。


2.2
方法二:借助 NXP GUI Guider 工具

工具下载地址:https://www.nxp.com/design/software/development-software/gui-guider:GUI-GUIDER,根据自己的系统选择安装包。



图 3. GUI Guider 安装

安装完了后,创建一个空白的工程,选择“资源管理 -> 图片 -> 导入图片”导入需要转换的图片,如下图。



图 4. GUI Guider 导入图片

接着,勾选需要转换的图片,点击“转换图片”,选择转换格式,开始转换。这里 GUI Guide 目前仅支持 ARGB8565 和 ARGB8888 两种格式(比如我们前面用到的 RGB565 Swap,这里 GUI Guider 暂时还不支持,这种情况只能使用 LVGL 官方工具转换)。



图 5. GUI Guider 转换图片

转换完成后,会得到一个合并后的 .bin 和一个 .c 文件,其中 .c 中记录了每张图片在 .bin 中的起始地址,如下图。



图 6. 转换完成的 .bin 和 .c


图 7. 每张图片的起始地址

 

三、 将图片 bin 烧入外部 Nor Flash


接着需要将合并的 bin 文件烧入到 Flash 中,这里大家各显神通吧,可以用专用的 Flash 烧录器,手边有 JLink 的也可以先用 JLink 顶上,下面简单介绍下 JLink 烧录的步骤,详细可参考这篇:https://www.wpgdadatong.com.cn/blog/detail/45625

硬件上需要将 QSPI Flash 引脚接到 JLink 上,JLink 引脚按下图高亮部分接,记得带上 GND。



图 8. JLink Pinout for SPI

注意,图中的 DI 表示 Flash 的 DI,即 JLink output,Flash input;DO 与之相反。

注意,如果烧录的 Flash 已经焊在板子上并连接了 MCU,则烧录过程需要保证 MCU 的 Reset 脚一直为低。

硬件准备好后,打开 JFlashSPI.exe,一般在 JLink 安装目录可以找到。



图 9. JFlashSPI

点击“Target -> Connect”连接,下方可以看到 Log 显示,如下图。



图 10. Connect

点击“Target -> Program & Verify”烧录,下方可以看到 Log 显示,如下图。如果想确认写入数据是否正确,也可读出来对比。



图 11. Program

 

四、 在代码中调用图片


显示图片的时候,需要给 LVGL 一个 lv_img_dsc_t 类型的结构体,其中除了图片像素数据外,还包含了图片的类型、大小等各种属性信息。



图 12. 图片结构体类型

从上图可以看出,结构体 lv_img_dsc_t 的前 4 bytes 为 header 信息,后面是图片数据的大小和数据首地址指针。

我们也要给每张图片定义一个该结构体给 LVGL 调用,这里的结构体数据有两种方式获得:

① 一种是借用之前将图片转换为 bin 的转换工具(参考前面章节二),这次我们更改输出文件类型为“C 文件”进行转换,转换完后每个图片会有一个对应的 .c 文件,打开翻到最下方,可以找到该图片对应的结构体,可以直接 copy 过来使用,如下图。



图 13. 图片结构体

② 另一种是,从 bin 文件读取,每个图片 bin 的前 4 bytes 即为 header 信息。



图 14. 图片结构体

现在我们就有足够的信息定义图片的结构体了,如下图,还记得前面合成 bin 时记下来的每张图片相对 Flash 开头的起始地址吗,下面也要用来定义图片的数据指针。





图 15. 定义图片结构体

接下来在代码中初始化 Flash,然后正常调用图片就可以了,调用前记得声明一下,如下图。



图 16. 调用图片


图 17. 运行现象

 

五、 记录一个 FlexSPI 配置问题


最初调用图片时,显示会出现下面的现象,图片上会有白色条纹,白色意味着这部分数据为 0x00,若把数据从 Flash 读到 SRAM,再把 SRAM 的数据给 LVGL 显示,又能正常显示。



图 18. 图片出现白色条纹

最后排查了一圈,发现是 FlexSPI 访问 Flash 的配置原因,默认的设置是对读取地址有对齐要求的,按下图修改可取消对齐限制,更改后即可正常显示。



图 19. 修改 FlexSPI 配置

 

六、参考资料


(1)LVGL 官方文档 :https://docs.lvgl.io/master/widgets/core/img.html

(2)《JLink 烧写外部 SPI Flash》:

https://www.wpgdadatong.com.cn/blog/detail/45625

(3)J-Link Manual (UM08001):

https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPackBeta

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论

qcmc

qcmc

4 个月前
你好,请问第二种方法能不能出一篇教程呢? ② 将图片数据转为 .bin 文件并以文件形式存储在外部 Flash 的文件系统中。 优:图片管理清晰明了,方便增删改查,下载 MCU 代码时,无需重复写入图片数据 缺:需要添加文件系统,文件数据需先读取到 ram 中转再调用