ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
29 марта
932155 Топик полностью
evgeniy1294 (08.07.2019 08:28 - 08:31, просмотров: 253) ответил mrVladimir на Я, можно сказать, начинающий. Не могли бы Вы вкратце пояснить как организовать ловушку на прерывание hardfault.
Для ARM все довольно просто(Cortex-M):  struct ArchRegs { uint32_t r0; //!< Register R0 uint32_t r1; //!< Register R1 uint32_t r2; //!< Register R2 uint32_t r3; //!< Register R3 uint32_t r12; //!< Register R12 uint32_t lr; //!< Link register uint32_t pc; //!< Program counter union { uint32_t all; struct { unsigned IPSR: 8; //!< Interrupt Program Status register (IPSR) unsigned EPSR: 19; //!< Execution Program Status register (EPSR) unsigned APSR: 5; //!< Application Program Status register (APSR) } bit; } psr; //!< Program status register. }; #ifdef __GNUC__ #ifdef __clang__ void isr::HardFault[[clang::optnone]]() #else void isr::HardFault[[gnu::optimize("-O0")]]() #endif #endif { volatile uint32_t out = 0; volatile core::ArchRegs* archregs; // Read fault information shcsr.all = *(uint32_t*)(0xe000'ed24); hfsr.all = *(uint32_t*)(0xe000'ed2c); mfsr.all = *(uint8_t* )(0xe000'ed28); bfsr.all = *(uint8_t* )(0xe000'ed29); ufsr.all = *(uint16_t*)(0xe000'ed2a); mmar = *(uint32_t*)(0xe000'ed34); bfar = *(uint32_t*)(0xe000'ed38); // Halt execution // If registers indicate readable memory, change the variable value to != 0 to continue execution. while(out == 0) { asm("nop"); } out = 0; // Get context pointer archregs = (core::ArchRegs*)(__get_MSP()+8); // Halt execution // To step out of the HardFaultHandler, change the variable value to != 0. while(out == 0) { asm("nop"); } return; } Подробно описано в мануале на ядро. Если выйти из прерывания, то вернешься в точку вылета, если править контекст, то можно попасть в любую точку программы - например, в повторную инициализацию.