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 ...
随机推荐
- Nginx的安装配置
1.安装PCRE库 $ cd /usr/local/ $ https://sourceforge.net/projects/pcre/files/pcre/8.36/ $ tar -zxvf pcre ...
- 表单 阻止 技巧 JavaScript js
阻止表单的提交,可以用return false 来进行阻止 长度不低于6,不高于20 if(username.length < 6 || username>20){ alert (&quo ...
- Android动态方式破解apk进阶篇(IDA调试so源码)
一.前言 今天我们继续来看破解apk的相关知识,在前一篇:Eclipse动态调试smali源码破解apk 我们今天主要来看如何使用IDA来调试Android中的native源码,因为现在一些app,为 ...
- Android多媒体--MediaCodec 中文API文档
*由于工作需要,需要利用MediaCodec实现Playback及Transcode等功能,故在学习过程中翻译了Google官方的MediaCodec API文档,由于作者水平限制,文中难免有错误和不 ...
- Discuz!模板解析语法
<!--{eval echo autostart("); }--> PHP中使用template()函数显示已存在模板 在Discuz!程序执行中可以通过 include tem ...
- 【前端】使用readline模块实现Node.js的输入输出
'use strict'; function f(x) { // do something... } var readline = require('readline'); //创建readline接 ...
- bash中使用mysql中的update命令
mysql -uroot -ppasswd -e "update tbadmin set sPassword ='************' where sUserName='admin'& ...
- 公钥私钥和RSA算法
1, RSA算法原理(一) http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html 2, RSA算法原理(二) http: ...
- 在Windows系统下用命令把应用程序添加到系统服务
在Windows系统下用命令把应用程序添加到系统服务,使用SC命令. 加入服务格式如下:sc create ServiceName binPath= 程序路径 start= auto(等号后面的空格是 ...
- NiosII常用函数整理
NiosII常用函数整理 IO操作函数函数原型:IORD(BASE, REGNUM) 输入参数:BASE为寄存器的基地址,REGNUM为寄存器的偏移量函数说明:从基地址为BASE的设备中读取寄存器中偏 ...