Print out a stack trace when a node reboots because of the watchdog

This commit is contained in:
adamdunkels 2010-03-30 23:02:23 +00:00
parent bcfa80102d
commit 4447782ab4

View File

@ -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 <io.h>
#include <signal.h>
#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;;
}
}
/*---------------------------------------------------------------------------*/