SAML21J Exceptions handling

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, many times during my code running, my program stops running for unknown reasons (many times where it implies writing to the debug USART).

I noticed that I goes everytime inside the "Dummy_Handler", inside "startup_saml21.c", which appears to be an exception handler.

My questions are : how to properly manage exceptions ? Should I write debug stuff inside the Dummy Handler ? Can I use the printf inside it ? Should I write it inside this file or is there another good way to do it ?

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd bet you cannot print from your dummy_handler. I'm guessing you didn't write your exception handlers. You're in the dummy because of something bad, like a pointer dereference to an invalid memory region. If you're using gdb you can type 'bt' to see a backtrace. Then you can go 'up' until you find the reason you ended up in the dummy.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know that I am in the handler because of a HardFault :/

And how and where should I write my exception handlers ? In my own files or directly in startup_saml21.c ?

If I use the "bt" technique, what info tells me that it was this one that made me end up in the dummy ?

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So your backtrace does not show you what caused the hardfault? I just wrote to non-existent memory and I get this as a backtrace:

 

Program received signal SIGTRAP, Trace/breakpoint trap.
unhandled_exc () at interrupts.c:51
gdb>bt
#0  unhandled_exc () at interrupts.c:51
#1  <signal handler called>
#2  0x00004e6e in board_init () at main.c:165
#3  0x00004fba in main () at main.c:410
 

I select frame 2 and see the problem

gdb> f 2

static _Bool board_init(void)
{
       uint32_t *bad_ptr = (void *) 0x40000000; 
       *bad_ptr = 12; <--- Cause of exception
 

I wrote all my own code so my exception vectors are in crt0.S and my handlers are implemented in interrupts.c. My unhandled_exc() looks like this:

 

static void unhandled_exc(void) { __asm__("bkpt #1 \n"); }

 

And I install it as a weak symbol at the location for all the exceptions. Exceptions that I want to handle just override this weak symbol.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The thing is that I really goes wrong when I just call a function, not when I do something on a variable.

I know the exact assembly line where it goes wrong, but when I go check the address of the register that goes wrong, I really have no clue what it could be.

On the screenshot bellow, if I go to the next statement, it will go into the dummy handler.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Something's not right. Unless you are accessing beyond your internal Flash (pc + 220) that ldr should work.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think is the blx that is not working, it fails when I go beyond that point (the next adds is not reached)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well what's in r3 then??? Blx is an unconditional branch, adds should not be reached.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Luc-- wrote:

I noticed that I goes everytime inside the "Dummy_Handler", inside "startup_saml21.c", which appears to be an exception handler.

[...] Should I write debug stuff inside the Dummy Handler ? 

 

When you use something like this the interrupt source will be clear (just Pause the program):

 

// let's see who generates an interrupt
void PM_Handler() { while(1) ; }
void SYSCTRL_Handler() { while(1) ; }
void WDT_Handler() { while(1) ; }
void RTC_Handler() { while(1) ; }
void EIC_Handler() { while(1) ; }
void NVMCTRL_Handler() { while(1) ; }
void DMAC_Handler() { while(1) ; }
void USB_Handler() { while(1) ; }
void EVSYS_Handler() { while(1) ; }
void SERCOM0_Handler() { while(1) ; }
void SERCOM1_Handler() { while(1) ; }
void SERCOM2_Handler() { while(1) ; }
void TCC0_Handler() { while(1) ; }
void TC1_Handler() { while(1) ; }
//elsewhere: void TC2_Handler() { while(1) ; }
//elsewhere: void ADC_Handler() { while(1) ; }
void AC_Handler() { while(1) ; }
void DAC_Handler() { while(1) ; }
void PTC_Handler() { while(1) ; }
void NMI_Handler() { while(1) ; }
void HardFault_Handler() { while(1) ; }
void SVC_Handler() { while(1) ; }
void PendSV_Handler() { while(1) ; }
void SysTick_Handler() { while(1) ; }

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The content of R3 is in the screenshot I posted above, I don't know what it refers to, maybe it's a pointer I don't know... Is it always the last line that I can't go over the reason I have an exception, or could it come from lines above ? I know that r0 holds the pointer to the parameter I'm passing to the function that triggers this exception.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can you print it's value? That's what I was asking for.