2025-09-18 8:42 PM
Hi,Master
MCU: STM32H743II
LVGL: V9.1
Problem Description:
I have an external SDRAM with a size of 32MB.The program is configured as follows:
void sys_cache_enable(void)
{
SCB_EnableICache();
SCB_EnableDCache();
SCB->CACR |= 1 << 2;
}
void mpu_memory_protection(void)
{
// RAM 512K
mpu_set_protection( 0x24000000,
MPU_REGION_SIZE_512KB,
MPU_REGION_NUMBER1,
MPU_REGION_FULL_ACCESS,
MPU_ACCESS_SHAREABLE,
MPU_ACCESS_CACHEABLE,
MPU_ACCESS_NOT_BUFFERABLE);
// EXSDRAM 32M
mpu_set_protection( 0XC0000000,
MPU_REGION_SIZE_32MB,
MPU_REGION_NUMBER2,
MPU_REGION_FULL_ACCESS,
MPU_ACCESS_SHAREABLE,
MPU_ACCESS_CACHEABLE,
MPU_ACCESS_NOT_BUFFERABLE);
}
The LVGL related frame buffers are stored in the external SDRAM as shown below.
static color_t render_buff1[1024 * 600];
static color_t render_buff2[1024 * 600];
static color_t frame_buff[1024 * 600];
// LVGL uses double buffering for rendering.
lv_display_set_buffers(disp, render_buff1, render_buff2,
sizeof(render_buff1),
LV_DISPLAY_RENDER_MODE_PARTIAL);
The process is as follows:
render dma2d ltdc
lvgl-------->double buff---------->frame_buff---------->lcd
// render: Switch between double buffers for rendering.
// dma2d: DMA2D is executed in the LVGL disp_flush callback. The code snippet is as follows:
SCB_CleanDCache_by_Addr((uint32_t*)disp->buf_1->data, 1024 * 600 * sizeof(color_t));
SCB_CleanDCache_by_Addr((uint32_t*)disp->buf_2->data, 1024 * 600 * sizeof(color_t));
__HAL_RCC_DMA2D_CLK_ENABLE(); /* Enable DMA2D clock */
DMA2D->CR &= ~(DMA2D_CR_START); /* Stop DMA2D first */
DMA2D->CR = DMA2D_M2M; /* Memory-to-memory mode */
DMA2D->FGPFCCR = LTDC_PIXFORMAT; /* Set color format */
DMA2D->FGOR = 0; /* Foreground layer line offset is 0 */
DMA2D->OOR = offline; /* Set line offset */
DMA2D->FGMAR = (uint32_t)color; /* Source address */
DMA2D->OMAR = addr; /* Output memory address */
DMA2D->NLR = (pey - psy + 1) | ((pex - psx + 1) << 16); /* Set the number of lines register */
DMA2D->CR |= DMA2D_CR_START; /* Start DMA2D */
In LVGL's flush_wait_cb, wait for the DMA transfer to complete.
int to = 100000;
while(to-- > 0) {
if ((DMA2D->ISR & (DMA2D_FLAG_TC))) break;
delay_us(1);
}
DMA2D->IFCR |= DMA2D_FLAG_TC;
SCB_CleanDCache_by_Addr((uint32_t*)frame_buff, 1024 * 600 * sizeof(color_t));
The flickering issue described above occurs when these functions are enabled. When I comment out sys_cache_enable(), mpu_memory_protection(), and SCB_CleanDCache_by_Addr(), the problem disappears.
I don't know what is causing this issue. I need help. Thank you very much!
2025-09-19 6:45 AM - edited 2025-09-19 6:52 AM
Hello,
Try first to enable the MPU background configuration to prevent the CM7 speculative access to the unused/uninitialized external memory regions. It's recommended for all products having CM7 as core. See this thread as example.
This is the MPU background config provided in all the examples in CubeH7:
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU as Strongly ordered for not defined regions */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x00;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Other MPU regions config come after */
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
You need to set that configuration as the first region in your MPU config.
It could be not the solution for your issue but this MPU configuration is mandatory.
Becarefull, about this value in the struct as you are not using this value in your implementation:
MPU_InitStruct.SubRegionDisable = 0x87;
2025-09-24 6:14 PM
Okay, thank you very much for your guidance. I will give it a try.