一、 概述
一般将图片数据存储到外部 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
评论
qcmc
4 个月前