全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 控制/MCU >

基于恩智浦i.MX RT芯片内部RAM运行LVGL工程

时间:2025-07-01 09:33

人气:

作者:admin

标签: 芯片  恩智浦  SDRAM  sram  LVGL 

导读:随着越来越多用户选择i.MX RT系列芯片制作产品,产品的需求以及芯片的用法也越来越多。本文将介绍在i.MX RT平台中,如何创建LVGL项目并将其运行在内部SRAM而非SDRAM上。本文档包含4个部...

随着越来越多用户选择i.MX RT系列芯片制作产品,产品的需求以及芯片的用法也越来越多。本文将介绍在i.MX RT平台中,如何创建LVGL项目并将其运行在内部SRAM而非SDRAM上。本文档包含4个部分:通过GUI Guider生成LVGL工程;LVGL工程的FlexRAM内存配置;修改工程配置使得程序运行;使用局部缓冲区节省SRAM空间。本文档以IAR项目为例。

用GUI Guider生成VGL工程

GUI Guider是恩智浦推出的一款图形用户界面开发工具,在往期的加油站文章中,也有关于它的介绍,在此就不多做描述。读者可以参考相关的文档资料进行了解学习。GUI GUIDER

1.创建LVGL工程

打开GUI Guider v1.9.1 GA,创建两个GUI Guider项目:一个LVGL v9项目,使用基于MIMXRT1170-EVKB和Rasberry Pi LCD显示屏的数字仪表盘模板。一个LVGL v8项目,使用基于MIMXRT1050-EVKB和RK043FN66HS LCD显示屏的数字仪表盘模板。以下是LVGL版本选择的屏幕截图。

3a86aadc-5228-11f0-b715-92fbcf53809c.png

2.根据你的设备修改工程配置

对于第一个RT1170-EVKB项目,无需修改GUI Guider中的配置。对于RT1050-EVKB项目,需要使用片内SRAM来保存帧缓冲区。在GUI Guider工具中,点击菜单上的“Project”按钮打开设置页面。窗口中可以看到一些项目设置。将“Frame Buffer Location”修改为SRAM,即可将缓冲区保存到内部RAM中。

3a9af2c6-5228-11f0-b715-92fbcf53809c.png

FlexRAM配置

FlexRAM是一种高度可配置且灵活的RAM存储器阵列。该存储器阵列包含多个存储器组,每个存储器组可独立配置,以便由不同类型的接口访问,例如I-TCM(指令紧密耦合存储器)、D-TCM(数据紧密耦合存储器)或AX(系统)。存储器组可以用作ITCM、DTCM或OCRAM存储器。本文档将简要介绍RT1170和RT10XX系列的FlexRAM静态配置以及运行时配置。更改IOMUX_GPR_GPR17(在RT1170上,也包括IOMUX_GPR_GPR18)寄存器中定义的FLEXRAM_BANK_CFG字段的值。在设置IOMUX_GPR_GPR17/18的值之前,需要将IOMUXC_GPR_GPR16寄存器的FLEXRAM_BANK_CFG_SEL值设置为1,以启用FlexRAM配置。设置FLEXRAM_BANK_CFG值来配置RAM类型:

•00:RAM组n未使用

•01:RAM组n为OCRAM

•10:RAM组n为DTCM

•11:RAM组n为ITCM

1.i.MX RT芯片FlexRAM配置

不同的i.MX RT芯片具有不同的内存容量,因此每个芯片可配置的FlexRAM大小也不同。下表列出了不同i.MX RT芯片的FlexRAM信息。

3aad57f4-5228-11f0-b715-92fbcf53809c.png

对于i.MX RT1170,系统内存映射如下所示。i.MX RT1170 SRAM的默认配置如下表所示:

3abaa0b2-5228-11f0-b715-92fbcf53809c.png

ITCM DTCM OCRAM
256KB 256KB 1.5MB

2.FlexRAM静态配置

芯片通过POR上电后,i.MX RT会从eFuse中检查FlexRAM组的值,以确定FlexRAM的分配。

OCRAM的最小配置为64KB。这是因为ROM代码的执行至少需要64 KB的RAM。OCRAM的最小配置要求可能因设备而异。

本文档不使用静态配置方法,因此这里不再详细介绍静态配置。

3.FlexRAM动态配置

FlexRAM也可以通过在运行时更改IOMUXC_GPR寄存器的值来配置。首先,将IOMUXC_GPR_GPR16寄存器中定义的FLEXRAM_BANK_CFG_SEL位置1。然后,可以通过IOMUXC_GPR_GPR17(在RT1170上,还有IOMUXC_GPR_GPR18)寄存器中FLEXRAM_BANK_CFG的值来配置FlexRAM的大小。运行时配置比静态配置有两个优势:在静态配置中,eFUse只能烧写一次,而FlexRAM配置无法多次调整;eFuse中只有4/6位配置位,不会穷尽所有FlexRAM Bank组合。

