ARM: STM32F7: hardfault caused by unaligned memory access


ARM: STM32F7: hardfault caused by unaligned memory access

ARM: STM32F7: 由未對齊的內存訪問引起的hardfault異常

 

Information in this knowledgebase article applies to:

這個知識庫文章中的信息適用於:

MDK-ARM Version 5

 

SYMPTOM

症狀

 

If a STM32F7xx microcontroller is used with an external SDRAM, the Cortex-M7 core may unexpectedly run into the hard fault handler because of an unaligned access. This may happen for example when the frame buffer of a LCD, a RAM filesystem or any other data is located into the SDRAM address range 0xC0000000 - 0xC03FFFFF (max. 4MB). The hardfault is executed although the bit UNALIGN_TRP (bit 3) in the CCR register is not enabled.

如果STM32F7xx微控制器使用了外部SDRAM,Cortex-M7內核可能會由於未對齊的內存訪問而意外的進入hardfault異常。當LCD幀緩沖,RAM文件系統或任何其他數據位於SDRAM地址范圍0xC0000000 - 0xC03FFFFF (最大. 4MB)時可能出現這種情況。盡管CCR寄存器的UNALIGN_TRP位(位3)沒有使能,hardfault異常仍然會被執行。

 

CAUSE

原因

 

In general, RAM accesses on Cortex-M7 based devices do not have to be aligned in any way. The Cortex-M7 core can handle unaligned accesses by hardware. Usually variables should be naturally aligned because these accesses are slightly faster than unaligned accesses.

在一般情況下,基於Cortex-M7的設備以任何方式訪問RAM都不必對齊。Cortex-M7內核可以硬件處理未對齊的訪問。通常變量應該自然對齊的,因為這樣的訪問比未對齊的訪問稍快。

 

STM32F7xx devices have the external SDRAM mapped to the address range 0xC0000000 - 0xC03FFFFF (max. 4MB). According to the ARMv7-M Architecture Reference Manual chapter B3.1 (table B3-1), the area 0xC0000000-0xDFFFFFFF (32MB) is specified as Device Memory Type. According to chapter A3.2.1, all accesses to Device Memory Types must be naturally aligned. If they are not, a hard fault will be executed no matter if the bit UNALIGN_TRP (bit 3) in the CCR register is enabled or not.

STM32F7xx將外部SDRAM映射到地址范圍0xC0000000 - 0xC03FFFFF (最大. 4MB)。根據ARMV7-M架構參考手冊第B3.1章(表格 B3-1),范圍0xC0000000-0xDFFFFFFF(32MB)作為設備內存類型。根據第A3.2.1章,對設備內存類型的訪問必須自然對齊。如果不對齊,hard fault異常將被執行而不管CCR寄存器的UNALIGN_TRP位(位3)是否被使能。

 

RESOLUTION

解決方案

There are several possible solutions for the STM32F7xx:

針對STM32F7xx的幾種解決方案:

 

1. Enable the MPU for this region

1. 使能該范圍的MPU(內存保護單元)

 

This is the solution we recommend and which we are using in our emWin GUI Demo for this microcontroller. This can be achieved by the following code that needs to be called before the SDRAM is accessed.

這是我們推薦的解決方案並且是我們在該微控制器的emWin GUI Demo中使用的。這可以通過在需要被訪問的SDRAM之前調用下面的代碼來實現。

static void MPU_Config (void) {

  MPU_Region_InitTypeDef MPU_InitStruct;

 

  /* Disable the MPU */

  HAL_MPU_Disable();

 

  /* Configure the MPU attributes for SDRAM */

  MPU_InitStruct.Enable = MPU_REGION_ENABLE;

  MPU_InitStruct.BaseAddress = 0xC0000000;

  MPU_InitStruct.Size = MPU_REGION_SIZE_4MB;

  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

  MPU_InitStruct.Number = MPU_REGION_NUMBER0;

  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;

  MPU_InitStruct.SubRegionDisable = 0x00;

  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;

 

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

 

  /* Enable the MPU */

  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

}

 

This code 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從而使SDRAM內存區域被認為是普通內存類型,而不是設備內存類型。這將禁用訪問對齊的限制。

 

2. Remap the SDRAM to a different address

2.重新映射SDRAM到不同的地址

The SDRAM could also be remapped to address 0x60000000 with the following code:

可以通過以下代碼重新映射SDRAM到地址0x60000000:

  RCC->APB2ENR   |= RCC_APB2ENR_SYSCFGEN;

  SYSCFG->MEMRMP |= SYSCFG_MEMRMP_SWP_FMC_1;

The data of the application needs to be linked into this area as well. The disadvantage is that this address area is usually used by external NOR Flash or PSRAM or SRAM. These external memory devices could not be used in this case.

應用的數據必須被鏈接到這個區域為好。該方案的缺點是,該地址區域通常由外部NOR閃存或PSRAM或SRAM使用。這些外部存儲設備在這種情況下將不能使用。

 

3. Generate code with the natural alignment

3. 生成自然對齊的代碼

 

If only your own code accesses the SDRAM area, you can compile your modules with the compiler option --no_unaligned_access to enforce code which uses natural alignment. This code will then be less efficient. We intentionally do not use this compiler directive for our middleware libraries (graphics, files system and TCP/IP stack) to provide best performance and code density.

如果只有你自己的代碼訪問SDRAM區域,你可以編譯你的模塊使用編譯器選項--no_unaligned_access執行其采用自然對齊的代碼。那么這段代碼效率會降低。我們故意不使用該編譯器指令對我們的中間件庫(圖形,文件系統和TCP / IP協議棧),以提供最佳的性能和代碼密度。

 

MORE INFORMATION

Refer to Application Note 209, Using Cortex-M3 and Cortex-M4 Fault Exceptions


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM