STM32一个地址未对齐引起的 HardFault 异常

news2024/7/6 20:16:33

1. 概述

客户在使用 STM32G070 的时候,KEIL MDK 为编译工具,当编译优化选项设置为Level0 的时候,程序会出现 Hard Fault 异常,而当编译优化选项设置为 Level1 的时候,则程序运行正常。表面上看,这似乎是 KEIL MDK 的问题,通过分析,导致这个问题的本质原因是内存地址没有对齐引起的,下面章节将详细分析该问题的来龙去脉以及解决方法。

2. 问题描述与分析

根据客户的反馈,引起问题的代码很简单,客户定义了几个全局数组,在主程序中访问这几个数组就会出现 Hard Fault 异常,参考代码如下。

图1.导致异常的代码片段
在这里插入图片描述

把客户提供的代码片段移植到 NUCLEO-G070RB 开发板上,问题很容易就复现了,代码本身功能简单,写法上也没有错误,所以从代码片段本身上看,无法确定问题出在哪里,通过 KEIL 调试器,在汇编窗口单步调试下,最终发现导致 HardFault 异常的语句为下图所示语句。

图2.导致 Hard Fault 异常的语句
在这里插入图片描述

根据单步调试得知出现问题的语句为 LDR 指令,参考 Cortex M0 编程手册 PM0223 得知 LDR 指令的作用是从内存地址中加载一个 WORD 数据到目的寄存器 Rt 中,其中内存地址根据 Rn 或者 SP 寄存器的值以及立即数 imm 得到。

图3.LDR 指令描述
在这里插入图片描述
根据指令的描述,使用 LDR 指令的时候,通过 Rn 和 imm 计算得到的内存地址必须是读取字节数的倍数,LDR 每次读取一个 WORD,所以使用 LDR 指令时,内存地址必须 4字节对齐。如果地址没有对齐,则会导致 HardFault 异常。

结合 LDR 指令的描述,在调试状态下,通过查看寄存器值,图 2 出错语句中根据 Rn和 imm 计算得到的内存地址为 R0=0x2000000B,imm=4 所以内存地址为 0x2000000F,很显然这个地址不是 4 字节对齐的。

图4.内存地址不对齐
在这里插入图片描述
而当我们改变编译优化选项为 Level1 时,得到的内存地址为R0=0x20000000,imm=0x04 显然这个地址是按照 4 字节对齐的,所以这种情况下是不会出现 HardFault 异常的,印证了客户的问题现象。

图5.内存地址对齐
在这里插入图片描述

3. 问题解决

通过上一节的分析,明确了导致该问题的本质原因是内存地址没有对齐,这个内存地址实际上是代码中定义的全局变量 g_curPlaySound_app 指向的地址,也就是全局数组变量 SoundFile 的地址,在编译器不同的优化选项下,分配给 SoundFile 变量的地址是不一样的,在本案例中,编译优化选项 Level0 条件下,SoundFile 分配的地址没有按照WORD 对齐,而在优化选项 Level1 条件下,SoundFile 分配的地址是 WORD 对齐,所以在两种优化选项下,出现了不一样的运行结果。所以要保证程序不出错,当通过指针访问变量的时候,要确保指针指向的地址是 4 字节对齐的,在 Keil 环境下,可以通过__attribute__((aligned (4))) 关键字实现,如下图所示,通过该关键字,对齐了地址,也就不会出现 HardFault 异常了。

图6.确保地址对齐
在这里插入图片描述

4. 总结

地址未对齐是嵌入式系统中容易忽视的一个细节,忽视这点往往会导致一些奇怪的问题,所以在开发过程中,注意这些细节还是很有必要的。

参考文献

在这里插入图片描述
文档中所用到的工具及版本
Keil MDK V5.29


本文档参考ST官方的《【应用笔记】LAT1185+一个地址未对齐引起的+HardFault+异常》文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1578205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法打卡day38|动态规划篇06| 完全背包理论基础|Leetcode 518.零钱兑换II、377. 组合总和 Ⅳ

目录 完全背包理论基础 完全背包问题描述 完全背包解法 算法题 Leetcode 518.零钱兑换II 个人思路 解法 动态规划 Leetcode 377. 组合总和 Ⅳ 个人思路 解法 动态规划 完全背包理论基础 完全背包问题描述 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是…

基于SSE长连接的智能客服问答系统技术方案及完整项目源码

文章目录 一、项目背景二、项目演示三、项目介绍B系统主要功能1. 注册登录重置密码2. 权限管理3. 项目管理4.客服管理 C系统主要功能1. 问答组件2. 主题色定制3. 类微信时间显示控件及智能tip提示4. 无障碍阅读4. 丰富的输入框组件5. 人工客服6. 聊天记录分表记录与查询 四、项…

【拓扑的基】示例及详解

集合X的某拓扑的一个基是X的子集的一个族(其成员称为基元素),满足条件: 1. 2. 由基生成拓扑 由生成的拓扑(满足以上两个条件) 等价描述: 由所有可表示为的某些成员的井的那些集合组成 例1: 证明:由生成的族确实是拓扑…

零代码与低代码开发平台

1、什么是低代码开发平台?什么是零代码开发平台? 零代码开发平台: 指的是不需要写代码就能够快速开发出业务应用/系统的平台。我们在工作中使用的业务应用,主要提供数据收集、数据处理、数据流转和展示等功能。零代码开发平台能够…

2005-2023年各省国内生产总值指数分季度数据