3.1确定FlexRAM的分配

首先,通过IOMUXC_GPR17(以及RT1170中的IOMUXC_GPR18)寄存器的FLEXRAM_BANK_CFG位,可以自由指定每个Bank的最终形态(ITCM/DTCM/OCRAM)。以下是FLEXRAM_BANK_CFG(i.MX RT1170芯片)的说明。

FlexRAM bank configuration GPR17 of RT1170

3accd700-5228-11f0-b715-92fbcf53809c.png

FlexRAM bank configuration GPR18 of RT1170

3adc4e74-5228-11f0-b715-92fbcf53809c.png

3.2使能动态配置

分配好FlexRAM Bank后,将IOMUXC_GPR16寄存器中的FLEXRAM_BANK_CFG_SET设置为1,FLEXRAM_BANK_CFG指定的配置就会立即生效。

FlexRAM bank configuration GPR16 of RT1170

3af079e4-5228-11f0-b715-92fbcf53809c.png

在片内RAM中运行LVGL工程

现在基于MIMXRT1170-EVKB创建了LVGL工程(2个全尺寸帧缓冲区),并介绍了配置FlexRAM的方法,下面是使项目在内部RAM而非外部SDRAM上运行的步骤。

1.在startup文件中配置FlexRAM

本工程中,所有内部RAM均配置为OCRAM,D-TCM和 I-TCM的大小均设置为0。此存储设置仅用于演示如何将所有程序都放入内部RAM,速度可能并非最快。打开“startup_MIMXRT1176_cm7.s”,并在“SystemInit”之前添加配置代码。参见以下代码:

Reset_Handler
CPSID I        ;Maskinterrupts
LDR  R0, =0xE000ED08
LDR  R1, =__vector_table
STR  R1, [R0]
LDR  R2, [R1]
MSR  MSP,R2

/*FlexRam Configuration*///OCRAM = 512KB, DTCM = 0KB ,ITCM = 0KB,
ldr  R0,=0x400E4040//gpr16 Enable FLEXRAM_BANK_CFG
ldr  R1,=0x0000AA07
str  R1,[R0]
ldr  R0,=0x400E4044//gpr17 0:15
ldr  R1,=0x00005555
str  R1,[R0]
ldr  R0,=0x400E4048//gpr18 0:15
ldr  R1,=0x00005555
str  R1,[R0]

LDR  R0, =SystemInit
BLX  R0
CPSIE I        ;Unmaskinterrupts
LDR  R0, =__iar_program_start
BX  R0

现在OCRAM大小设置为2MB。保存更改,FlexRAM配置将在项目运行时生效。

2.修改链接文件

GUI Guider生成的基于i.MX RT芯片的LVGL工程默认存储在Nor Flash和SDRAM中。在工程选项中打开Linker File,删除其他data region,只保留1个data region。将整个OCRAM设置为data region。只保留data region配置,删除其他配置。参见以下代码:

/*
define symbol m_interrupts_ram_start = 0x20200000;
define symbol m_interrupts_ram_end = 0x20200000 + __ram_vector_table_offset__;
define symbol m_data_start = m_interrupts_ram_start + __ram_vector_table_size__;
define symbol m_data_end = 0x203FFFFF;
*/
definesymbolm_data_start =0x20240000;
definesymbolm_data_end =0x203EFFFF;
definesymbolm_ncache_start =0x203F0000;
definesymbolm_ncache_end =0x203FFFFF;
…
define exportedsymbol__VECTOR_TABLE = m_interrupts_start;
//define exported symbol __VECTOR_RAM = isdefinedsymbol(__ram_vector_table__) ? m_interrupts_ram_start : m_interrupts_start;
define exportedsymbol__VECTOR_RAM = m_interrupts_start;
define exportedsymbol__RAM_VECTOR_TABLE_SIZE =0x0;
define memory memwithsize = 4G;
define region TEXT_region =mem:[fromm_interrupts_start to m_interrupts_end]
|mem:[fromm_text_start to m_text_end];
define region DATA_region =mem:[fromm_data_start to m_data_end-__size_cstack__];
define region CSTACK_region =mem:[fromm_data_end-__size_cstack__+1to m_data_end];
define region NCACHE_region =mem:[fromm_ncache_start to m_ncache_end];
…
3. 减小代码尺寸

在GUI Guider生成的项目中,LVGL内存大小默认设置为2MB。通常项目不需要这么大的内存。因此,此处将LV_MEM_SIZE改为80kB,以节省SRAM。

