-
Notifications
You must be signed in to change notification settings - Fork 2
Description
A really nice feature would be the ability to actually locate what code caused a fault not just that one occurred, it was actually easier to achieve than i thought
First we have to get the pc at the point of the fault
Here is some working code:
static const char * const hex = "0123456789ABCDEF";
static void _fault_dumpInt(uint32_t num) {
while (!(USART1->SR & USART_SR_TXE));
USART1->DR = '0';
while (!(USART1->SR & USART_SR_TXE));
USART1->DR = 'x';
unsigned char i = 32;
while (i) {
i -= 4;
while (!(USART1->SR & USART_SR_TXE));
USART1->DR = hex[(num >> i) % 16];
}
while (!(USART1->SR & USART_SR_TXE));
USART1->DR = '\r';
while (!(USART1->SR & USART_SR_TXE));
USART1->DR = '\n';
}
// this function is basically the default error handler but prints out the instruction pointer
uint32_t _fault_dumpPC(uint32_t *faultStack) {
//we dont need these for now
//volatile uint32_t r0;
//volatile uint32_t r1;
//volatile uint32_t r2;
//volatile uint32_t r3;
//volatile uint32_t r12;
//volatile uint32_t lr;
volatile uint32_t pc;
//volatile uint32_t psr;
//r0 = faultStack[0];
//r1 = faultStack[1];
//r2 = faultStack[2];
//r3 = faultStack[3];
//r12 = faultStack[4];
//lr = faultStack[5];
pc = faultStack[6];
//psr = faultStack[7];
__disable_irq();
USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
_fault_dumpInt(pc);
while (!(USART1->SR & USART_SR_TXE));
__reset();
}
// some ASM that calls our _fault_dumpPC function with a pointer to the stack that caused the fault
static void _fault_test( void ) __attribute__( ( naked ) );
static void _fault_test(void) {
__asm volatile (
" tst lr, #4 \n"
" ite eq \n"
" mrseq r0, msp \n"
" mrsne r0, psp \n"
" ldr r1, [r0, #24] \n"
" ldr r2, handler2_address_const \n"
" bx r2 \n"
" handler2_address_const: .word _fault_dumpPC \n"
);
}and then just call it at the top of the current fault handler because im lazy
void __attribute__((noreturn)) _exit(int status) {
_fault_test();compile kernel, put it in a project with some faulty code:
compile project and open up the debug terminal:
woo! we have our instruction pointer "0x08000192"
in order to convert this into the actual location of the fault, (obviously) first we need to compile the project with debugging information by adding -g to $CFLAGS in common.mk
CFLAGS:=$(CCFLAGS) -std=gnu99 -Werror=implicit-function-declaration -g
make sure you have arm-none-eabi-addr2line
finally
pixel@pixel-PC:~/pros_test$ arm-none-eabi-addr2line 0x08000192 --exe=bin/output.elf
/home/pixel/pros_test/src/opcontrol.c:36
Now ill work on getting a full backtrace and automating the process

