Skip to main content
Visitor II
October 18, 2024
Question

MPU on STM32H755

  • October 18, 2024
  • 2 replies
  • 990 views

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?

    This topic has been closed for replies.

    2 replies

    Graduate II
    October 18, 2024

    REGION2 describes 24080000 to 240FFFFF

    sbiAuthor
    Visitor II
    October 21, 2024

    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?

    Technical Moderator
    October 18, 2024

    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?

    sbiAuthor
    Visitor II
    October 21, 2024

    Hello @mƎALLEm 


    @mƎALLEm 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?