cancel
Showing results for 
Search instead for 
Did you mean: 

MPU on STM32H755

sbi
Associate III

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?

4 REPLIES 4

REGION2 describes 24080000 to 240FFFFF

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
SofLit
ST Employee

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?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

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?

sbi
Associate III

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?