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
ARM: STM32F7: hardfault caused by unaligned memory access的更多相关文章
- (转)DMA(Direct Memory Access)
DMA(Direct Memory Access) DMA(Direct Memory Access)即直接存储器存取,是一种快速传送数据的机制. 工作原理 DMA是指外部设备不通过CPU而直接与系统 ...
- NONUNIFORM MEMORY ACCESS
COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION In terms of commercia ...
- Catch a Memory Access Violation in C++
From: https://stackoverflow.com/questions/16612444/catch-a-memory-access-violation-in-c In C++, is ...
- numactl 修改 非统一内存访问架构 NUMA(Non Uniform Memory Access Architecture)模式
当今数据计算领域的主要应用程序和模型可大致分为三大类: (1)联机事务处理(OLTP). (2)决策支持系统(DSS) (3)企业信息通讯(BusinessCommunications) 上述三类系统 ...
- CUDA ---- Memory Access
Memory Access Patterns 大部分device一开始从global Memory获取数据,而且,大部分GPU应用表现会被带宽限制.因此最大化应用对global Memory带宽的使用 ...
- [中英对照]Introduction to Remote Direct Memory Access (RDMA) | RDMA概述
前言: 什么是RDMA? 简单来说,RDMA就是指不通过操作系统(OS)内核以及TCP/IP协议栈在网络上传输数据,因此延迟(latency)非常低,CPU消耗非常少. 下面给出一篇简单介绍RDMA的 ...
- DMA(Direct Memory Access)简介
什么是DMA(Direct Memory Access) DMA绕过CPU,在内存和外设之间开辟了一条 "隧道" ,直接控制内存与外设之间的操作,并完全由硬件控制. 这样数据传送不 ...
- 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. ...
- DMA(direct memory access)直接内存访问
DMA(Direct Memory Access),这里的 memory,指的是计算机的内存,自然与外存(storage)相对.这里的关键词在 Direct (直接),与传统的相对低效的,需要通过 C ...
随机推荐
- ADO 读取 ACCESS
#pragma once #include <vector> // 加入ADO支持库, #import "C:\Program Files\Common Files\System ...
- Android BinderService 过程
步骤:建立服务器端服务,暴露接口 1.BinderService /** * @Title BinderService.java * @package cn.boxai.binderservice * ...
- AfxBeginThread中使用updatedata出错
原因:MFC对象不支持多线程操作,不能供多个线程进程使用,所以尽量不要在线程里面更新界面. 解决办法: 1.将工程改为release 2.使用控件来SetWindowText 3.在线程里面发送消息 ...
- vue.js存储--localStorage
//list例子:绑定从localStorage中读取的数据,动态添加list并监听将数据变化存储在localStorage中,绑定点击事件改变样式, 页面 data数据: input_name:'' ...
- PHP的PDO
PDO中包含三个预定一类:PDO.PODStatement和PDOException. 1.PDO类 PDO类代表一个PHP和数据库之间的连接,PDO类所拥有的方法如下: PDO:构造器,构建一个新的 ...
- JFinal - Handler 处理流程
Handler 处理流程 doFilter - Handler 链中每个 handler.handle(...) 容器初始化时访问 web.xml 配置的 JFinalFilter.doFilter. ...
- unreal 自定义 Slate Style Sets
搜集到的最有价值的一篇教学,按照作者的方法尝试中遇到了一些问题.[感谢这位作者!] 网址:https://wiki.unrealengine.com/Slate_Style_Sets_Part_2 在 ...
- javascript的继承小结
继承是OO语言中最为津津乐道的概念,一般有两种继承方式,接口继承和实现继承,接口继承只继承方法签名,实现继承则是集成真正的方法.由于js中函数没有签名,因此ECMAScript中没有接口继承,只有实现 ...
- TLD目标跟踪算法
1. 简介 TLD目标跟踪算法是Tracking-Learning-Detection算法的简称.这个视频跟踪算法框架由英国萨里大学的一个捷克籍博士生Zdenek Kalal提出.TLD将传统的视频跟 ...
- svn patch
生成patch文件: svn diff > patchFile // 整个工程的变动生成patch 或svn diff file > patchFile // 某个文件单独变动的patch ...