Contiki 2.6
|
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 */