【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从文件系统中读取图片
【STM32H750】玩转ART-Pi(八)——添加动态模块
硬件: 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工具
演示代码下载:https://download.csdn.net/download/sinat_31039061/13139312
注:此教程图片资源比较大,需要把images.bin放在SD卡里
加我微信,备注“加群”,加入技术交流群
官方文档介绍:使用非内存映射的闪存存储图像
出于性能原因,TouchGFX要求直接存储在外部闪存中的所有图形数据(通过指针),而无需通过驱动程序层。这意味着TouchGFX无法直接从非内存映射的闪存(如SD卡)进行渲染。为了克服此限制,位图缓存提供了一种在加电期间将部分或全部位图数据缓存在RAM中的机制。因此,当您需要将位图存储在慢速外部存储(例如USB磁盘或SD卡)上时,位图缓存非常有用。
默认情况下,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文件中获取数据。
当您将位图缓存到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);
}
}
在TouchGFXHAL.cpp中启用和配置位图缓存。首先,需要删除默认创建的位图缓存数据库,然后根据提供的存储区域设置新的缓存。
有SD的可以通过读卡器或者fileziia将images.bin复制到卡里,程序默认先从SD卡中寻找images.bin文件。
没有SD卡的,就上传到NOR FLASH里,程序找不到SD后,会从NOR FLASH中寻找images.bin文件。
关注公众号,后续有精彩内容会第一时间发送给您!