Contiki 2.6

contiki-mc1322x-main.c

00001 /*
00002  * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
00003  * to the MC1322x project (http://mc1322x.devl.org) and Contiki.
00004  *
00005  * Copyright (c) 2006, Technical University of Munich
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. Neither the name of the Institute nor the names of its contributors
00017  *    may be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00021  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00024  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00025  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00026  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00027  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00028  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00029  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  * This file is part of the Contiki operating system.
00033  *
00034  * @(#)$$
00035  */
00036 
00037 #include <signal.h>
00038 #include <stdio.h>
00039 #include <string.h>
00040 
00041 #include "contiki.h"
00042 
00043 #include "dev/leds.h"
00044 #include "dev/serial-line.h"
00045 #include "dev/slip.h"
00046 #include "dev/xmem.h"
00047 #include "dev/button-sensor.h"
00048 #include "lib/random.h"
00049 #include "net/netstack.h"
00050 #include "net/mac/frame802154.h"
00051 #include "lib/include/mc1322x.h"
00052 
00053 #if WITH_UIP6
00054 #include "net/sicslowpan.h"
00055 #include "net/uip-ds6.h"
00056 #include "net/mac/sicslowmac.h"
00057 #endif /* WITH_UIP6 */
00058 
00059 #include "net/rime.h"
00060 
00061 #include "sys/autostart.h"
00062 #include "sys/profile.h"
00063 
00064 /* from libmc1322x */
00065 #include "mc1322x.h"
00066 #include "default_lowlevel.h"
00067 #include "contiki-maca.h"
00068 #include "contiki-uart.h"
00069 
00070 /* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */
00071 /* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */
00072 #define PERIODICPRINTS 0
00073 #if PERIODICPRINTS
00074 //#define PINGS 64
00075 #define ROUTES 300
00076 #define STAMPS 60
00077 #define STACKMONITOR 600
00078 //#define HEAPMONITOR 60
00079 uint16_t clocktime;
00080 #define TESTRTIMER 0
00081 #if TESTRTIMER
00082 uint8_t rtimerflag=1;
00083 struct rtimer rt;
00084 void rtimercycle(void) {rtimerflag=1;}
00085 #endif
00086 #endif
00087 
00088 #define DEBUG 0
00089 #if DEBUG
00090 #include <stdio.h>
00091 #define PRINTF(...) printf(__VA_ARGS__)
00092 #define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
00093 #define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5])
00094 #else
00095 #define PRINTF(...)
00096 #define PRINT6ADDR(addr)
00097 #define PRINTLLADDR(addr)
00098 #endif
00099 
00100 #ifndef RIMEADDR_NVM
00101 #define RIMEADDR_NVM 0x1E000
00102 #endif
00103 
00104 #ifndef RIMEADDR_NBYTES
00105 #define RIMEADDR_NBYTES 8
00106 #endif
00107 
00108 #if UIP_CONF_ROUTER
00109 
00110 #ifndef UIP_ROUTER_MODULE
00111 #ifdef UIP_CONF_ROUTER_MODULE
00112 #define UIP_ROUTER_MODULE UIP_CONF_ROUTER_MODULE
00113 #else /* UIP_CONF_ROUTER_MODULE */
00114 #define UIP_ROUTER_MODULE rimeroute
00115 #endif /* UIP_CONF_ROUTER_MODULE */
00116 #endif /* UIP_ROUTER_MODULE */
00117 
00118 extern const struct uip_router UIP_ROUTER_MODULE;
00119 
00120 #endif /* UIP_CONF_ROUTER */
00121 
00122 #if DCOSYNCH_CONF_ENABLED
00123 static struct timer mgt_timer;
00124 #endif
00125 
00126 #ifndef WITH_UIP
00127 #define WITH_UIP 0
00128 #endif
00129 
00130 #if WITH_UIP
00131 #include "net/uip.h"
00132 #include "net/uip-fw.h"
00133 #include "net/uip-fw-drv.h"
00134 #include "net/uip-over-mesh.h"
00135 static struct uip_fw_netif slipif =
00136   {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)};
00137 static struct uip_fw_netif meshif =
00138   {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
00139 
00140 #endif /* WITH_UIP */
00141 
00142 #define UIP_OVER_MESH_CHANNEL 8
00143 #if WITH_UIP
00144 static uint8_t is_gateway;
00145 #endif /* WITH_UIP */
00146 
00147 /*---------------------------------------------------------------------------*/
00148 void uip_log(char *msg) { printf("%c",msg); }
00149 /*---------------------------------------------------------------------------*/
00150 #ifndef RF_CHANNEL
00151 #define RF_CHANNEL              26
00152 #endif
00153 /*---------------------------------------------------------------------------*/
00154 #if WITH_UIP
00155 static void
00156 set_gateway(void)
00157 {
00158   if(!is_gateway) {
00159     leds_on(LEDS_RED);
00160     printf("%d.%d: making myself the IP network gateway.\n\n",
00161            rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00162     printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
00163            uip_ipaddr_to_quad(&uip_hostaddr));
00164     uip_over_mesh_set_gateway(&rimeaddr_node_addr);
00165     uip_over_mesh_make_announced_gateway();
00166     is_gateway = 1;
00167   }
00168 }
00169 #endif /* WITH_UIP */
00170 /*---------------------------------------------------------------------------*/
00171 static void
00172 print_processes(struct process * const processes[])
00173 {
00174   /*  const struct process * const * p = processes;*/
00175   printf("Starting");
00176   while(*processes != NULL) {
00177     printf(" '%s'", (*processes)->name);
00178     processes++;
00179   }
00180   printf("\n");
00181 }
00182 /*--------------------------------------------------------------------------*/
00183 
00184 SENSORS(&button_sensor);
00185 
00186 void
00187 init_lowlevel(void)
00188 {
00189         /* button init */
00190         /* set up kbi */
00191         enable_irq_kbi(4);
00192         kbi_edge(4);
00193         enable_ext_wu(4);
00194 //      kbi_pol_neg(7);
00195 //      kbi_pol_pos(7);
00196 //      gpio_sel0_pullup(29);
00197 //      gpio_pu0_disable(29);
00198 
00199         trim_xtal();
00200         
00201         /* uart init */
00202         uart_init(BRINC, BRMOD, SAMP);
00203         
00204         default_vreg_init();
00205 
00206         maca_init();
00207 
00208         set_channel(RF_CHANNEL - 11); /* channel 11 */
00209         set_power(0x12); /* 0x12 is the highest, not documented */
00210 
00211         enable_irq(CRM);
00212 
00213 #if USE_32KHZ_XTAL
00214         enable_32khz_xtal();
00215 #else
00216         cal_ring_osc();
00217 #endif
00218 
00219 #if USE_32KHZ_XTAL
00220         *CRM_RTC_TIMEOUT = 32768 * 10; 
00221 #else 
00222         *CRM_RTC_TIMEOUT = cal_rtc_secs * 10;
00223 #endif
00224 
00225 #if (USE_WDT == 1)
00226         /* set the watchdog timer timeout to 1 sec */
00227         cop_timeout_ms(WDT_TIMEOUT);
00228         /* enable the watchdog timer */
00229         CRM->COP_CNTLbits.COP_EN = 1;
00230 #endif
00231 
00232         /* XXX debug */
00233         /* trigger periodic rtc int */
00234 //      clear_rtc_wu_evt();
00235 //      enable_rtc_wu();
00236 //      enable_rtc_wu_irq();
00237 }
00238 
00239 #if RIMEADDR_SIZE == 1
00240 const rimeaddr_t addr_ff = { { 0xff } };
00241 #else /*RIMEADDR_SIZE == 2*/
00242 #if RIMEADDR_SIZE == 2
00243 const rimeaddr_t addr_ff = { { 0xff, 0xff } };
00244 #else /*RIMEADDR_SIZE == 2*/
00245 #if RIMEADDR_SIZE == 8
00246 const rimeaddr_t addr_ff = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
00247 #endif /*RIMEADDR_SIZE == 8*/
00248 #endif /*RIMEADDR_SIZE == 2*/
00249 #endif /*RIMEADDR_SIZE == 1*/
00250 
00251 void iab_to_eui64(rimeaddr_t *eui64, uint32_t oui, uint16_t iab, uint32_t ext) {
00252         /* OUI for IABs */
00253         eui64->u8[0] =  0x00;
00254         eui64->u8[1] =  0x50;
00255         eui64->u8[2] =  0xc2;
00256 
00257         /* IAB */
00258         eui64->u8[3] = (iab >> 4)  & 0xff;
00259         eui64->u8[4] = (iab << 4) &  0xf0;
00260 
00261         /* EXT */
00262 
00263         eui64->u8[4] |= (ext >> 24) & 0xf;
00264         eui64->u8[5] = (ext >> 16) & 0xff;
00265         eui64->u8[6] = (ext >> 8)  & 0xff;
00266         eui64->u8[7] =  ext        & 0xff;
00267 }
00268 
00269 void oui_to_eui64(rimeaddr_t *eui64, uint32_t oui, uint64_t ext) {
00270         /* OUI */
00271         eui64->u8[0] = (oui >> 16) & 0xff;
00272         eui64->u8[1] = (oui >> 8)  & 0xff;
00273         eui64->u8[2] =  oui        & 0xff;
00274 
00275         /* EXT */
00276         eui64->u8[3] = (ext >> 32) & 0xff;
00277         eui64->u8[4] = (ext >> 24) & 0xff;
00278         eui64->u8[5] = (ext >> 16) & 0xff;
00279         eui64->u8[6] = (ext >> 8)  & 0xff;
00280         eui64->u8[7] =  ext        & 0xff;
00281 }
00282 
00283 unsigned short node_id = 0;
00284 
00285 void
00286 set_rimeaddr(rimeaddr_t *addr) 
00287 {
00288         nvmType_t type=0;
00289         nvmErr_t err;   
00290         volatile uint8_t buf[RIMEADDR_NBYTES];
00291         rimeaddr_t eui64;
00292         int i;
00293                 
00294         err = nvm_detect(gNvmInternalInterface_c, &type);
00295 
00296         err = nvm_read(gNvmInternalInterface_c, type, (uint8_t *)buf, RIMEADDR_NVM, RIMEADDR_NBYTES);
00297 
00298         rimeaddr_copy(addr,&rimeaddr_null);
00299 
00300         for(i=0; i<RIMEADDR_CONF_SIZE; i++) {           
00301                 addr->u8[i] = buf[i];
00302         }
00303 
00304         if (memcmp(addr, &addr_ff, RIMEADDR_CONF_SIZE)==0) {
00305 
00306                 //set addr to EUI64
00307 #ifdef IAB              
00308    #ifdef EXT_ID
00309                 PRINTF("address in flash blank, setting to defined IAB and extension.\n\r");
00310                 iab_to_eui64(&eui64, OUI, IAB, EXT_ID);
00311    #else  /* ifdef EXT_ID */
00312                 PRINTF("address in flash blank, setting to defined IAB with a random extension.\n\r");
00313                 iab_to_eui64(&eui64, OUI, IAB, *MACA_RANDOM);
00314    #endif /* ifdef EXT_ID */
00315 
00316 #else  /* ifdef IAB */
00317 
00318    #ifdef EXT_ID
00319                 PRINTF("address in flash blank, setting to defined OUI and extension.\n\r");
00320                 oui_to_eui64(&eui64, OUI, EXT_ID);
00321    #else  /*ifdef EXT_ID */
00322                 PRINTF("address in flash blank, setting to defined OUI with a random extension.\n\r");
00323                 oui_to_eui64(&eui64, OUI, ((*MACA_RANDOM << 32) | *MACA_RANDOM));
00324    #endif /*endif EXTID */
00325 
00326 #endif /* ifdef IAB */
00327 
00328                 rimeaddr_copy(addr, &eui64);            
00329 #ifdef FLASH_BLANK_ADDR
00330                 PRINTF("flashing blank address\n\r");
00331                 err = nvm_write(gNvmInternalInterface_c, type, &(eui64.u8), RIMEADDR_NVM, RIMEADDR_NBYTES);             
00332 #endif /* ifdef FLASH_BLANK_ADDR */
00333         } else {
00334                 PRINTF("loading rime address from flash.\n\r");
00335         }
00336 
00337         node_id = (addr->u8[6] << 8 | addr->u8[7]);
00338         rimeaddr_set_node_addr(addr);
00339 }
00340 
00341 int
00342 main(void)
00343 {
00344         volatile uint32_t i;
00345         rimeaddr_t addr;
00346 
00347         /* Initialize hardware and */
00348         /* go into user mode */
00349         init_lowlevel();
00350 
00351 #if STACKMONITOR
00352   /* Simple stack pointer highwater monitor. Checks for magic numbers in the main
00353    * loop. In conjuction with PERIODICPRINTS, never-used stack will be printed
00354    * every STACKMONITOR seconds.
00355    */
00356 {
00357 extern uint32_t __und_stack_top__, __sys_stack_top__;
00358 uint32_t p=(uint32_t)&__und_stack_top__;
00359     do {
00360       *(uint32_t *)p = 0x42424242;
00361       p+=16;
00362     } while (p<(uint32_t)&__sys_stack_top__-100); //don't overwrite our own stack
00363 }
00364 #endif
00365 #if HEAPMONITOR
00366   /* Simple heap pointer highwater monitor. Checks for magic numbers in the main
00367    * loop. In conjuction with PERIODICPRINTS, never-used heap will be printed
00368    * every HEAPMONITOR seconds.
00369    * This routine assumes a linear FIFO heap as used by the printf _sbrk call.
00370    */
00371 {
00372 extern uint32_t __heap_start__, __heap_end__;
00373 uint32_t p=(uint32_t)&__heap_end__-4;
00374   do {
00375      *(uint32_t *)p = 0x42424242;
00376          p-=4;
00377   } while (p>=(uint32_t)&__heap_start__);
00378 }
00379 #endif
00380 
00381         /* Clock */
00382         clock_init();   
00383 
00384         /* LED driver */
00385         leds_init();
00386 
00387         /* control TX_ON with the radio */
00388         GPIO->FUNC_SEL.GPIO_44 = 2;
00389         GPIO->PAD_DIR.GPIO_44 = 1;
00390 
00391         /* Process subsystem */
00392         process_init();
00393         process_start(&etimer_process, NULL);
00394         process_start(&contiki_maca_process, NULL);
00395 
00396         ctimer_init();
00397 
00398         set_rimeaddr(&addr);
00399 
00400         printf("Rime started with address ");
00401         for(i = 0; i < sizeof(addr.u8) - 1; i++) {
00402                 printf("%02X:", addr.u8[i]);
00403         }
00404         printf("%02X\n", addr.u8[i]);
00405 
00406 
00407 #if WITH_UIP6
00408   memcpy(&uip_lladdr.addr, &addr.u8, sizeof(uip_lladdr.addr));
00409   /* Setup nullmac-like MAC for 802.15.4 */
00410 /*   sicslowpan_init(sicslowmac_init(&cc2420_driver)); */
00411 /*   printf(" %s channel %u\n", sicslowmac_driver.name, RF_CHANNEL); */
00412 
00413   /* Setup X-MAC for 802.15.4 */
00414   queuebuf_init();
00415   NETSTACK_RDC.init();
00416   NETSTACK_MAC.init();
00417   NETSTACK_NETWORK.init();
00418 
00419   printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
00420          NETSTACK_MAC.name, NETSTACK_RDC.name,
00421          CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
00422                          NETSTACK_RDC.channel_check_interval()),
00423          RF_CHANNEL);
00424 
00425   process_start(&tcpip_process, NULL);
00426 
00427   printf("Tentative link-local IPv6 address ");
00428   {
00429     int i, a;
00430     for(a = 0; a < UIP_DS6_ADDR_NB; a++) {
00431       if (uip_ds6_if.addr_list[a].isused) {
00432         for(i = 0; i < 7; ++i) {
00433           printf("%02x%02x:",
00434                  uip_ds6_if.addr_list[a].ipaddr.u8[i * 2],
00435                  uip_ds6_if.addr_list[a].ipaddr.u8[i * 2 + 1]);
00436         }
00437         printf("%02x%02x\n",
00438                uip_ds6_if.addr_list[a].ipaddr.u8[14],
00439                uip_ds6_if.addr_list[a].ipaddr.u8[15]);
00440       }
00441     }
00442   }
00443   
00444   if(1) {
00445     uip_ipaddr_t ipaddr;
00446     int i;
00447     uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
00448     uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
00449     uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
00450     printf("Tentative global IPv6 address ");
00451     for(i = 0; i < 7; ++i) {
00452       printf("%02x%02x:",
00453              ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
00454     }
00455     printf("%02x%02x\n",
00456            ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
00457   }
00458 
00459   
00460 #else /* WITH_UIP6 */
00461 
00462   NETSTACK_RDC.init();
00463   NETSTACK_MAC.init();
00464   NETSTACK_NETWORK.init();
00465 
00466   printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
00467          NETSTACK_MAC.name, NETSTACK_RDC.name,
00468          CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1:
00469                          NETSTACK_RDC.channel_check_interval()),
00470          RF_CHANNEL);
00471 #endif /* WITH_UIP6 */
00472 
00473   *MACA_MACPANID = 0xcdab; /* this is the hardcoded contiki pan, register is PACKET order */
00474   *MACA_MAC16ADDR = 0xffff; /* short addressing isn't used, set this to 0xffff for now */
00475 
00476   *MACA_MAC64HI =
00477           addr.u8[0] << 24 |
00478           addr.u8[1] << 16 |
00479           addr.u8[2] << 8 |
00480           addr.u8[3];
00481   *MACA_MAC64LO =
00482           addr.u8[4] << 24 |
00483           addr.u8[5] << 16 |
00484           addr.u8[6] << 8 |
00485           addr.u8[7];
00486   PRINTF("setting panid 0x%04x\n\r", *MACA_MACPANID);
00487   PRINTF("setting short mac 0x%04x\n\r", *MACA_MAC16ADDR);
00488   PRINTF("setting long mac 0x%08x_%08x\n\r", *MACA_MAC64HI, *MACA_MAC64LO);
00489 
00490 #if MACA_AUTOACK
00491   set_prm_mode(AUTOACK);
00492 #endif
00493 
00494 #if PROFILE_CONF_ON
00495   profile_init();
00496 #endif /* PROFILE_CONF_ON */
00497 
00498 #if TIMESYNCH_CONF_ENABLED
00499   timesynch_init();
00500   timesynch_set_authority_level(rimeaddr_node_addr.u8[0]);
00501 #endif /* TIMESYNCH_CONF_ENABLED */
00502 
00503 #if WITH_UIP
00504   process_start(&tcpip_process, NULL);
00505   process_start(&uip_fw_process, NULL); /* Start IP output */
00506   process_start(&slip_process, NULL);
00507 
00508   slip_set_input_callback(set_gateway);
00509 
00510   {
00511     uip_ipaddr_t hostaddr, netmask;
00512 
00513     uip_init();
00514 
00515     uip_ipaddr(&hostaddr, 172,16,
00516                rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
00517     uip_ipaddr(&netmask, 255,255,0,0);
00518     uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
00519 
00520     uip_sethostaddr(&hostaddr);
00521     uip_setnetmask(&netmask);
00522     uip_over_mesh_set_net(&hostaddr, &netmask);
00523     /*    uip_fw_register(&slipif);*/
00524     uip_over_mesh_set_gateway_netif(&slipif);
00525     uip_fw_default(&meshif);
00526     uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
00527     printf("uIP started with IP address %d.%d.%d.%d\n",
00528            uip_ipaddr_to_quad(&hostaddr));
00529   }
00530 #endif /* WITH_UIP */
00531 
00532   process_start(&sensors_process, NULL);
00533   
00534   print_processes(autostart_processes);
00535   autostart_start(autostart_processes);
00536  
00537   /* Main scheduler loop */
00538   while(1) {
00539           check_maca();
00540 
00541 #if (USE_WDT == 1)
00542           cop_service();
00543 #endif
00544 
00545           if(uart1_input_handler != NULL) {
00546                   if(uart1_can_get()) {
00547                           uart1_input_handler(uart1_getc());
00548                   }
00549           }
00550                  
00551           process_run();
00552 
00553 #if PERIODICPRINTS
00554 #if TESTRTIMER
00555 /* Timeout can be increased up to 8 seconds maximum.
00556  * A one second cycle is convenient for triggering the various debug printouts.
00557  * The triggers are staggered to avoid printing everything at once.
00558  */
00559     if (rtimerflag) {
00560       rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
00561       rtimerflag=0;
00562 #else
00563   if (clocktime!=clock_seconds()) {
00564      clocktime=clock_seconds();
00565 #endif
00566 
00567 #if STAMPS
00568 if ((clocktime%STAMPS)==0) {
00569 #if ENERGEST_CONF_ON
00570 #include "lib/print-stats.h"
00571         print_stats();
00572 #elif RADIOSTATS
00573 extern volatile unsigned long radioontime;
00574   printf("\r%u(%u)s ",clocktime,radioontime);
00575 #else
00576   printf("%us\n",clocktime);
00577 #endif
00578 
00579 }
00580 #endif
00581 #if TESTRTIMER
00582       clocktime+=1;
00583 #endif
00584 
00585 #if PINGS && UIP_CONF_IPV6
00586 extern void raven_ping6(void); 
00587 if ((clocktime%PINGS)==1) {
00588   printf("**Ping\n");
00589   raven_ping6();
00590 }
00591 #endif
00592 
00593 #if ROUTES && UIP_CONF_IPV6
00594 if ((clocktime%ROUTES)==2) {
00595       
00596 extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
00597 extern uip_ds6_route_t uip_ds6_routing_table[];
00598 extern uip_ds6_netif_t uip_ds6_if;
00599 
00600   uint8_t i,j;
00601   printf("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
00602   for (i=0;i<UIP_DS6_ADDR_NB;i++) {
00603     if (uip_ds6_if.addr_list[i].isused) {
00604       uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
00605       printf("\n");
00606     }
00607   }
00608   printf("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
00609   for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
00610     if(uip_ds6_nbr_cache[i].isused) {
00611       uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr);
00612       printf("\n");
00613       j=0;
00614     }
00615   }
00616   if (j) printf("  <none>");
00617   printf("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
00618   for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
00619     if(uip_ds6_routing_table[i].isused) {
00620       uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
00621       printf("/%u (via ", uip_ds6_routing_table[i].length);
00622       uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
00623  //     if(uip_ds6_routing_table[i].state.lifetime < 600) {
00624         printf(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
00625  //     } else {
00626  //       printf(")\n");
00627  //     }
00628       j=0;
00629     }
00630   }
00631   if (j) printf("  <none>");
00632   printf("\n---------\n");
00633 }
00634 #endif
00635 
00636 #if STACKMONITOR
00637 if ((clocktime%STACKMONITOR)==3) {
00638 extern uint32_t __und_stack_top__, __sys_stack_top__;
00639 uint32_t p=(uint32_t)&__und_stack_top__;
00640   do {
00641     if (*(uint32_t *)p != 0x42424242) {
00642       printf("Never-Used stack > %d bytes\n",p-(uint32_t)&__und_stack_top__);
00643       break;
00644     }
00645     p+=16;
00646   } while (p<(uint32_t)&__sys_stack_top__-100);
00647 }
00648 #endif
00649 #if HEAPMONITOR
00650 if ((clocktime%HEAPMONITOR)==4) {
00651 extern uint32_t __heap_start__, __heap_end__;
00652 uint32_t p=(uint32_t)&__heap_end__-4;
00653   do {
00654     if (*(uint32_t *)p != 0x42424242) {
00655       break;
00656     }
00657     p-=4;
00658   } while (p>=(uint32_t)&__heap_start__);
00659   printf("Never-used heap >= %d bytes\n",(uint32_t)&__heap_end__-p-4);
00660 #if 0
00661 #include <stdlib.h>
00662 char *ptr=malloc(1);  //allocates 16 bytes from the heap
00663 printf("********Got pointer %x\n",ptr);
00664 #endif
00665 }
00666 #endif
00667 
00668     }
00669 #endif /* PERIODICPRINTS */
00670   }
00671   
00672   return 0;
00673 }
00674 
00675 /*---------------------------------------------------------------------------*/
00676 #if LOG_CONF_ENABLED
00677 void
00678 log_message(char *m1, char *m2)
00679 {
00680   printf("%s%s\n", m1, m2);
00681 }
00682 #endif /* LOG_CONF_ENABLED */