我想创建一个调试工具,它将帮助我更好地调试我的应用程序。
我在做裸体工作(没有操作系统)在Atmel的SAM3上使用IAR嵌入式工作台。
我有一个看门狗定时器,它在超时的情况下调用一个特定的IRQ(这将被释放时的软件重置所代替)。
在IRQ处理程序中,我想打印出(UART)堆栈跟踪,即监视程序超时的确切位置。
我在网上查了一下,没有找到任何功能的实现。
有人知道怎么处理这种事情吗?
编辑:好的,我设法从堆栈中获取了返回地址,所以我知道WDT超时发生在哪里。
展开整个堆栈并不像它最初显示的那样简单,因为每个函数将不同数量的局部变量推入堆栈。
我最终得到的代码是这样的(对于其他人来说,他们可能会发现它很有用)
void WDT_IrqHandler( void )
{
uint32_t * WDT_Address;
Wdt *pWdt = WDT ;
volatile uint32_t dummy ;
WDT_Address = (uint32_t *) __get_MSP() + 16 ;
LogFatal ("Watchdog Timer timeout,The Return Address is %#X", *WDT_Address);
/* Clear status bit to acknowledge interrupt */
dummy = pWdt->WDT_SR ;
}
最佳答案
执行死刑应该很直接不是在你的isr中编程。。。
我们从手臂上得知,在皮质-M3上,它推动了xPSR,
堆栈上的ReturnAddress、LR(R14)、R12、R3、R2、R1和R0损坏lr,以便它能够检测到来自中断的返回,然后调用向量表中列出的入口点。如果在asm中实现isr来控制堆栈,可以使用一个简单的循环来禁用中断源(关闭wdt,不管怎样,这需要一些时间),然后进入一个循环来转储堆栈的一部分。
从该转储文件中,您将看到lr/返回地址,即从程序的反汇编过程中中断的函数/指令,然后您可以看到编译器为每个函数在堆栈上放置了什么,在每个阶段将其减去,然后尽可能回到您喜欢的位置,或者尽可能回到您打印堆栈内容的位置。
您还可以在ram中复制堆栈,并在稍后对其进行剖析,而不是在isr中执行这样的操作(复制仍然需要太多时间,但比等待uart要少一些干扰)。
如果您所要寻找的只是被中断的指令的地址,这是最简单的任务,只需从堆栈中读取它,它就会在一个已知的位置,并将其打印出来。
关于c - ARM Cortex M3中的调用堆栈展开,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11325915/