2018年9月15日 星期六

STM32H7 SDRAM hardfault

The STM32H7xx SDRAM Brief :

The two default regions of SDRAM banks are not cacheable. Even if the cache is enabled,
the data or instructions do not go through the cache.

To benefit from cache acceleration, the SDRAM banks can be remapped from 0xC000 0000 and 0xD000 0000 to 0x6000 0000 and 0x7000 0000 respectively, which are, by default, cacheable regions. This is done by setting the field BMAP[1:0] bits in the FMC_BCR1 register.  Figure shows the different external memory mappings and their corresponding BMAP[1:0] values.


If the remapping is not suitable for the application, the Cortex®-M7 MPU can be used to
modify the propriety of the default SDRAM memory region to be cacheable.

The hardfault caused by unaligned memory access. STM32H7xx devices have the external SDRAM mapped to the address range 0xC0000000 - 0xCFFFFFFF (max. 256MB) and 0xD0000000 - 0xDFFFFFFF. According to the ARMv7-M Architecture Reference Manual chapter B3.1 (table B3-1), the area 0xC0000000-0xDFFFFFFF (512MB) is specified as Device Memory Type. According to chapter A3.2.1, all accesses to Device Memory Types must be naturally aligned.

Initializes the MPU so that the SDRAM memory area is considered as Normal Memory type instead of Device Memory type. This disables the access alignment restrictions.

    MPU_Region_InitTypeDef MPU_InitStruct;
    HAL_MPU_Disable();

    /* Configure the MPU attributes as WT for SDRAM */
    MPU_Region_InitTypeDef MPU_InitStruct;
    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress = 0xD0000000;
    MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER1;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);

    /* Enable the MPU */
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

Other solutions for the STM32H7xx: Remap the SDRAM to address  0x60000000 - 0x7FFFFFFF or Generate code with the natural alignment.

References:
https://www.st.com/resource/en/application_note/dm00306681.pdf
https://developer.arm.com/docs/ddi0403/e/armv7-m-architecture-reference-manual
http://www.keil.com/support/docs/3777.htm
https://www.st.com/resource/en/application_note/dm00272912.pdf

沒有留言:

張貼留言