2024-10-18 05:17 AM - last edited on 2024-10-18 06:26 AM by SofLit
I'm having a hard time figuring out how to configure the MPU of my microcontrollore in order to have this behaviour.
I've a framebuffer in ram that is big 384KB. I've modified my linker in order to have the framebuffer starting at location 0x24022000
The RAM_D1 starts at 0x24000000 and finish at 0x2407FFFF
I like to use the DCache for normal operation but I would like to disable the cache for the region 0x24022000 - 0x2407FC00 in order to avoid graphic glitches due to the DMA and LTDC accesses.
I'm aware of the SCB_CleanDCache_by_Addr and SCB_InvalidateDCache_by_Addr functions but I would like to make this ram not cacheable so I can not use these functions anymore.
I've configured my MPU in this way:
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* */
HAL_MPU_Disable();
/* Configure the first region: 0x24022000 - 0x2403FFFF */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x24020000;
MPU_InitStruct.Size = MPU_REGION_SIZE_128KB;
MPU_InitStruct.SubRegionDisable = 0x03; // Disable the first 2 subregion (16KB each)
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the second region: 0x24040000 - 0x2407FFFF */
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x24040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
MPU_InitStruct.SubRegionDisable = 0x00; // All subregion active
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the third region: 0x24080000 - 0x2407FFFF */
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0x24080000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.SubRegionDisable = 0xFE; // Disable the last 7 sub regions
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Abilita la MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
In this way I see that the framebuffer is still cached because if I don't do an SCB_CleanInvalidateDCache_by_Addr() call after I write in the framebuffer, the display is corrupt.
How can I set the MPU in order to disable the cache only in the region above?
2024-10-18 05:34 AM
REGION2 describes 24080000 to 240FFFFF
2024-10-18 06:24 AM
Hello @sbi ,
First please use </> button to share your code. See tips on posting.
Second,
@sbi wrote:
I've a framebuffer in ram that is big 384KB.
Then you said:
@sbi wrote:
but I would like to disable the cache for the region 0x24022000 - 0x2407FC00 in order to avoid graphic glitches due to the DMA and LTDC accesses.
0x24022000 - 0x2407FC00 is a 375kB region not 384kB. Could you please check?
2024-10-21 01:59 AM
Sorry, you are right. I made a copy & paste of an older version. My actual version is only with the region0 and region1 as follow:
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* */
HAL_MPU_Disable();
/* Configure the first region: 0x24022000 - 0x2403FFFF */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x24020000;
MPU_InitStruct.Size = MPU_REGION_SIZE_128KB;
MPU_InitStruct.SubRegionDisable = 0x03; // Disable the first 2 subregion (16KB each)
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the second region: 0x24040000 - 0x2407FFFF */
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x24040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
MPU_InitStruct.SubRegionDisable = 0x00; // All subregion active
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* MPU enable */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
However, also in this way, I can see some screen corruption if I don't clean and invalidate the cache.
What am I doing wrong?
2024-10-21 02:10 AM
Hello @SofLit
@SofLit wrote:Hello @sbi ,
First please use </> button to share your code. See tips on posting.
Sorry about this.
0x24022000 - 0x2407FC00 is a 375kB region not 384kB. Could you please check?
My framebuffer should be for a resolution of 800x480 @ 8bit color depth.
It should be 384000bytes. So 0x2422000 + 0x5DC00 is 0x2407FC00
I can also make this region from 0x2422000 to 0x2407FFF for my purposes it's not a problem. However, have I made a wrong calculation?