隨著越來越多用戶選擇i.MX RT系列芯片制作產(chǎn)品,產(chǎn)品的需求以及芯片的用法也越來越多。本文將介紹在i.MX RT平臺中,如何創(chuàng)建LVGL項目并將其運行在內(nèi)部SRAM而非SDRAM上。本文檔包含4個部分:通過GUI Guider生成LVGL工程;LVGL工程的FlexRAM內(nèi)存配置;修改工程配置使得程序運行;使用局部緩沖區(qū)節(jié)省SRAM空間。本文檔以IAR項目為例。
用GUI Guider生成VGL工程
GUI Guider是恩智浦推出的一款圖形用戶界面開發(fā)工具,在往期的加油站文章中,也有關(guān)于它的介紹,在此就不多做描述。讀者可以參考相關(guān)的文檔資料進行了解學(xué)習(xí)。GUI GUIDER
1.創(chuàng)建LVGL工程
打開GUI Guider v1.9.1 GA,創(chuàng)建兩個GUI Guider項目:一個LVGL v9項目,使用基于MIMXRT1170-EVKB和Rasberry Pi LCD顯示屏的數(shù)字儀表盤模板。一個LVGL v8項目,使用基于MIMXRT1050-EVKB和RK043FN66HS LCD顯示屏的數(shù)字儀表盤模板。以下是LVGL版本選擇的屏幕截圖。
2.根據(jù)你的設(shè)備修改工程配置
對于第一個RT1170-EVKB項目,無需修改GUI Guider中的配置。對于RT1050-EVKB項目,需要使用片內(nèi)SRAM來保存幀緩沖區(qū)。在GUI Guider工具中,點擊菜單上的“Project”按鈕打開設(shè)置頁面。窗口中可以看到一些項目設(shè)置。將“Frame Buffer Location”修改為SRAM,即可將緩沖區(qū)保存到內(nèi)部RAM中。
FlexRAM配置
FlexRAM是一種高度可配置且靈活的RAM存儲器陣列。該存儲器陣列包含多個存儲器組,每個存儲器組可獨立配置,以便由不同類型的接口訪問,例如I-TCM(指令緊密耦合存儲器)、D-TCM(數(shù)據(jù)緊密耦合存儲器)或AX(系統(tǒng))。存儲器組可以用作ITCM、DTCM或OCRAM存儲器。本文檔將簡要介紹RT1170和RT10XX系列的FlexRAM靜態(tài)配置以及運行時配置。更改IOMUX_GPR_GPR17(在RT1170上,也包括IOMUX_GPR_GPR18)寄存器中定義的FLEXRAM_BANK_CFG字段的值。在設(shè)置IOMUX_GPR_GPR17/18的值之前,需要將IOMUXC_GPR_GPR16寄存器的FLEXRAM_BANK_CFG_SEL值設(shè)置為1,以啟用FlexRAM配置。設(shè)置FLEXRAM_BANK_CFG值來配置RAM類型:
?00:RAM組n未使用
?01:RAM組n為OCRAM
?10:RAM組n為DTCM
?11:RAM組n為ITCM
1.i.MX RT芯片F(xiàn)lexRAM配置
不同的i.MX RT芯片具有不同的內(nèi)存容量,因此每個芯片可配置的FlexRAM大小也不同。下表列出了不同i.MX RT芯片的FlexRAM信息。
對于i.MX RT1170,系統(tǒng)內(nèi)存映射如下所示。i.MX RT1170 SRAM的默認配置如下表所示:
ITCM | DTCM | OCRAM |
256KB | 256KB | 1.5MB |
2.FlexRAM靜態(tài)配置
芯片通過POR上電后,i.MX RT會從eFuse中檢查FlexRAM組的值,以確定FlexRAM的分配。
OCRAM的最小配置為64KB。這是因為ROM代碼的執(zhí)行至少需要64 KB的RAM。OCRAM的最小配置要求可能因設(shè)備而異。
本文檔不使用靜態(tài)配置方法,因此這里不再詳細介紹靜態(tài)配置。
3.FlexRAM動態(tài)配置
FlexRAM也可以通過在運行時更改IOMUXC_GPR寄存器的值來配置。首先,將IOMUXC_GPR_GPR16寄存器中定義的FLEXRAM_BANK_CFG_SEL位置1。然后,可以通過IOMUXC_GPR_GPR17(在RT1170上,還有IOMUXC_GPR_GPR18)寄存器中FLEXRAM_BANK_CFG的值來配置FlexRAM的大小。運行時配置比靜態(tài)配置有兩個優(yōu)勢:在靜態(tài)配置中,eFUse只能燒寫一次,而FlexRAM配置無法多次調(diào)整;eFuse中只有4/6位配置位,不會窮盡所有FlexRAM Bank組合。
3.1確定FlexRAM的分配
首先,通過IOMUXC_GPR17(以及RT1170中的IOMUXC_GPR18)寄存器的FLEXRAM_BANK_CFG位,可以自由指定每個Bank的最終形態(tài)(ITCM/DTCM/OCRAM)。以下是FLEXRAM_BANK_CFG(i.MX RT1170芯片)的說明。
FlexRAM bank configuration GPR17 of RT1170
FlexRAM bank configuration GPR18 of RT1170
3.2使能動態(tài)配置
分配好FlexRAM Bank后,將IOMUXC_GPR16寄存器中的FLEXRAM_BANK_CFG_SET設(shè)置為1,F(xiàn)LEXRAM_BANK_CFG指定的配置就會立即生效。
FlexRAM bank configuration GPR16 of RT1170
在片內(nèi)RAM中運行LVGL工程
現(xiàn)在基于MIMXRT1170-EVKB創(chuàng)建了LVGL工程(2個全尺寸幀緩沖區(qū)),并介紹了配置FlexRAM的方法,下面是使項目在內(nèi)部RAM而非外部SDRAM上運行的步驟。
1.在startup文件中配置FlexRAM
本工程中,所有內(nèi)部RAM均配置為OCRAM,D-TCM和 I-TCM的大小均設(shè)置為0。此存儲設(shè)置僅用于演示如何將所有程序都放入內(nèi)部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
現(xiàn)在OCRAM大小設(shè)置為2MB。保存更改,F(xiàn)lexRAM配置將在項目運行時生效。
2.修改鏈接文件
GUI Guider生成的基于i.MX RT芯片的LVGL工程默認存儲在Nor Flash和SDRAM中。在工程選項中打開Linker File,刪除其他data region,只保留1個data region。將整個OCRAM設(shè)置為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內(nèi)存大小默認設(shè)置為2MB。通常項目不需要這么大的內(nèi)存。因此,此處將LV_MEM_SIZE改為80kB,以節(jié)省SRAM。
/*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/
#defineLV_MEM_SIZE (80U * 1024U)
4.編譯運行工程
保存更改并構(gòu)建項目,查看“l(fā)vgl_guider_cm7.map”文件。內(nèi)存占用大小顯示在底部。
203'063 bytes of readonlycode memory
7'351'345 bytes of readonlydata memory
1'753'889 bytes of readwrite data memory
將其下載到開發(fā)板,工程將成功運行。
局部緩沖區(qū)刷新
另一個基于MIMXRT1050-EVKB的LVGL v8項目使用局部緩沖區(qū)刷新來節(jié)省SRAM空間。將緩沖區(qū)位置配置到SRAM中,生成的項目將在內(nèi)部SRAM而非外部SDRAM上運行。
在“l(fā)vgl_support.c”文件中,如果啟用宏“FB_USE_SRAM”,則會創(chuàng)建兩個不同大小的幀緩沖區(qū):一個全尺寸緩沖區(qū)和一個部分尺寸緩沖區(qū)。
#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
緩沖區(qū)初始化也不一樣。
#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方式是更新改變的區(qū)域。
#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中,這些緩沖區(qū)的大小將遠小于兩個全尺寸緩沖區(qū)。因此,LVGL項目可以在內(nèi)部RAM上運行。
小結(jié)
本文介紹了如何使基于i.MX RT芯片的LVGL工程在內(nèi)部RAM上運行而不是外部SDRAM。一種方法是使用FlexRAM擴展OCRAM的大小,以便獲得連續(xù)的RAM來存儲緩沖區(qū)。另一種方法是使用部分緩沖區(qū)而不是全尺寸緩沖區(qū),這樣可以節(jié)省SRAM。
-
芯片
+關(guān)注
關(guān)注
460文章
52529瀏覽量
441303 -
SDRAM
+關(guān)注
關(guān)注
7文章
443瀏覽量
56336 -
恩智浦
+關(guān)注
關(guān)注
14文章
5981瀏覽量
117078 -
sram
+關(guān)注
關(guān)注
6文章
786瀏覽量
116000 -
LVGL
+關(guān)注
關(guān)注
1文章
107瀏覽量
3716
原文標(biāo)題:在i.MX RT片內(nèi)RAM中運行LVGL工程
文章出處:【微信號:NXP_SMART_HARDWARE,微信公眾號:恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
恩智浦i.MX RTxxx系列MCU的特性
i.MX RT1050平臺的相關(guān)資料推薦
恩智浦最新的應(yīng)用處理器 i.MX 95采用專有NPU IP進行片上AI加速
01:i.MX RT的市場應(yīng)用和參考解決方案

恩智浦i.MX RT1170開創(chuàng)GHz MCU時代
恩智浦i.MX RT1170在將該系列帶上了更高的層面
恩智浦發(fā)布新一代i.MX 9系列應(yīng)用處理器
恩智浦推出核跨界MCU的第二款產(chǎn)品i.MX RT1160
痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU特性那些事(1)- 概覽

i.MX RT開發(fā)筆記-08 | i.MX RT1062嵌套中斷向量控制器NVIC(按鍵中斷檢測)

基于i.MX RT單芯片實現(xiàn)的GUI圖形顯示和語音控制解決方案
適用于i.MX RT500和i.MX RT600 MCU的Xtensa音頻框架介紹
恩智浦i.MX RT1170 uSDHC eMMC啟動時間

評論