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

ARM: STM32F7: hardfault caused by unaligned memory access的更多相关文章

  1. (转)DMA(Direct Memory Access)

    DMA(Direct Memory Access) DMA(Direct Memory Access)即直接存储器存取,是一种快速传送数据的机制. 工作原理 DMA是指外部设备不通过CPU而直接与系统 ...

  2. NONUNIFORM MEMORY ACCESS

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION In terms of commercia ...

  3. Catch a Memory Access Violation in C++

    From:  https://stackoverflow.com/questions/16612444/catch-a-memory-access-violation-in-c In C++, is ...

  4. numactl 修改 非统一内存访问架构 NUMA(Non Uniform Memory Access Architecture)模式

    当今数据计算领域的主要应用程序和模型可大致分为三大类: (1)联机事务处理(OLTP). (2)决策支持系统(DSS) (3)企业信息通讯(BusinessCommunications) 上述三类系统 ...

  5. CUDA ---- Memory Access

    Memory Access Patterns 大部分device一开始从global Memory获取数据,而且,大部分GPU应用表现会被带宽限制.因此最大化应用对global Memory带宽的使用 ...

  6. [中英对照]Introduction to Remote Direct Memory Access (RDMA) | RDMA概述

    前言: 什么是RDMA? 简单来说,RDMA就是指不通过操作系统(OS)内核以及TCP/IP协议栈在网络上传输数据,因此延迟(latency)非常低,CPU消耗非常少. 下面给出一篇简单介绍RDMA的 ...

  7. DMA(Direct Memory Access)简介

    什么是DMA(Direct Memory Access) DMA绕过CPU,在内存和外设之间开辟了一条 "隧道" ,直接控制内存与外设之间的操作,并完全由硬件控制. 这样数据传送不 ...

  8. Atitit. 。Jna技术与 解决 java.lang.Error: Invalid memory access

    Atitit. .Jna技术与 解决 java.lang.Error: Invalid memory access 1. 原因与解决1 2. jNA (这个ms sun 的)1 3. Code1 4. ...

  9. DMA(direct memory access)直接内存访问

    DMA(Direct Memory Access),这里的 memory,指的是计算机的内存,自然与外存(storage)相对.这里的关键词在 Direct (直接),与传统的相对低效的,需要通过 C ...

随机推荐

  1. angularjs的三目运算

    前言:前几天写代码的时候遇到一个问题,有一个按钮,有"已关注"和"+关注"两种状态,需要对这两种状态的按钮的背景颜色进行区分,单后点击"已关注&quo ...

  2. TCP重传率高的监控

    TCP重传率是对网络质量的一个体现,简单包装netstat -s的输出可以计算出TCP重传率.现成的脚本如下: #!/bin/bash export PATH='/bin:/sbin:/usr/bin ...

  3. Linux启动过程详述

    http://www.ibm.com/developerworks/cn/linux/kernel/startup/index.html Linux启动第1步:引导内核 Linux启动第2步:内核部分 ...

  4. vs远程发布

    安装IIS管理服务Web Management Service 在IIS中,选择服务器结点,然后在内容里面打开[管理服务],右边操作栏里面停止服务,把[启用远程连接]前面复选框选上.然后选在下面的使用 ...

  5. [翻译]lithium 安装

    安装 要求 web服务器 你需要一个web服务器来运行你的应用,最好是可以运行在你的本地机器上(你所有的开发不是都在这上面做的吗,不是吗?不是吗?).对于PHP而言,框架在很多web服务器上都运行的很 ...

  6. javascript回文和类名的检测方法

    回文**           //"123"变为"123321" //"abc321"变为"abcd321123cba" ...

  7. java 调用axis2 webservice

    import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apach ...

  8. C#委托,事件理解入门 (译稿)

    原文地址:http://www.codeproject.com/Articles/4773/Events-and-Delegates-Simplified 引用翻译地址:http://www.cnbl ...

  9. centos升级glibc(升级到2.14版)

    1.下载源码包 到http://ftp.gnu.org/gnu/glibc/下载glibc-2.14.tar.xz 2.解压 tar glibc-2.14.tar.gz 3.创建build目录 cd ...

  10. oracle的imp导入时覆盖目标数据库

    背景:oracle正式库通过exp命令导出的dmp备份包,现在通过imp命令还原到测试库,测试库上面的表数据全部不要,要用新的. 方法:先删除用户.用户所在表空间,再新建用户和表空间,再imp导入. ...