打印
[应用相关]

TouchGFX从文件系统中读取图片

[复制链接]
742|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
实验平台:
硬件: RT-Thread官方ART-PI H750开发版,正点原子4.3寸RGBLCD屏(800*480)
软件: TouchGFXDesigner v4.15和 STM32CubeMX V6.0.1,开发环境 MDK 或 RT-Thread Studio 1.1.5,env工具


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

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


使用特权

评论回复
沙发
heimaojingzhang|  楼主 | 2021-7-3 10:55 | 只看该作者
从文件系统中读取图片资源
1.修改链接脚本
默认情况下,TouchGFX中的所有位图都放入ExtFlashSection中,标准的链接描述文件(此处为GCC)将其他只读数据一起放入闪存。在此示例中,我们将图像数据放入地址为0x9A000000的ExtFlashSection中。您可以选择任何其他未使用的地址(不属于代码或数据地址空间的一部分)。
首先,除了正常的内部闪存和RAM区域外,我们还定义了一个新的存储区域(地址为0x9A000000的USB闪存):

然后,指示链接器将ExtFlashSection放入USB区域:



使用特权

评论回复
板凳
heimaojingzhang|  楼主 | 2021-7-3 10:55 | 只看该作者
链接后,我们可以通过检查映射文件(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文件中获取数据。


使用特权

评论回复
地板
heimaojingzhang|  楼主 | 2021-7-3 10:56 | 只看该作者
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);
    }
}


使用特权

评论回复
5
heimaojingzhang|  楼主 | 2021-7-3 10:56 | 只看该作者
3.将位图数据从闪存复制到缓存

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


使用特权

评论回复
6
heimaojingzhang|  楼主 | 2021-7-3 10:56 | 只看该作者
4.通过fileziia将images.bin上传到SD卡或者nor flash
有SD的可以通过读卡器或者fileziia将images.bin复制到卡里,程序默认先从SD卡中寻找images.bin文件。

没有SD卡的,就上传到NOR FLASH里,程序找不到SD后,会从NOR FLASH中寻找images.bin文件。



使用特权

评论回复
7
heimaojingzhang|  楼主 | 2021-7-3 10:57 | 只看该作者
5.demo演示

导入touchgfx的demo。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

4102

帖子

4

粉丝