【发布时间】:2020-05-11 05:41:50
【问题描述】:
Freertos 使用下面的代码部分作为故障处理程序,从当前堆栈指针(导致崩溃的任务堆栈)中获取信息。不幸的是,这只适用于异常,并且如果导致函数是堆栈中的最后一个调用。
"tst lr, #4 \n"
"ite eq \n"
"mrseq r0, msp \n"
"mrsne r0, psp \n"
"ldr r1, ADDRESS \n"
"bx r1 \n"
"ADDRESS: .word stackdump_printf \n"
我正在寻找与上述相同的实现理念,但如果导致错误的函数不是最后一个调用者,则能够向我提供堆栈信息,如下例所示
lumos_c_mangling void getRegistersFromStack( uint32_t *pulFaultStackAddress )
{
uint32_t dummy;
/* These are volatile to try and prevent the compiler/linker optimising them
away as the variables never actually get used. If the debugger won't show the
values of the variables, make them global my moving their declaration outside
of this function. */
volatile uint32_t r0;
volatile uint32_t r1;
volatile uint32_t r2;
volatile uint32_t r3;
volatile uint32_t r12;
volatile uint32_t lr; /* Link register. */
volatile uint32_t pc; /* Program counter. */
volatile uint32_t psr;/* Program status register. */
r0 = pulFaultStackAddress[ 0 ];
r1 = pulFaultStackAddress[ 1 ];
r2 = pulFaultStackAddress[ 2 ];
r3 = pulFaultStackAddress[ 3 ];
r12 = pulFaultStackAddress[ 4 ];
lr = pulFaultStackAddress[ 5 ];
pc = pulFaultStackAddress[ 6 ];
psr = pulFaultStackAddress[ 7 ];
/* When the following line is hit, the variables contain the register values. */
for(;;);
}
void Hardfault_Handler()
{
__asm__
(
" tst lr, #4 \n"
" ite eq \n"
" mrseq r0, msp \n"
" mrsne r0, psp \n"
" ldr r1, [r0, #24] \n"
" ldr r2, SP_ADDRESS_CONST \n"
" bx r2 \n"
" SP_ADDRESS_CONST: .word getRegistersFromStack \n"
);
}
void my_assert(int exp) {
if(!exp) {
// here set exception (for debug purposes, i will set here hardfault active (ignore this please in the current discussion)
NVIC_SetPendingIRQ(HardFault_IRQn);
}
}
void main() {
my_assert(0);
}
所以在这里,它会告诉我函数“my_assert()”导致了问题,但这不是真的,它是“my_assert()”的调用者。
问题:
根据链接 (https://www.silabs.com/content/usergenerated/asi/cloud/content/siliconlabs/en/community/mcu/32-bit/knowledge-base/jcr:content/content/primary/blog/debug_a_hardfault-78gc.social.0.10.html),我可以通过“0x1C + sizeof(uint32_t)”更正 SP,这是否正确?
是否有解决方案可以将此调用从 ASM 重构为 C?我真的不熟悉 ASM,并且非常喜欢 C 实现。
【问题讨论】: