how can I catch unhandled exceptions in c source code

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

I try to catch unhandled exceptions in my c source.

Atmel does this in exeption.s assembler module.

first try:
// Register the Busmon interrupt handler to the interrupt controller.
INTC_register_interrupt(&busmon_irq, 0x008, AVR32_INTC_INT0);

did not work!

Does anyone know how to solve this?

/*
 * EVBA must be aligned with a power of two strictly greater than the
 * EVBA-relative offset of the last vector.
 */
.balign 0x200

// Export symbol.
.global _evba
.type _evba, @function
_evba:

	.org  0x000
	// Unrecoverable Exception.
_handle_Unrecoverable_Exception:
	rjmp $

	.org  0x004
	// TLB Multiple Hit.
_handle_TLB_Multiple_Hit:
	rjmp $

	.org  0x008
	// Bus Error Data Fetch.
_handle_Bus_Error_Data_Fetch:
	rjmp $

	.org  0x00C
	// Bus Error Instruction Fetch.
_handle_Bus_Error_Instruction_Fetch:
	rjmp $

	.org  0x010
	// NMI.
_handle_NMI:
	rjmp $

	.org  0x014
	// Instruction Address.
_handle_Instruction_Address:
	rjmp $
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

If you just want to see what caused the exception, here’s how I handle that:

_evba:

    .org  0x000
_handle_Unrecoverable_Exception:
    mov r8, 3
    rjmp isr_exception

    .org  0x004
_handle_TLB_Multiple_Hit:
    mov r8, 4
    rjmp isr_exception

    .org  0x008
_handle_Bus_Error_Data_Fetch:
    mov r8, 5
    rjmp isr_exception

    .org  0x00C
_handle_Bus_Error_Instruction_Fetch:
    mov r8, 6
    rjmp isr_exception

    .org  0x010
_handle_NMI:
    mov r8, 7
    rjmp isr_exception

You probably get the idea. Continue adding numbers for all other handlers according to the exception numbers in the datasheet, then jump to isr_exception.

Later in the assembly code I have this helper function:

isr_exception:
    st.w    --sp,sp
    pushm   r0-r7,lr
    bral    exception

That jumps to the following C function:

__attribute__((__interrupt__))
void exception(
        uint32_t r12,
        uint32_t r11,
        uint32_t r10,
        uint32_t r9,
        uint32_t exception_priority,
        uint32_t lr,
        uint32_t r7,
        uint32_t r6,
        uint32_t r5,
        uint32_t r4,
        uint32_t r3,
        uint32_t r2,
        uint32_t r1,
        uint32_t r0,
        uint32_t sp,
        uint32_t sr,
        uint32_t pc,
        uint32_t stack0,
        uint32_t stack1,
        uint32_t stack2) {
    sp += 8; // adjust SP to pre-exception value

    // do something fancy with all the values here
}

That way you can access all register values at the time of the exception, except for r8. The exception_priority parameter is the number you moved into r8 inside the handler. I use that for debugging and just print all information via USART.

If you want to use individual handlers, just replace the "rjmp $" with an rjmp to a custom handler.

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

Great!
Thank You for the given information!

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

I just noticed why that question sounded familiar: I answered the same question a while ago. D’oh. sambrown offered an alternative to my solution over there, so you might want to have a look.