【STM32H750】玩转ART-Pi(七)——TouchGFX从文件系统中读取图片

目录

【STM32H750】玩转ART-Pi(一)——使用STM32CUBMX生成TouchGFX工程
【STM32H750】玩转ART-Pi(二)——制作MDK的外部QSPI-FLASH烧录算法
【STM32H750】玩转ART-Pi(三)——如何在ART-PI上创建TouchGFX工程
【STM32H750】玩转ART-Pi(四)——添加文件系统
【STM32H750】玩转ART-Pi(五)——添加网络功能
【STM32H750】玩转ART-Pi(六)——添加FTP服务器
【STM32H750】玩转ART-Pi(七)——TouchGFX从文件系统中读取图片

实验平台:

硬件: RT-Thread官方ART-PI H750开发版
软件: RT-Thread Studio 1.1.5

联系作者:

加我微信,备注“加群”,加入技术交流群
在这里插入图片描述

实验思路

官方文档介绍:使用非内存映射的闪存存储图像

出于性能原因,TouchGFX要求直接存储在外部闪存中的所有图形数据(通过指针),而无需通过驱动程序层。这意味着TouchGFX无法直接从非内存映射的闪存(如SD卡)进行渲染。为了克服此限制,位图缓存提供了一种在加电期间将部分或全部位图数据缓存在RAM中的机制。因此,当您需要将位图存储在慢速外部存储(例如USB磁盘或SD卡)上时,位图缓存非常有用。

从文件系统中读取图片资源

1.修改链接脚本

默认情况下,TouchGFX中的所有位图都放入ExtFlashSection中,标准的链接描述文件(此处为GCC)将其他只读数据一起放入闪存。在此示例中,我们将图像数据放入地址为0x9A000000的ExtFlashSection中。您可以选择任何其他未使用的地址(不属于代码或数据地址空间的一部分)。
首先,除了正常的内部闪存和RAM区域外,我们还定义了一个新的存储区域(地址为0x9A000000的USB闪存):
在这里插入图片描述
然后,指示链接器将ExtFlashSection放入USB区域:
在这里插入图片描述
链接后,我们可以通过检查映射文件(application.map)来检查位图的地址。这是相关的部分:
在这里插入图片描述
现在,假设我们希望位图数据进入SD卡。我们可以使用简单的objcopy命令从.elf文件中提取位图的二进制数据:

arm-none-eabi-objcopy -O binary -j ExtFlashSection "${BuildArtifactFileBaseName}.elf" "images.bin"

在这里插入图片描述
此时编译代码,会生成一个仅包含图像字节数组的文件(images.bin)。该文件可以复制到USB闪存,SD卡,甚至可以编程到闪存芯片。

接下来,当TouchGFX要求地址0x9A000000以上的数据时,我们从SD卡上的images.bin文件中获取数据。

2.修改BlockCopy功能

当您将位图缓存到RAM时,TouchGFX会调用HAL :: BlockCopy来获取数据。
为了将其链接到SD卡或者nor flash上的数据,我们可以在您的特定HAL类中实现一个新的BlockCopy。在这里,我们假设该类称为TouchGFXHAL(由TouchGFX Generator生成)。
首先在SD卡中寻找images.bin,如果没有挂载SD卡,则在nor flash中寻找:

bool TouchGFXHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes)
{
    
    
    uint32_t dataOffset = (uint32_t)src;
    if (dataOffset >= 0x9A000000 && dataOffset < 0xA0000000)
    {
    
    
            int fd;
            struct statfs buffer;
            if(rt_device_find("sd0") != RT_NULL)
            {
    
    
                if ((dfs_statfs("/sdcard",&buffer) == RT_EOK) | (dfs_mount("sd0", "/sdcard", "elm", 0, 0) == RT_EOK))
                {
    
    
                    fd = open("/sdcard/images.bin", O_RDONLY, 0);
                    if (fd < 0)
                    {
    
    
                        rt_kprintf("open file for read failed\n");
                        return false;
                    }
                    dataOffset =  dataOffset - 0x9A000000;
                    lseek(fd, dataOffset, SEEK_SET);
                    // for copying data from there.
                    read(fd, (uint8_t *)dest, numBytes);
                    close(fd);
                }
                return true;
            }
            else if(dfs_statfs("/flash",&buffer) == RT_EOK)
            {
    
    
                fd = open("/flash/images.bin", O_RDONLY, 0);
                if (fd < 0)
                {
    
    
                    rt_kprintf("open file for read failed\n");
                    return false;
                }
                dataOffset =  dataOffset - 0x9A000000;
                lseek(fd, dataOffset, SEEK_SET);
                // for copying data from there.
                read(fd, (uint8_t *)dest, numBytes);
                close(fd);
                return true;
            }
            else
            {
    
    
                return false;
            }
    }
    else
    {
    
    
        // For all other addresses, just use the default implementation.
        // This is important, as blockCopy is also used for other things in the core framework.
        return HAL::blockCopy(dest, src, numBytes);
    }
}

3.将位图数据从闪存复制到缓存

在TouchGFXHAL.cpp中启用和配置位图缓存。首先,需要删除默认创建的位图缓存数据库,然后根据提供的存储区域设置新的缓存。
在这里插入图片描述

4.通过fileziia将images.bin上传到SD卡或者nor flash

有SD的可以通过读卡器或者fileziia将images.bin复制到卡里,程序默认先从SD卡中寻找images.bin文件。
在这里插入图片描述
没有SD卡的,就上传到NOR FLASH里,程序找不到SD后,会从NOR FLASH中寻找images.bin文件。
在这里插入图片描述

5.demo演示

导入touchgfx的demo。
在这里插入图片描述
演示代码下载:https://download.csdn.net/download/sinat_31039061/13139312
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sinat_31039061/article/details/109763842