diff --git a/ports/arm/platforms/qemu_integratorcp/modules.c b/ports/arm/platforms/qemu_integratorcp/modules.c index 96312a1..86c658a 100644 --- a/ports/arm/platforms/qemu_integratorcp/modules.c +++ b/ports/arm/platforms/qemu_integratorcp/modules.c @@ -33,6 +33,7 @@ #include "atomport-private.h" #include "atom.h" #include "atomport.h" +#include "uart.h" /** Imports required by C startup code */ @@ -170,3 +171,15 @@ __interrupt_dispatcher (void) } + +/** + * \b null_handler + * + * Handler to catch interrupts at uninitialised vectors. + * + */ +void null_handler (void) +{ + uart_write_halt ("Unhandled interrupt\n"); +} + diff --git a/ports/arm/platforms/qemu_integratorcp/startup.s b/ports/arm/platforms/qemu_integratorcp/startup.s index a19ea76..1537d74 100644 --- a/ports/arm/platforms/qemu_integratorcp/startup.s +++ b/ports/arm/platforms/qemu_integratorcp/startup.s @@ -20,13 +20,13 @@ __interrupt_vector_table: B Reset_Handler /* Reset */ - B . /* Undefined */ - B . /* SWI */ - B . /* Prefetch Abort */ - B . /* Data Abort */ - B . /* reserved */ - B IRQ_Handler /* IRQ */ - B . /* FIQ */ + B Null_Handler /* Undefined */ + B Null_Handler /* SWI */ + B Null_Handler /* Prefetch Abort */ + B Null_Handler /* Data Abort */ + B Null_Handler /* reserved */ + B IRQ_Handler /* IRQ */ + B Null_Handler /* FIQ */ @@ -49,3 +49,5 @@ Reset_Handler: IRQ_Handler: B archIRQHandler +Null_Handler: + B null_handler diff --git a/ports/arm/platforms/qemu_integratorcp/uart.c b/ports/arm/platforms/qemu_integratorcp/uart.c index a57a194..36ab27a 100644 --- a/ports/arm/platforms/qemu_integratorcp/uart.c +++ b/ports/arm/platforms/qemu_integratorcp/uart.c @@ -218,3 +218,38 @@ int uart_write (const char *ptr, int len) return len; } + +/** + * \b uart_write_halt + * + * Simple polled UART write for handling critical failures + * by printing out a message on the UART and looping forever. + * Can be called from interrupt (unlike the standard + * uart_write()) but is not thread-safe because it cannot + * take the thread-safety mutex, and hence is only useful for + * a last-resort catastrophic debug message. + * + * @param[in] ptr Pointer to write string + */ +void uart_write_halt (const char *ptr) +{ + /* Check parameters */ + if (ptr != NULL) + { + /* Loop through all bytes until NULL terminator encountered */ + while (*ptr != '\0') + { + /* Wait for empty */ + while(UART_FR(UART0_ADDR) & UART_FR_TXFF) + ; + + /* Write byte to UART */ + UART_DR(UART0_ADDR) = *ptr++; + } + } + + /* Loop forever */ + while (1) + ; + +} diff --git a/ports/arm/platforms/qemu_integratorcp/uart.h b/ports/arm/platforms/qemu_integratorcp/uart.h index 57018c4..20fac85 100644 --- a/ports/arm/platforms/qemu_integratorcp/uart.h +++ b/ports/arm/platforms/qemu_integratorcp/uart.h @@ -33,5 +33,6 @@ /* UART driver APIs */ extern int uart_read (char *ptr, int len); extern int uart_write (const char *ptr, int len); +extern void uart_write_halt (const char *ptr); #endif /* __ATOM_UART_H */