2005-2023年各省国内生产总值指数分季度数据 1、时间:2005-2023年 2、来源:国家统计局、各省统计局 3、指标:地区生产总值指数(上年同期100)_累计值(%) 4、范围:31省 5、时间跨度:季度 6、缺失情况:无…

Qt | Q_PROPERTY属性和QVariant 类

一、属性基础 1、属性与数据成员相似,但是属性可使用 Qt 元对象系统的功能。他们的主要差别在于存取方式不相同,比如属性值通常使用读取函数(即函数名通常以 get 开始的函数)和设置函数(即函数名通常以 set 开始的函数)来存取其值,除此种方法外,Qt 还有其他方式存取属性值…

比亚迪,学历大于一切

比亚迪 今天逛学生聚集地(牛客网)的时候,看到一篇前几天的帖子。 标题为「比亚迪,学历大于一切」。 这位发帖的同学指出,他曾在比亚迪工作,当时入职时级别为 G3/F1,目测自己工作三年也不一定能升…

【频繁模式挖掘】FP-Tree算法(附Python实现)

一、实验内容简介 该实验主要使用频繁模式和关联规则进行数据挖掘,在已经使用过Apriori算法挖掘频繁模式后,这次使用FP-tree算法来编写和设计程序,依然使用不同规模的数据集来检验效果,最后分析和探讨实验结果,看其是…

HarmonyOS 应用开发-使用colorPicker实现背景跟随主题颜色转换

介绍 本示例介绍使用image库以及effectKit库中的colorPicker对目标图片进行取色,将获取的颜色作为背景渐变色,通过swiper组件对图片进行轮播, 效果图预览 使用说明 直接进入页面,对图片进行左右滑动,或者等待几秒&a…

2014最新AI智能创作系统ChatGPT网站源码+Midjourney绘画网站源码+搭建部署教程文档,支持最近火爆的Suno-v3-AI音乐生成大模型

一、文章前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧。已支持…

鼠标经过切换项,切换显示对应的内容(js)

一、功能描述 有多个切换项,鼠标移到每一项时对应切换下面对应的内容,一项对应一项内容,并且切换选中的样式。 二、实现效果 以这个例子为例。 三、实现思路 1.获取所有切换项。 2.获取所有切换项内容。 3.定义好“move”样式&#xff0…

链表之双向链表的实现

铁汁们大家好,我们上一篇博客学习了单链表,这节课让我们继续往深学习,学习一下双线链表,话不多说,我们开始吧! 目录 1.双向链表 2.顺序表和链表的优缺点 3.双向链表的实现 1.双向链表 1.我们要实现的双线…

IDEA中修改git的作者、邮箱名称

目录 一、查看当前git信息 1、查看git作者名称 如下图: 2、查看git邮箱信息 二、修改git信息 1、修改git作者名称 如下图: 2、修改git邮箱名称 一、查看当前git信息 1、查看git作者名称 在git控制台 或者 Terminal 输入 git config user.name …

蓝桥杯物联网竞赛_STM32L071_16_EEPROM

仍然是没有考过的知识点 朴素的讲就是板子中一块不会因为断电重启而导致数值初始化的一片地址 要注意的是有时候容易把板子什么写错导致板子什么地址写坏了导致程序无法烧录,这个时候记得一直按flash键烧录,烧录时会报错,点击确定&#xff0…

飞鸟写作可靠吗 #职场发展#经验分享#经验分享

飞鸟写作是一个非常便捷的论文写作工具,不仅可以帮助用户高效地完成论文写作,还可以提供查重降重的功能,帮助用户确保论文的原创性。那么,飞鸟写作到底可靠吗?答案是肯定的。 首先,飞鸟写作提供的查重降重功…

经典算法-分治法由散点得出凸包-python实现

import copy import random import matplotlib import mathdef distance_p2l(point, line_point1, line_point2):if (line_point2[0] - line_point1[0]) 0:return abs(point[0] - line_point2[0])# 计算直线的斜率m (line_point2[1] - line_point1[1]) / (line_point2[0] - l…

电脑出现mfc140u.dll丢失怎么办?教你7个方法解决此问题

mfc140u.dll 是一个动态链接库 (Dynamic Link Library, DLL) 文件,它是 Microsoft Windows 操作系统环境下用于支持应用程序运行的重要组成部分。具体来说,mfc140u.dll 是 Microsoft Foundation Class (MFC) 库 14.0 版本的 Unicode 版本动态链接库文件。…

分享一下项目中遇到的排序失效问题

今天把原来的一个查询接口的业务代码进行了优化&#xff0c;减少了十几行冗余的代码。 原来的代码 ChongwuServiceImpl.java /*** author heyunlin* version 1.0*/ Slf4j Service public class ChongwuServiceImpl implements ChongwuService {Overridepublic JsonResult<…

TensorFlow-gpu安装教程(Linux系统)

一、TensorFlow-gpu环境的安装 使用这个代码安装的前提是你的深度学习已经环境存在 &#xff08;例如&#xff1a;conda、pytorch、cuda、cudnn等环境&#xff09; TensorFlow版本对应GPU版本&#xff0c;自己选择版本&#xff0c;也可以忽略版本直接安装TensorFlow-gpu cond…

百度松果菁英班——机器学习实践五:明星图片爬取

飞桨AI Studio星河社区-人工智能学习与实训社区 &#x1f96a;图片爬取 import requests import os import urllib ​ class GetImage():def __init__(self,keyword大雁,paginator1):# self.url: 链接头self.url http://image.baidu.com/search/acjson?self.headers {User…