Add periodic prints and stack monitor

This commit is contained in:
David Kopf 2011-08-24 10:55:58 -04:00
parent c23abeb3ed
commit 3c18372939

View file

@ -67,6 +67,24 @@
#include "contiki-maca.h" #include "contiki-maca.h"
#include "contiki-uart.h" #include "contiki-uart.h"
/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */
/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */
#define PERIODICPRINTS 0
#if PERIODICPRINTS
//#define PINGS 64
#define ROUTES 300
#define STAMPS 60
#define STACKMONITOR 600
//#define HEAPMONITOR 60
uint16_t clocktime;
#define TESTRTIMER 0
#if TESTRTIMER
uint8_t rtimerflag=1;
struct rtimer rt;
void rtimercycle(void) {rtimerflag=1;}
#endif
#endif
#define DEBUG 0 #define DEBUG 0
#if DEBUG #if DEBUG
#include <stdio.h> #include <stdio.h>
@ -327,6 +345,36 @@ main(void)
/* go into user mode */ /* go into user mode */
init_lowlevel(); init_lowlevel();
#if STACKMONITOR
/* Simple stack pointer highwater monitor. Checks for magic numbers in the main
* loop. In conjuction with PERIODICPRINTS, never-used stack will be printed
* every STACKMONITOR seconds.
*/
{
extern uint32_t __und_stack_top__, __sys_stack_top__;
uint32_t p=(uint32_t)&__und_stack_top__;
do {
*(uint32_t *)p = 0x42424242;
p+=16;
} while (p<(uint32_t)&__sys_stack_top__-100); //don't overwrite our own stack
}
#endif
#if HEAPMONITOR
/* Simple heap pointer highwater monitor. Checks for magic numbers in the main
* loop. In conjuction with PERIODICPRINTS, never-used heap will be printed
* every HEAPMONITOR seconds.
* This routine assumes a linear FIFO heap as used by the printf _sbrk call.
*/
{
extern uint32_t __heap_start__, __heap_end__;
uint32_t p=(uint32_t)&__heap_end__-4;
do {
*(uint32_t *)p = 0x42424242;
p-=4;
} while (p>=(uint32_t)&__heap_start__);
}
#endif
/* Clock */ /* Clock */
clock_init(); clock_init();
@ -498,6 +546,124 @@ main(void)
} }
process_run(); process_run();
#if PERIODICPRINTS
#if TESTRTIMER
/* Timeout can be increased up to 8 seconds maximum.
* A one second cycle is convenient for triggering the various debug printouts.
* The triggers are staggered to avoid printing everything at once.
*/
if (rtimerflag) {
rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
rtimerflag=0;
#else
if (clocktime!=clock_seconds()) {
clocktime=clock_seconds();
#endif
#if STAMPS
if ((clocktime%STAMPS)==0) {
#if ENERGEST_CONF_ON
#include "lib/print-stats.h"
print_stats();
#elif RADIOSTATS
extern volatile unsigned long radioontime;
printf("\r%u(%u)s ",clocktime,radioontime);
#else
printf("%us\n",clocktime);
#endif
}
#endif
#if TESTRTIMER
clocktime+=1;
#endif
#if PINGS && UIP_CONF_IPV6
extern void raven_ping6(void);
if ((clocktime%PINGS)==1) {
printf("**Ping\n");
raven_ping6();
}
#endif
#if ROUTES && UIP_CONF_IPV6
if ((clocktime%ROUTES)==2) {
extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
extern uip_ds6_route_t uip_ds6_routing_table[];
extern uip_ds6_netif_t uip_ds6_if;
uint8_t i,j;
printf("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
for (i=0;i<UIP_DS6_ADDR_NB;i++) {
if (uip_ds6_if.addr_list[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
printf("\n");
}
}
printf("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
if(uip_ds6_nbr_cache[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr);
printf("\n");
j=0;
}
}
if (j) printf(" <none>");
printf("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
if(uip_ds6_routing_table[i].isused) {
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
printf("/%u (via ", uip_ds6_routing_table[i].length);
uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
// if(uip_ds6_routing_table[i].state.lifetime < 600) {
printf(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
// } else {
// printf(")\n");
// }
j=0;
}
}
if (j) printf(" <none>");
printf("\n---------\n");
}
#endif
#if STACKMONITOR
if ((clocktime%STACKMONITOR)==3) {
extern uint32_t __und_stack_top__, __sys_stack_top__;
uint32_t p=(uint32_t)&__und_stack_top__;
do {
if (*(uint32_t *)p != 0x42424242) {
printf("Never-Used stack > %d bytes\n",p-(uint32_t)&__und_stack_top__);
break;
}
p+=16;
} while (p<(uint32_t)&__sys_stack_top__-100);
}
#endif
#if HEAPMONITOR
if ((clocktime%HEAPMONITOR)==4) {
extern uint32_t __heap_start__, __heap_end__;
uint32_t p=(uint32_t)&__heap_end__-4;
do {
if (*(uint32_t *)p != 0x42424242) {
break;
}
p-=4;
} while (p>=(uint32_t)&__heap_start__);
printf("Never-used heap >= %d bytes\n",(uint32_t)&__heap_end__-p-4);
#if 0
#include <stdlib.h>
char *ptr=malloc(1); //allocates 16 bytes from the heap
printf("********Got pointer %x\n",ptr);
#endif
}
#endif
}
#endif /* PERIODICPRINTS */
} }
return 0; return 0;