找出哪个指令在Cortex M3

时间:2015-11-18 10:09:52

标签: c assembly embedded cortex-m3 cortex-m

我正在使用Keil uVision调试硬故障陷阱,这在STM32F205 Cortex-M3处理器上是一个精确的数据总线错误。由于冗长的调试和谷歌搜索过程,我发现导致陷阱的汇编指令。现在我正在寻找一种方法来避免下次发生陷阱时这个漫长的过程。

在Keil的应用说明209中,它说:

  

PRECISEERR:精确的数据总线错误:   0 =没有精确的数据总线错误   1 =发生了数据总线错误,并且为异常返回堆叠的PC值指向导致故障的指令。当处理器设置该位时,它将故障地址写入SCB-> BFAR

还有这个:

  

异常保存寄存器R0-R3,R12,PC&的状态。 LR是主堆栈还是进程堆栈(取决于发生异常时正在使用的堆栈)。

我正在解释的最后一句话应该有7个寄存器加上相应的堆栈。当我在内存中查找我的SP地址时,我看到导致错误的地址的地址比堆栈指针地址高10个字。

我的问题是:

  • 导致陷阱的指令地址是否始终比当前堆栈指针高10个字?你能否指出一份文件,我可以在哪里阅读这是怎么以及为什么?

  • 是否还有另一个包含此地址的寄存器?

2 个答案:

答案 0 :(得分:2)

正如您所说,ARM Cortex-M3上的异常(或中断)将自动堆栈一些寄存器,即:

  
      
  • 程序计数器(PC)
  •   
  • 处理器状态寄存器(xPSR)
  •   
  • R0-R3
  •   
  • R12
  •   
  • 链接注册(LR)。
  •   

总共8个寄存器(参考:Cortex™-M3 Technical Reference Manual, Chapter 5.5.1)。

现在,如果使用汇编语言以外的语言编写异常处理程序,编译器可能会堆叠其他寄存器,而您无法确定多少寄存器。

一个简单的解决方案是在真实处理程序之前添加一个小代码,以传递自动堆叠寄存器的地址:

void myRealHandler( void * stack );

void handler(void) {
    asm volatile("mov r0, sp");
    asm volatile("b myRealHandler");
}

寄存器BFAR特定于总线故障。它将包含故障地址,而不是故障指令的地址。例如,如果在地址0x30005632处读取整数时出错,则BFAR将设置为0x30005632

答案 1 :(得分:1)

返回地址的精确堆栈位置取决于中断处理程序需要多少堆栈。如果你看一下HardFault_Handler的反汇编,你应该能够看到堆栈中存储了多少数据/推送了多少寄存器,以及硬件中断机器推送的寄存器(R0-R3,R12,PC, LR& PSR)

我发现this对于如何调试硬故障非常好,尽管它需要一些内联汇编。