/*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/

#defineLV_MEM_SIZE (80U * 1024U)

4.编译运行工程

保存更改并构建项目,查看“lvgl_guider_cm7.map”文件。内存占用大小显示在底部。

203'063 bytes of readonlycode memory

7'351'345 bytes of readonlydata memory

1'753'889 bytes of readwrite data memory

将其下载到开发板,工程将成功运行。

局部缓冲区刷新

另一个基于MIMXRT1050-EVKB的LVGL v8项目使用局部缓冲区刷新来节省SRAM空间。将缓冲区位置配置到SRAM中,生成的项目将在内部SRAM而非外部SDRAM上运行。

在“lvgl_support.c”文件中,如果启用宏“FB_USE_SRAM”,则会创建两个不同大小的帧缓冲区:一个全尺寸缓冲区和一个部分尺寸缓冲区。

#ifFB_USE_SRAM
#defineDRAW_BUF_HEIGHT (LCD_HEIGHT / 5)
#defineDEMO_DB_SIZE LCD_WIDTH * DRAW_BUF_HEIGHT * LCD_FB_BYTE_PER_PIXEL
SDK_ALIGN(__attribute__((section("FrameBuffer")))staticuint8_ts_frameBuffer[1][DEMO_FB_SIZE], DEMO_FB_ALIGN);
SDK_ALIGN(__attribute__((section("DrawBuffer")))staticuint8_ts_lvglBuffer[DEMO_DB_SIZE], DEMO_FB_ALIGN);
#else
SDK_ALIGN(staticuint8_ts_frameBuffer[2][DEMO_FB_SIZE], DEMO_FB_ALIGN);
#endif

缓冲区初始化也不一样。

#ifFB_USE_SRAM
lv_disp_draw_buf_init(&disp_buf, s_lvglBuffer,NULL, LCD_WIDTH * DRAW_BUF_HEIGHT);
#else
lv_disp_draw_buf_init(&disp_buf, s_frameBuffer[0], s_frameBuffer[1], LCD_WIDTH * LCD_HEIGHT);
#endif
…
/* Partial refresh */
#ifFB_USE_SRAM
disp_drv.full_refresh =0;
#else
disp_drv.full_refresh =1;
#endif

Flush方式是更新改变的区域。

#ifFB_USE_SRAM
staticvoidDEMO_WaitVsync(lv_disp_drv_t*disp_drv)
{
s_framePending =true;
#ifdefined(SDK_OS_FREE_RTOS)
if(xSemaphoreTake(s_frameSema, portMAX_DELAY) != pdTRUE)
{
PRINTF("Display flush failed
");
assert(0);
}
#else
while(s_framePending)
{
}
#endif
}
staticvoidcopy_area(constlv_area_t*area,lv_color_t*color_p,uint8_t*fb,uint32_tfbStrideBytes)
{
uint32_ty;
uint32_tareaWidth =lv_area_get_width(area);
fb += (area->y1 * fbStrideBytes + area->x1 *sizeof(lv_color_t));
for(y = area->y1; y <= area->y2; y++)
{
lv_memcpy(fb, color_p, areaWidth *sizeof(lv_color_t));
fb += fbStrideBytes;
color_p += areaWidth;
}
}
staticvoidDEMO_FlushDisplay(lv_disp_drv_t*disp_drv,constlv_area_t*area,lv_color_t*color_p)
{
/* Wait VSYNC for each small update. */
DEMO_WaitVsync(disp_drv);
/* Copy data from draw buffer to frame buffer. */
copy_area(area, color_p, (uint8_t*) s_frameBuffer, LCD_WIDTH * LCD_FB_BYTE_PER_PIXEL);
SCB_CleanInvalidateDCache();
lv_disp_flush_ready(disp_drv);
}
#else
staticvoidDEMO_FlushDisplay(lv_disp_drv_t*disp_drv,constlv_area_t*area,lv_color_t*color_p)
{
DCACHE_CleanInvalidateByRange((uint32_t)color_p, DEMO_FB_SIZE);
ELCDIF_SetNextBufferAddr(LCDIF, (uint32_t)color_p);
s_framePending =true;
#ifdefined(SDK_OS_FREE_RTOS)
if(xSemaphoreTake(s_frameSema, portMAX_DELAY) == pdTRUE)
{
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
else
{
PRINTF("Display flush failed
");
assert(0);
}
#else
while(s_framePending)
{
}
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
#endif
}
#endif

通过修改链接器文件,我们可以将“DrawBuffer”和“FrameBuffer”放入SRAM中,这些缓冲区的大小将远小于两个全尺寸缓冲区。因此,LVGL项目可以在内部RAM上运行。

小结

本文介绍了如何使基于i.MX RT芯片的LVGL工程在内部RAM上运行而不是外部SDRAM。一种方法是使用FlexRAM扩展OCRAM的大小,以便获得连续的RAM来存储缓冲区。另一种方法是使用部分缓冲区而不是全尺寸缓冲区,这样可以节省SRAM。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信