Я пытаюсь получить в своем коде адрес возврата обработчика IRQ. Моя цель - сохранить значение ПК непосредственно перед истечением сторожевого таймера и перед сбросом для целей отладки с помощью WDT_IRQHandler (). Я также тестирую этот подход с другими IRQ, чтобы проверить, уловил ли я идею. Но, похоже, нет.
Я прочитал документацию доступно. Я понял, что при возникновении исключения в стек помещается 8 регистров: R0, R1, R2, R3, R12, LR, PC и XPSR.
Я также читал, что стек автоматически выравнивается по двойному слову. На мой взгляд, получить обратный адрес так же просто, как:
- получить адрес sp с помощью __builtin_frame_address (0);
- добавьте к нему смещение сложенного ПК (0x18) и прочтите значение, которое предположительно является значением, которое будет восстановлено на ПК, когда обработчик вернется.
Проверка с подключенным отладчиком, похоже, не так, содержимое по этому адресу памяти не всегда указывает на область флэш-памяти или даже на допустимую область, и в любом случае это никогда не будет значением, которое ПК примет после Инструкция по POP.
Код работает нормально, поэтому я думаю, что у меня проблемы с пониманием того, как он работает.
Если я проверю разборку, в некоторых IRQ к sp перед POPping (?) Добавляется константа.
00001924: 0x000009b0 ...TE_IRQHandler+280 add sp, #36 ; 0x24
00001926: 0x0000f0bd ...TE_IRQHandler+282 pop {r4, r5, r6, r7, pc}
В других IRQ этого не происходит.
Я понимаю, что может случиться так, что в стек будет помещено больше регистров, поэтому как я могу быть уверенным, по какому смещению извлекать ПК?
Если я проверю дамп памяти вокруг SP, когда код все еще находится в обработчике IRQ, я могу определить адрес возврата, но он всегда находится в странном месте с отрицательным смещением по сравнению с SP. Я не понимаю, как получить правильный адрес.