У меня проблема с ошибкой моего Cortex-M0, поэтому я пытаюсь отладить его. Я пытаюсь распечатать содержимое регистров ядра ARM, которые были помещены в стек при возникновении сбоя.
Вот мой основной код сборки:
__attribute__((naked)) void HardFaultVector(void) {
asm volatile(
// check LR to see whether the process stack or the main stack was being used at time of exception.
"mov r2, lr\n"
"mov r3, #0x4\n"
"tst r2, r3\n"
"beq _MSP\n"
//process stack was being used.
"_PSP:\n"
"mrs r0, psp\n"
"b _END\n"
//main stack was being used.
"_MSP:\n"
"mrs r0, msp\n"
"b _END\n"
"_END:\n"
"b fault_handler\n"
);
}
Функция fault_handler
напечатает содержимое кадра стека, который был помещен либо в стек процессов, либо в основной стек. Вот мой вопрос, хотя:
Когда я печатаю содержимое кадра стека, который предположительно имеет сохраненные регистры, вот что я вижу:
Stack frame at 0x20000120:
pc = 0xfffffffd; saved pc 0x55555554
called by frame at 0x20000120, caller of frame at 0x20000100
Arglist at unknown address.
Locals at unknown address, Previous frame's sp is 0x20000120
Saved registers:
r0 at 0x20000100, r1 at 0x20000104, r2 at 0x20000108, r3 at 0x2000010c, r12 at 0x20000110, lr at 0x20000114, pc at 0x20000118, xPSR at 0x2000011c
Вы можете видеть сохраненные регистры, это регистры, которые выдвигаются ядром ARM при возникновении серьезного сбоя. Вы также можете увидеть строку pc = 0xfffffffd;
, которая указывает, что это значение LR
EXC_RETURN
. Значение 0xfffffffd
указывает мне, что стек процессов использовался во время серьезной ошибки.
Если я напечатаю значение $psp
, я получу следующее:
gdb $ p/x $psp
$91 = 0x20000328
Если я напечатаю значение $msp
, я получу следующее:
gdb $ p/x $msp
$92 = 0x20000100
Вы можете ясно видеть, что $msp
указывает на вершину стека, где предположительно находятся сохраненные регистры. Не означает ли это, что в главном стеке есть сохраненные регистры, которые ядро ARM поместило в стек?
Если я печатаю содержимое памяти, начиная с адреса $msp
, я получаю следующее:
gdb $ x/8xw 0x20000100
0x20000100 <__process_stack_base__>: 0x55555555 0x55555555 0x55555555 0x55555555
0x20000110 <__process_stack_base__+16>: 0x55555555 0x55555555 0x55555555 0x55555555
Пусто ...
Теперь, если я распечатываю содержимое памяти, начиная с адреса $psp
, я получаю следующее:
gdb $ x/8xw 0x20000328
0x20000328 <__process_stack_base__+552>: 0x20000860 0x00000054 0x00000054 0x20000408
0x20000338 <__process_stack_base__+568>: 0x20000828 0x08001615 0x1ad10800 0x20000000
Это выглядит более точно. Но я думал, что сохраненные регистры должны указывать, где они находятся во флэш-памяти? Так как это имеет смысл?