STM32小笔记-内核复位过程(复位序列)和HardFault_Handler问题查找方法

笔记来源-STM32嵌入式开发公众号(分析ARM Cortex-M内核复位过程)

笔记来源-HardFault_Handler问题查找方法 

复位序列

大部分CPU复位后都是从0x0000 0000处取得第一条指令开始运行的,然而在ARM Cortex-M内核中的复位序列不同。

ARM Cortex-M内核中的复位序列过程:

中断向量表默认是在复位向量处,但是中断向量表的位置也可以改变。

在ARM Cortex-M内核中,发送异常后,并不是执行中断向量表对应的代码,而是将对应处的数据存入PC中,然后去此地址处进行取指。也就是,在ARM Cortex-M的中断向量表存放是ISR程序的入口地址。复位相当于发生了一次Reset异常,地址0x0000 0004处存放的正是Reset异常对应的中断处理函数入口地址。

需要注意的是:

0x0000 0000处的MSP初始值最低三位需要是0。因为手册上规定栈任何时候都必须4字节对齐,在调入入口需要2字节对齐,而且SP的最低两位在硬件上就被置为0了。

0x0000 0004处存放的地址最低位必须为1。这与ARM模式和Thumb模式有关。ARM中PC的地址必须是32位对齐,其最低两位也被硬件置0,所以写入PC的数据最低两位并不代表真实的取值地址。ARM中使用最低一位判断这条指令是ARM指令还是Thumb指令(0-ARM、1-Thumb)。在Cortex-M内核中,并不支持ARM模式,若强行切换到ARM模式会引起HardFault。

HardFault_Handler问题查找方法

出现问题的现象:在对Keil对STM32程序调试时意外跑飞,停止调试时停在HardFault_Handler函数的while(1)里,说明STM32出现了硬件错误。

有两种原因:

内存溢出或访问越界。

堆栈溢出。

查找问题方法1:

发生异常后先查看LR寄存器的值,确定当时使用的堆栈是MSP还是PSP。

在Keil里view-Registers Window打开寄存器窗口,查看R14(LR)的值。

若R14(LR) = 0xFFFF FFE9,查看MSP(主堆栈指针)的值;

若R14(LR) = 0xFFFF FFFD,查看PSP(进程堆栈指针)的值。

上图的R14(LR) = 0xFFFF FFFD,则查看PSP(进程堆栈指针)的值。

找到相应堆栈的指针,在内存中查看相应堆栈的内容。

由于异常发生时,内核将R0~R3、R12、R14(LR)、PC、XPRS寄存器依次入栈,其中R14(LR)即为发送异常前PC将要执行的下一条指令地址。

注意:寄存器均是32位、且STM32是小端模式。

当CM3开始相应一个中断/异常时,会有三个动作:

入栈:把xPSR、PC、LR、R12、R3~R0寄存器的值压入栈。

取向量:从中断向量表中找出对应的服务程序入口地址。

选择堆栈指针MSP/PSP,更新堆栈指针SP,更新连接寄存器LR,更新程序计数器PC

响应异常的第一个动作,就是自动保存现场的必要部分:依次把xPSR、PC、LR、R12、R3~R0由硬件自动压入适当的堆栈中;如果当响应异常时,当前的代码正在使用PSP,则压入PSP,否则压入MSP。一旦退出服务例程,就将一直使用主堆栈。

上图中可看出,SP的值为0x2000 19A8,keil里点击view-Memory Windows-Memory1,在Address地址栏输入SP的值,然后查看堆栈里的值,依次是R0~R3、R12,R14(LR)、PC、XPRS。

即地址为0x0800 8263为异常前PC将要执行的下一条指令地址。

找到将要执行下一条指令的位置

keil里点击view-Disassembly Window-右击-Show Disassembly at Address...。在弹出框Show Code at Address的地址框输入地址0x0800 8263进行搜索,然后就可以找到对应的代码了。

查找问题方法2:

在中断函数HardFault_Handler里的while(1)打个断点。

运行到断点时。返回到出错的函数位置。keil里点击View-Call Stack Window,弹出Call Stack + Locals对话框,右击对话框的HardFault_Handler,选择Show Caller Code,就会跳到出错的函数位置。

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值