教大家如何写出一个现场保存函数以及如何调用该函数

在进行cortexm系列mcu开发时,大家应该都或多或少触发过不可屏蔽中断,例如人见人爱的hardfault。
对于嵌入式工程师来说,能够稳定复现的bug最好解决,再不济挨个打断点也能定位到问题代码位置。
可是异常如果是不定时,无规律的发生在日常的运行中,那打断点的方式无异于守株待兔。
本篇将提供小技巧简述cortexm的异常压栈机制,教大家如何写出一个现场保存函数以及如何调用该函数。
如下图所示,触发中断的时候,cortexm​系列芯片会按照该排列将相关现场数据进行地址偏移压栈,n即此时的sp数值,通过sp中存放的地址,我们可以获取到如图所示的数据。
而要知道触发异常的地址则需要关注lr(link register)的数值,它存放着异常触发点的函数地址。
那么按照压栈的排列,我们可以编写一个结构体以及相关的记录现场函数,如下图所示,结构体的成员完全是按照上图的压栈顺序排列,那下一步就是在哪里调用这个接口来获取到案发时的第一手资料
​要想获得第一手数据,就要去中断函数的执行处,很多厂商的sdk都会在名为xxx_it.c文件里为开发者们写好各个中断的handler,由于s文件中都是弱定义(弱定义即在c文件中有同名的函数,则以c文件中的函数优先编译,则可能造成触发中断时并不会运行s文件处的函数)所以建议可以将其屏蔽或者自己重新编写一个新的函数名。
由下图可见,通过import的形式调用外部现场保存函数,将sp寄存器赋值给r0寄存器是因为r0通常时作为函数的第一个参数进行调用的,可看作是将sp数值作为参数传入stacksave函数,bl的意思是带返回的跳转,即使跳转运行完成stacksave函数后还返回此处。
完成上述函数编写以及调用后,即可进行测试了。本次范例通过spi初始化时传入错误的外设寄存器地址来触发hardfault中断,由下图可看出,此时记录到的lr数值为0x8000e83
​查询后可知,0x8000e83的位置为spi初始化函数中,符合预设的异常触发位置。在非仿真环境下可通过map文件找到大致的函数地址。
综上,我们就知道了如何获取到触发异常中断时的程序运行地址,通过将获取到的信息存入到片上flash指定地址的形式将此时的现场信息进行保存,并通过固件和map一一对应管控。
这样在漫长运行过程中,如果不慎触发异常异常中断,通过对应的map文件即可迅速定位bug所在大致位置​

德州仪器推出全球首款面向运动手表的可定制开发环境eZ430-
韩国半导体产业的发展历程、现状和得失经验
快递新江湖显现,阿里能否通吃天下?
英集芯PD快充芯片IP6510\IP6566\IP6538简介
行云管家再发布新功能 新增云主机比价器
教大家如何写出一个现场保存函数以及如何调用该函数
苹果上架新一代无线耳机AirPods Pro,增加内向式麦克风和力度传感器
防静电接地实时监控系统应用实例
MediaTek全面布局5G产品,携手英特尔将5G体验带入下一代PC市场
川崎机器人维修保养ZD250S码垛机器人维修保养 帕斯科山东机器人科技公司
Humble VR Bundle售出超70000个 达成了100万美元的支付金额
2021年2月Android手机好评排行榜公布
Aurrigo测试无人驾驶微型车 残疾人也能开车了
松下拟最早2021年试生产特斯拉更便宜的新型电池
嵌入式软件的基本测试方法
安克创新300万美元投资半导体公司Navitas持股2.79%
51单片机与PIC单片机和AVR单片机的性能对比分析
OPPO正式在印度宣布旗下子品牌Realme,能否靠着Realme 1在印度击败小米?
Digi-Key庆祝公司发出第五千万个包裹
高容值贴片陶瓷电容 大容量贴片电容