Bootstrap

ESP32+LVGL笔记(6)-把712k的一二级汉字字库放在SPIRAM

在前面的文章《lvgl 笔记(3)-中文字库的制作和使用(windows模拟和esp32)》提到,esp32使用大字库会引起刷新速度变慢(文件浏览界面上下滑动时)的问题。今天尝试把712k大小的字库先读取到SPIRAM,使用时,直接读取SPIRAM,果然速度大为提升,效果还可以接受。
我用的模块是ESP32-S3-WROOM-1(N8R8),内部有8M byte SPIRAM。
本文对应的工程源码:《LVGL_HX8369_HZK》。

1.字库制作

参考《lvgl 笔记(3)-中文字库的制作和使用(windows模拟和esp32)》

2.字库烧录到ESP32-S3的flash

2.1 配置好分区文件

我测试的开发板模块是esp32-S3-WROOM-1(N8R8),模块内部集成了8MB的spi flash。
首先要知道自己开发板的flash大概空间,字库放置的地址和用户程序不要冲突。以我的工程为例,flash空间的规划《partitions_singleapp_large.csv》是:

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     ,        0x6000,
phy_init, data, phy,     ,        0x1000,
factory,  app,  factory, ,        2000K,
storage,0x01,0x40,0x300000,800k

这里给用户程序安排了2M的空间,我的程序实际不超过 600k bytes;所以我就把字库放在3M开始的地方,也就是偏移量为0x30 0000.
具体操作很简单,把汉字库文件《 myFont_16_2.bin 》往0x300000地址烧录就行了。字库的大小是712k bytes,这里分配800k。
工程配置选择《partitions_singleapp_large.csv》文件:
在这里插入图片描述

2.2 汉字库文件烧录到ESP32的flash

在这里插入图片描述

3.将字库从 flash 拷贝到 SPIRAM

3.1 工程配置中有关 SPIRAM 部分

在我的工程中,我也是拿别人的工程,基本没有改动SPIRAM的配置:
在这里插入图片描述

3.2 将汉字库从flash拷贝到SPIRAM的代码

一开始,我想用一个全局数组:

EXT_RAM_ATTR	unsigned char __g_hzk_buf[712*1024];

编译失败,提升下面的 error:

esp32 section `.dram0.bss' will not fit in region `dram0_0_seg'

于是改用动态分配就可以正常运行。先定义一个全局指针,再给这个指针动态分配空间:

uint8_t * __g_p_hz_data;
__g_p_hz_data=(uint8_t *) heap_caps_malloc(712*1024,  MALLOC_CAP_SPIRAM);

下面是《myFont_16_2.c》的关键代码:

//  配置是否copy to SPIRAM    
#define     CONFIG_HZK_IN_SPIRAM        1

//     1. 将字库从  flash copy to SPIRAM 
#if     CONFIG_HZK_IN_SPIRAM
#define     HZK_LEN     (712*1024)

 uint8_t * __g_p_hz_data;
//  上电时,在进入lvgl初始化之前,调用本函数
//  函数名: copyHZK_from_flash_to_SPIRAM()
//	功  能:把字库全部读取到外部SPI RAM
void    copyHZK_from_flash_to_SPIRAM(void)
{
    __g_p_hz_data=(uint8_t *) heap_caps_malloc(HZK_LEN,  MALLOC_CAP_SPIRAM);
    spi_flash_read(0x300000,__g_p_hz_data,HZK_LEN);
}
static uint8_t *__user_font_getdata(int offset, int size){
    return __g_p_hz_data + offset;
}

#else       
//  2.直接在flash 读取
static uint8_t __g_font_buf[256];//如bin文件存在SPI FLASH可使用此buff
static uint8_t *__user_font_getdata(int offset, int size){
    //如字模保存在SPI FLASH, SPIFLASH_Read(__g_font_buf,offset,size);    
    spi_flash_read(0x300000+offset,__g_font_buf,size);
    return __g_font_buf;
}
#endif

测试时,可以通过配置 宏 CONFIG_HZK_IN_SPIRAM 为0(没有把字库放在SPIRAM)或为1(把字库放在SPIRAM),对比两者的速度。

3.3 在进入lvgl之前调用函数 copyHZK_from_flash_to_SPIRAM

源码参考《lvgl_gui.c》。

void    copyHZK_from_flash_to_SPIRAM(void);
void guiTask(void *pvParameter)
{
    //  先copy 汉字库到 spiram
    copyHZK_from_flash_to_SPIRAM();
    xGuiSemaphore = xSemaphoreCreateMutex();
    static lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s)
    ......
}

函数 guiTask是lvgl的主函数,在对lvgl初始化之前调用 copyHZK_from_flash_to_SPIRAM

;