Первый шаг - определить, какое значение имеет ПК в случае неисправности.В вашем «DefaultHardFaultHandle» обратите внимание:
" mrseq r0,msp \n"
" mrsne r0,psp \n"
" mov r1,lr \n"
" ldr ,=HardwareFaultHandler_GetSP \n"
" bx r2"
Первые две инструкции получают правильный SP (указатель стека) на R0.Существует два SP, и один используемый зависит от режима ЦП (режим потока или обработчика), в котором ЦП находится в случае сбоя.Последние две инструкции переходят к новой подпрограмме HardwareFaultHandler_GetSP.Другими словами, если бы вы написали сигнатуру C для HardwareFaultHandler_GetSP, это выглядело бы так:
void HardwareFaultHandler_GetSP (uint32_t * sp);
Вы должны бытьвозможность детализировать с помощью отладчика, чтобы найти неисправный ПК.например, переходя через DefaultHardFaultHandle, как только он получает SP в R0, затем посмотрите на значение R0.Допустим, это 0x20004000.Затем используйте окно памяти, посмотрите на адрес 0x20004000 + 0x18 или 0x20004018.Он содержит ПК, на котором он выходит из строя.
Если вы делаете это часто, используя подпись функции, как я написал, вы можете изменить HardwareFaultHandler_GetSP, чтобы отобразить «SP [6]» для получения ПК.
ПРИМЕЧАНИЕ ПК может быть отключен по одной или двум инструкциям из-за кэширования.Бит IMPRECISERR (бит 2) в регистре состояния BusFault (или BFSR, доступный по байту по адресу 0xE000ED29) контролирует это поведение.Если он включен, вы можете отключить его в отладчике (например, когда вы прерываете main ()) или программно.Это замедляет работу вашей программы, но при сбое показывает точный ПК.