一.前言
上节中我们实现了页面的初步的布局,整体效果看起来还不错,但是有两个问题需要进行优化。
1.随着项目的增加,图片资源越来越多,同时为了升级方便,我们需要把位图资源存放在SD卡或者扩展FLASH中
2.界面切换不流畅,影响效果
二.从文件系统中读取图片资源
https://blog.csdn.net/sinat_31039061/article/details/109763842
此部分内容,参考大神博客,不讲述原理,只快速实现,记录操作过程,详细内容查看链接博客。
1.打开链接脚本文件
2.打开链接脚本文件,添加自定义映射地址
如图添加我们自己定义的存储区域(可以选择任意的未用地址)
3.链接器将ExtFlashSection 放入USB区域
打开link.lds文件(需要使用外部编译器进行编辑修改),添加以下代码。
ExtFlashSection :
{
KEEP(*(ExtFlashSection.*))
. = ALIGN(4);
} > USB
注意要添加的代码放在 __bss_start = .; _end = .; 之间。
4.添加objcopy命令从elf文件中提取位图的二进制数据
arm-none-eabi-objcopy -O binary -j ExtFlashSection "${BuildArtifactFileBaseName}.elf" "images.bin"
添加了这部之后,编译就会生成images.bin文件
5.修改代码中BlockCopy函数
位图缓存到RAM中,TouchGFx会调用HAL::BlockCopy来获取数据。
修改路径modbus_demo\libraries\touchgfx_lib\TouchGFX\target下TouchGFXHAL.cpp的bool TouchGFXHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes)函数
添加代码:
#include "dfs_posix.h"
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);
}
}
优先查找sd卡,然后查找flash中有没有文件。
6.将位图数据从闪存复制到缓存
在TouchGFXHAL.cpp中启用和配置位图缓存。首先,需要删除默认创建的位图缓存数据库,然后根据提供的存储区域设置新的缓存。
void TouchGFXHAL::initialize()
{
// Calling parent implementation of initialize().
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
// Please note, HAL::initialize() must be called to initialize the framework.
TouchGFXGeneratedHAL::initialize();
uint16_t* cacheStartAddr =(uint16_t *)rt_malloc(0x1400000);
uint32_t cacheSize = 0x1400000;
Bitmap::removeCache();
Bitmap::setCache(cacheStartAddr,cacheSize,1024);
Bitmap::cacheAll();
}
7.将代码进行编译,将生成的images.bin复制到我们的sd卡目录下。
之前的章节我们实现了usb功能和FTP功能,随自己方便只要将文件拷贝过去就可以了。
我是直接通过usb拷贝过去的。
此时重启看效果就可以了。
三.优化界面切换效果
为了炫酷,在界面切换的时候添加了过度效果。通过测试也确实发现,卡顿现象由这个效果引入。
虽然4.15版本的TouchGfx引入了位图缓冲器,但是效果还是不很理想。切换方向东(上北下南,左西右东)。不过也不难理解
本来直接刷新了,这个还要实现过度,肯定要多处理一些内容。
解决方法:
1.不使用这个效果
2.超频来提高运行速度来解决这个问题
我目前不打算调整频率,对页面文件大的,去掉该效果,占用小的使用过渡效果,提升档次。初步测试还是很不错的。
注意:项目开发中我们要锦上添花,不能画蛇添足,为了提升档次而牺牲了体验,没有必要。