From 4447782ab450fb58efd91b0360c27bcd3ef3befa Mon Sep 17 00:00:00 2001 From: adamdunkels Date: Tue, 30 Mar 2010 23:02:23 +0000 Subject: [PATCH] Print out a stack trace when a node reboots because of the watchdog --- cpu/msp430/watchdog.c | 62 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/cpu/msp430/watchdog.c b/cpu/msp430/watchdog.c index 75a1c8d67..acff7a03c 100644 --- a/cpu/msp430/watchdog.c +++ b/cpu/msp430/watchdog.c @@ -28,13 +28,66 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: watchdog.c,v 1.5 2008/02/11 10:45:19 adamdunkels Exp $ + * @(#)$Id: watchdog.c,v 1.6 2010/03/30 23:02:23 adamdunkels Exp $ */ #include +#include #include "dev/watchdog.h" static int stopped = 0; /*---------------------------------------------------------------------------*/ +static void +printchar(char c) +{ + /* Loop until the transmission buffer is available. */ + while((IFG2 & UTXIFG1) == 0); + + /* Transmit the data. */ + TXBUF1 = c; +} +/*---------------------------------------------------------------------------*/ +static void +hexprint(uint8_t v) +{ + const char hexconv[] = "0123456789abcdef"; + printchar(hexconv[v >> 4]); + printchar(hexconv[v & 0x0f]); +} +/*---------------------------------------------------------------------------*/ +static void +printstring(char *s) +{ + while(*s) { + printchar(*s++); + } +} +/*---------------------------------------------------------------------------*/ +interrupt(WDT_VECTOR) +watchdog_interrupt(void) +{ + uint8_t dummy; + static uint8_t *ptr; + static int i; + + ptr = &dummy; + + printstring("Watchdog reset"); + /* printstring("Watchdog reset at PC $"); + hexprint(ptr[3]); + hexprint(ptr[2]);*/ + printstring("\nStack:\n"); + + for(i = 0; i < 64; ++i) { + hexprint(ptr[i]); + printchar(' '); + if((i & 0x0f) == 0x0f) { + printchar('\n'); + } + } + printchar('\n'); + watchdog_reboot(); +} +/*---------------------------------------------------------------------------*/ void watchdog_init(void) { @@ -42,6 +95,9 @@ watchdog_init(void) initialization. */ stopped = 0; watchdog_stop(); + + IFG1 &= ~WDTIFG; + IE1 |= WDTIE; } /*---------------------------------------------------------------------------*/ void @@ -51,7 +107,7 @@ watchdog_start(void) unless watchdog_periodic() is called. */ stopped--; if(!stopped) { - WDTCTL = WDTPW | WDTCNTCL | WDT_ARST_1000; + WDTCTL = WDTPW | WDTCNTCL | WDT_ARST_1000 | WDTTMSEL; } } /*---------------------------------------------------------------------------*/ @@ -61,7 +117,7 @@ watchdog_periodic(void) /* This function is called periodically to restart the watchdog timer. */ if(!stopped) { - WDTCTL = (WDTCTL & 0xff) | WDTPW | WDTCNTCL; + WDTCTL = (WDTCTL & 0xff) | WDTPW | WDTCNTCL | WDTTMSEL;; } } /*---------------------------------------------------------------------------*/