Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2006, Technical University of Munich 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 * @(#)$$ 00032 */ 00033 00034 /** 00035 * \file 00036 * Contiki 2.4 kernel for Jackdaw USB stick 00037 * 00038 * \author 00039 * Simon Barner <barner@in.tum.de> 00040 * David Kopf <dak664@embarqmail.com> 00041 */ 00042 00043 #define DEBUG 0 00044 #if DEBUG 00045 #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) 00046 #else 00047 #define PRINTD(...) 00048 #endif 00049 00050 #include <avr/pgmspace.h> 00051 #include <avr/fuse.h> 00052 #include <avr/eeprom.h> 00053 #include <avr/wdt.h> 00054 #include <util/delay.h> 00055 #include <stdio.h> 00056 #include <string.h> 00057 00058 #include "lib/mmem.h" 00059 #include "loader/symbols-def.h" 00060 #include "loader/symtab.h" 00061 00062 #include "contiki.h" 00063 #include "contiki-net.h" 00064 #include "contiki-lib.h" 00065 #include "contiki-raven.h" 00066 00067 /* Set ANNOUNCE to send boot messages to USB or RS232 serial port */ 00068 #define ANNOUNCE 1 00069 00070 /* But only if a serial port exists */ 00071 #if USB_CONF_SERIAL||USB_CONF_RS232 00072 #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) 00073 #else 00074 #define PRINTA(...) 00075 #endif 00076 00077 #include "usb_task.h" 00078 #if USB_CONF_SERIAL 00079 #include "cdc_task.h" 00080 #endif 00081 #if USB_CONF_RS232 00082 #include "dev/rs232.h" 00083 #endif 00084 00085 #include "rndis/rndis_task.h" 00086 #if USB_CONF_STORAGE 00087 #include "storage/storage_task.h" 00088 #endif 00089 00090 #include "dev/watchdog.h" 00091 #include "dev/usb/usb_drv.h" 00092 00093 #if JACKDAW_CONF_USE_SETTINGS 00094 #include "settings.h" 00095 #endif 00096 00097 #if RF230BB //radio driver using contiki core mac 00098 #include "radio/rf230bb/rf230bb.h" 00099 #include "net/mac/frame802154.h" 00100 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 00101 rimeaddr_t macLongAddr; 00102 #define tmp_addr macLongAddr 00103 #else //legacy radio driver using Atmel/Cisco 802.15.4'ish MAC 00104 #include <stdbool.h> 00105 #include "mac.h" 00106 #include "sicslowmac.h" 00107 #include "sicslowpan.h" 00108 #include "ieee-15-4-manager.h" 00109 #endif /* RF230BB */ 00110 00111 /* Test rtimers, also useful for pings, time stamps, routes, stack monitor */ 00112 #define TESTRTIMER 0 00113 #if TESTRTIMER 00114 #define PINGS 0 00115 #define STAMPS 60 00116 #define ROUTES 120 00117 #define STACKMONITOR 600 00118 uint8_t rtimerflag=1; 00119 uint16_t rtime; 00120 struct rtimer rt; 00121 void rtimercycle(void) {rtimerflag=1;} 00122 #endif /* TESTRTIMER */ 00123 00124 #if UIP_CONF_IPV6_RPL 00125 /*---------------------------------------------------------------------------*/ 00126 /*--------------------------------- RPL ----------------------------------*/ 00127 /*---------------------------------------------------------------------------*/ 00128 /* TODO: Put rpl code into another file, once it stabilizes */ 00129 /* Set up fallback interface links to direct stack tcpip output to ethernet */ 00130 static void 00131 init(void) 00132 { 00133 } 00134 void mac_LowpanToEthernet(void); 00135 static void 00136 output(void) 00137 { 00138 // if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { 00139 /* Do not bounce packets back over USB if the packet was received from USB */ 00140 // PRINTA("JACKDAW router: Destination off-link but no route\n"); 00141 // } else { 00142 PRINTD("SUT: %u\n", uip_len); 00143 mac_LowpanToEthernet(); //bounceback trap is done in lowpanToEthernet 00144 // } 00145 } 00146 const struct uip_fallback_interface rpl_interface = { 00147 init, output 00148 }; 00149 00150 #if RPL_BORDER_ROUTER 00151 #include "net/rpl/rpl.h" 00152 00153 // avr-objdump --section .bss -x ravenusbstick.elf 00154 const uint16_t dag_id[] PROGMEM = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011}; 00155 00156 PROCESS(border_router_process, "RPL Border Router"); 00157 PROCESS_THREAD(border_router_process, ev, data) 00158 { 00159 00160 PROCESS_BEGIN(); 00161 00162 PROCESS_PAUSE(); 00163 00164 { rpl_dag_t *dag; 00165 char buf[sizeof(dag_id)]; 00166 memcpy_P(buf,dag_id,sizeof(dag_id)); 00167 dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)buf); 00168 00169 /* Assign separate addresses to the jackdaw uip stack and the host network interface, but with the same prefix */ 00170 /* E.g. bbbb::200 to the jackdaw and bbbb::1 to the host network interface with $ip -6 address add bbbb::1/64 dev usb0 */ 00171 /* Otherwise the host will trap packets intended for the jackdaw, just as the jackdaw will trap RF packets intended for the host */ 00172 /* $ifconfig usb0 -arp on Ubuntu to skip the neighbor solicitations. Add explicit neighbors on other OSs */ 00173 if(dag != NULL) { 00174 PRINTD("created a new RPL dag\n"); 00175 00176 #if UIP_CONF_ROUTER_RECEIVE_RA 00177 //Contiki stack will shut down until assigned an address from the interface RA 00178 //Currently this requires changes in the core rpl-icmp6.c to pass the link-local RA broadcast 00179 00180 #else 00181 uip_ip6addr_t ipaddr; 00182 uip_ip6addr(&ipaddr, 0xbbbb, 0, 0, 0, 0, 0, 0, 0x200); 00183 uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL); 00184 rpl_set_prefix(dag, &ipaddr, 64); 00185 #endif 00186 } 00187 } 00188 /* The border router runs with a 100% duty cycle in order to ensure high 00189 packet reception rates. */ 00190 // NETSTACK_MAC.off(1); 00191 00192 while(1) { 00193 PROCESS_YIELD(); 00194 /* Local and global dag repair can be done from the jackdaw menu */ 00195 00196 } 00197 00198 PROCESS_END(); 00199 } 00200 #endif /* RPL_BORDER_ROUTER */ 00201 00202 #endif /* UIP_CONF_IPV6_RPL */ 00203 00204 /*-------------------------------------------------------------------------*/ 00205 /*----------------------Configuration of the .elf file---------------------*/ 00206 #if 1 00207 /* The proper way to set the signature is */ 00208 #include <avr/signature.h> 00209 #else 00210 /* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */ 00211 typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t; 00212 #define SIGNATURE __signature_t __signature __attribute__((section (".signature"))) 00213 SIGNATURE = { 00214 .B2 = 0x82,//SIGNATURE_2, //AT90USB128x 00215 .B1 = 0x97,//SIGNATURE_1, //128KB flash 00216 .B0 = 0x1E,//SIGNATURE_0, //Atmel 00217 }; 00218 #endif 00219 00220 FUSES ={.low = 0xde, .high = 0x99, .extended = 0xff,}; 00221 00222 /* Save the default settings into program flash memory */ 00223 const uint8_t default_mac_address[8] PROGMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16}; 00224 #ifdef CHANNEL_802_15_4 00225 const uint8_t default_channel PROGMEM = CHANNEL_802_15_4; 00226 #else 00227 const uint8_t default_channel PROGMEM = 26; 00228 #endif 00229 #ifdef IEEE802154_PANID 00230 const uint16_t default_panid PROGMEM = IEEE802154_PANID; 00231 #else 00232 const uint16_t default_panid PROGMEM = 0xABCD; 00233 #endif 00234 #ifdef IEEE802154_PANADDR 00235 const uint16_t default_panaddr PROGMEM = IEEE802154_PANID; 00236 #else 00237 const uint16_t default_panaddr PROGMEM = 0; 00238 #endif 00239 #ifdef RF230_MAX_TX_POWER 00240 const uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER; 00241 #else 00242 const uint8_t default_txpower PROGMEM = 0; 00243 #endif 00244 00245 #if JACKDAW_CONF_RANDOM_MAC 00246 #include "rng.h" 00247 static void 00248 generate_new_eui64(uint8_t eui64[8]) { 00249 eui64[0] = 0x02; 00250 eui64[1] = rng_get_uint8(); 00251 eui64[2] = rng_get_uint8(); 00252 eui64[3] = 0xFF; 00253 eui64[4] = 0xFE; 00254 eui64[5] = rng_get_uint8(); 00255 eui64[6] = rng_get_uint8(); 00256 eui64[7] = rng_get_uint8(); 00257 } 00258 #endif /* JACKDAW_CONF_RANDOM_MAC */ 00259 00260 #if !JACKDAW_CONF_USE_SETTINGS 00261 /****************************No settings manager*****************************/ 00262 /* If not using the settings manager, put the default values into EEMEM 00263 * These can be manually changed and kept over program reflash. 00264 * The channel and bit complement are used to check EEMEM integrity, 00265 * If corrupt all values will be rewritten with the default flash values. 00266 * To make this work, get the channel before anything else. 00267 */ 00268 00269 uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16}; 00270 #ifdef CHANNEL_802_15_4 00271 uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4}; 00272 #else 00273 uint8_t eemem_channel[2] EMEM = {26, ~26}; 00274 #endif 00275 #ifdef IEEE802154_PANID 00276 uint16_t eemem_panid EEMEM = IEEE802154_PANID; 00277 #else 00278 uint16_t eemem_panid EEMEM = 0xABCD; 00279 #endif 00280 #ifdef IEEE802154_PANADDR 00281 uint16_t eemem_panaddr EEMEM = IEEE802154_PANADDR; 00282 #else 00283 uint16_t eemem_panaddr EEMEM = 0; 00284 #endif 00285 #ifdef RF230_MAX_TX_POWER 00286 uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER; 00287 #else 00288 uint8_t eemem_txpower EEMEM = 0; 00289 #endif 00290 static uint8_t get_channel_from_eeprom() { 00291 uint8_t x[2]; 00292 *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel); 00293 if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit 00294 /* Verification fails, rewrite everything */ 00295 uint8_t mac[8]; 00296 #if JACKDAW_CONF_RANDOM_MAC 00297 PRINTA("Generating random MAC address.\n"); 00298 generate_new_eui64(&mac); 00299 #else 00300 {uint8_t i; for (i=0;i<8;i++) mac[i] = pgm_read_byte_near(default_mac_address+i);} 00301 #endif 00302 eeprom_write_block(&mac, &eemem_mac_address, 8); 00303 eeprom_write_word(&eemem_panid , pgm_read_word_near(&default_panid)); 00304 eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr)); 00305 eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower)); 00306 x[0] = pgm_read_byte_near(&default_channel); 00307 x[1]= ~x[0]; 00308 eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x); 00309 } 00310 return x[0]; 00311 } 00312 static bool get_eui64_from_eeprom(uint8_t macptr[8]) { 00313 eeprom_read_block ((void *)macptr, &eemem_mac_address, 8); 00314 return macptr[0]!=0xFF; 00315 } 00316 static uint16_t get_panid_from_eeprom(void) { 00317 return eeprom_read_word(&eemem_panid); 00318 } 00319 static uint16_t get_panaddr_from_eeprom(void) { 00320 return eeprom_read_word (&eemem_panaddr); 00321 } 00322 static uint8_t get_txpower_from_eeprom(void) 00323 { 00324 return eeprom_read_byte(&eemem_txpower); 00325 } 00326 00327 #else /* !JACKDAW_CONF_USE_SETTINGS */ 00328 /******************************Settings manager******************************/ 00329 static uint8_t get_channel_from_eeprom() { 00330 uint8_t x = settings_get_uint8(SETTINGS_KEY_CHANNEL, 0); 00331 if(!x) x = pgm_read_byte_near(&default_channel); 00332 return x; 00333 } 00334 static bool get_eui64_from_eeprom(uint8_t macptr[8]) { 00335 size_t size = 8; 00336 if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)macptr, &size)==SETTINGS_STATUS_OK) { 00337 PRINTD("<=Get EEPROM MAC address.\n"); 00338 return true; 00339 } 00340 #if JACKDAW_CONF_RANDOM_MAC 00341 PRINTA("--Generating random MAC address.\n"); 00342 generate_new_eui64(macptr); 00343 #else 00344 {uint8_t i;for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);} 00345 #endif 00346 settings_add(SETTINGS_KEY_EUI64,(unsigned char*)macptr,8); 00347 PRINTA("->Set EEPROM MAC address.\n"); 00348 return true; 00349 } 00350 static uint16_t get_panid_from_eeprom(void) { 00351 uint16_t x; 00352 if (settings_check(SETTINGS_KEY_PAN_ID,0)) { 00353 x = settings_get_uint16(SETTINGS_KEY_PAN_ID,0); 00354 PRINTD("<-Get EEPROM PAN ID of %04x.\n",x); 00355 } else { 00356 x=pgm_read_word_near(&default_panid); 00357 if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) { 00358 PRINTA("->Set EEPROM PAN ID to %04x.\n",x); 00359 } 00360 } 00361 return x; 00362 } 00363 static uint16_t get_panaddr_from_eeprom(void) { 00364 uint16_t x; 00365 if (settings_check(SETTINGS_KEY_PAN_ADDR,0)) { 00366 x = settings_get_uint16(SETTINGS_KEY_PAN_ADDR,0); 00367 PRINTD("<-Get EEPROM PAN address of %04x.\n",x); 00368 } else { 00369 x=pgm_read_word_near(&default_panaddr); 00370 if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) { 00371 PRINTA("->Set EEPROM PAN address to %04x.\n",x); 00372 } 00373 } 00374 return x; 00375 } 00376 static uint8_t get_txpower_from_eeprom(void) { 00377 uint8_t x; 00378 if (settings_check(SETTINGS_KEY_TXPOWER,0)) { 00379 x = settings_get_uint8(SETTINGS_KEY_TXPOWER,0); 00380 PRINTD("<-Get EEPROM tx power of %d. (0=max)\n",x); 00381 } else { 00382 x=pgm_read_byte_near(&default_txpower); 00383 if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) { 00384 PRINTA("->Set EEPROM tx power of %d. (0=max)\n",x); 00385 } 00386 } 00387 return x; 00388 } 00389 #endif /* !JACKDAW_CONF_USE_SETTINGS */ 00390 00391 /*-------------------------------------------------------------------------*/ 00392 /*-----------------------------Low level initialization--------------------*/ 00393 static void initialize(void) { 00394 00395 watchdog_init(); 00396 watchdog_start(); 00397 00398 #if CONFIG_STACK_MONITOR 00399 /* Simple stack pointer highwater monitor. The 'm' command in cdc_task.c 00400 * looks for the first overwritten magic number. 00401 */ 00402 { 00403 extern uint16_t __bss_end; 00404 uint16_t p=(uint16_t)&__bss_end; 00405 do { 00406 *(uint16_t *)p = 0x4242; 00407 p+=100; 00408 } while (p<SP-100); //don't overwrite our own stack 00409 } 00410 #endif 00411 00412 /* Initialize hardware */ 00413 // Checks for "finger", jumps to DFU if present. 00414 init_lowlevel(); 00415 00416 /* Clock */ 00417 clock_init(); 00418 00419 /* Leds are referred to by number to prevent any possible confusion :) */ 00420 /* Led0 Blue Led1 Red Led2 Green Led3 Yellow */ 00421 Leds_init(); 00422 Led1_on(); 00423 00424 /* Get a random (or probably different) seed for the 802.15.4 packet sequence number. 00425 * Some layers will ignore duplicates found in a history (e.g. Contikimac) 00426 * causing the initial packets to be ignored after a short-cycle restart. 00427 */ 00428 ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference. 00429 ADCSRA=1<<ADEN; //Enable ADC, not free running, interrupt disabled, fastest clock 00430 ADCSRA|=1<<ADSC; //Start conversion 00431 while (ADCSRA&(1<<ADSC)); //Wait till done 00432 PRINTD("ADC=%d\n",ADC); 00433 random_init(ADC); 00434 ADCSRA=0; //Disable ADC 00435 00436 #if USB_CONF_RS232 00437 /* Use rs232 port for serial out (tx, rx, gnd are the three pads behind jackdaw leds */ 00438 rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); 00439 /* Redirect stdout to second port */ 00440 rs232_redirect_stdout(RS232_PORT_0); 00441 #if ANNOUNCE 00442 PRINTA("\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); 00443 #endif 00444 #endif 00445 00446 /* rtimer init needed for low power protocols */ 00447 rtimer_init(); 00448 00449 /* Process subsystem. */ 00450 process_init(); 00451 00452 /* etimer process must be started before USB or ctimer init */ 00453 process_start(&etimer_process, NULL); 00454 00455 Led2_on(); 00456 /* Now we can start USB enumeration */ 00457 process_start(&usb_process, NULL); 00458 00459 /* Start CDC enumeration, bearing in mind that it may fail */ 00460 /* Hopefully we'll get a stdout for startup messages, if we don't already */ 00461 #if USB_CONF_SERIAL 00462 process_start(&cdc_process, NULL); 00463 {unsigned short i; 00464 for (i=0;i<65535;i++) { 00465 process_run(); 00466 watchdog_periodic(); 00467 if (stdout) break; 00468 } 00469 #if !USB_CONF_RS232 00470 PRINTA("\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); 00471 #endif 00472 } 00473 #endif 00474 if (!stdout) Led3_on(); 00475 00476 #if RF230BB 00477 #if JACKDAW_CONF_USE_SETTINGS 00478 PRINTA("Settings manager will be used.\n"); 00479 #else 00480 {uint8_t x[2]; 00481 *(uint16_t *)x = eeprom_read_word((uint16_t *)&eemem_channel); 00482 if((uint8_t)x[0]!=(uint8_t)~x[1]) { 00483 PRINTA("Invalid EEPROM settings detected. Rewriting with default values.\n"); 00484 get_channel_from_eeprom(); 00485 } 00486 } 00487 #endif 00488 00489 ctimer_init(); 00490 /* Start radio and radio receive process */ 00491 /* Note this starts RF230 process, so must be done after process_init */ 00492 NETSTACK_RADIO.init(); 00493 00494 /* Set addresses BEFORE starting tcpip process */ 00495 00496 memset(&tmp_addr, 0, sizeof(rimeaddr_t)); 00497 00498 if(get_eui64_from_eeprom(tmp_addr.u8)); 00499 00500 //Fix MAC address 00501 init_net(); 00502 00503 #if UIP_CONF_IPV6 00504 memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8); 00505 #endif 00506 00507 rf230_set_pan_addr( 00508 get_panid_from_eeprom(), 00509 get_panaddr_from_eeprom(), 00510 (uint8_t *)&tmp_addr.u8 00511 ); 00512 00513 rf230_set_channel(get_channel_from_eeprom()); 00514 rf230_set_txpower(get_txpower_from_eeprom()); 00515 00516 rimeaddr_set_node_addr(&tmp_addr); 00517 00518 /* Initialize stack protocols */ 00519 queuebuf_init(); 00520 NETSTACK_RDC.init(); 00521 NETSTACK_MAC.init(); 00522 NETSTACK_NETWORK.init(); 00523 00524 #if ANNOUNCE 00525 PRINTA("MAC address %x:%x:%x:%x:%x:%x:%x:%x\n\r",tmp_addr.u8[0],tmp_addr.u8[1],tmp_addr.u8[2],tmp_addr.u8[3],tmp_addr.u8[4],tmp_addr.u8[5],tmp_addr.u8[6],tmp_addr.u8[7]); 00526 PRINTA("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); 00527 if (NETSTACK_RDC.channel_check_interval) { 00528 unsigned short tmp; 00529 tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\ 00530 NETSTACK_RDC.channel_check_interval()); 00531 if (tmp<65535) PRINTA(", check rate %u Hz",tmp); 00532 } 00533 PRINTA("\n"); 00534 #endif 00535 00536 #if UIP_CONF_IPV6_RPL 00537 #if RPL_BORDER_ROUTER 00538 process_start(&tcpip_process, NULL); 00539 process_start(&border_router_process, NULL); 00540 PRINTD ("RPL Border Router Started\n"); 00541 #else 00542 process_start(&tcpip_process, NULL); 00543 PRINTD ("RPL Started\n"); 00544 #endif 00545 #if RPL_HTTPD_SERVER 00546 extern struct process httpd_process; 00547 process_start(&httpd_process, NULL); 00548 PRINTD ("Webserver Started\n"); 00549 #endif 00550 #endif /* UIP_CONF_IPV6_RPL */ 00551 00552 #else /* RF230BB */ 00553 /* The order of starting these is important! */ 00554 process_start(&mac_process, NULL); 00555 process_start(&tcpip_process, NULL); 00556 #endif /* RF230BB */ 00557 00558 /* Start ethernet network and storage process */ 00559 process_start(&usb_eth_process, NULL); 00560 #if USB_CONF_STORAGE 00561 process_start(&storage_process, NULL); 00562 #endif 00563 00564 /* Autostart other processes */ 00565 /* There are none in the default build so autostart_processes will be unresolved in the link. */ 00566 /* The AUTOSTART_PROCESSES macro which defines it can only be used in the .co module. */ 00567 /* See /examples/ravenusbstick/ravenusb.c for an autostart template. */ 00568 #if 0 00569 autostart_start(autostart_processes); 00570 #endif 00571 00572 #if ANNOUNCE 00573 #if USB_CONF_RS232 00574 PRINTA("Online.\n"); 00575 #else 00576 PRINTA("Online. Type ? for Jackdaw menu.\n"); 00577 #endif 00578 #endif 00579 00580 Leds_off(); 00581 } 00582 00583 /*-------------------------------------------------------------------------*/ 00584 /*---------------------------------Main Routine----------------------------*/ 00585 int 00586 main(void) 00587 { 00588 /* GCC depends on register r1 set to 0 (?) */ 00589 asm volatile ("clr r1"); 00590 00591 /* Initialize in a subroutine to maximize stack space */ 00592 initialize(); 00593 00594 #if DEBUG 00595 {struct process *p; 00596 for(p = PROCESS_LIST();p != NULL; p = ((struct process *)p->next)) { 00597 PRINTA("Process=%p Thread=%p Name=\"%s\" \n",p,p->thread,PROCESS_NAME_STRING(p)); 00598 } 00599 } 00600 #endif 00601 00602 while(1) { 00603 process_run(); 00604 00605 watchdog_periodic(); 00606 00607 /* Print rssi of all received packets, useful for range testing */ 00608 #ifdef RF230_MIN_RX_POWER 00609 uint8_t lastprint; 00610 if (rf230_last_rssi != lastprint) { //can be set in halbb.c interrupt routine 00611 PRINTA("%u ",rf230_last_rssi); 00612 lastprint=rf230_last_rssi; 00613 } 00614 #endif 00615 00616 #if 0 00617 /* Clock.c can trigger a periodic PLL calibration in the RF230BB driver. 00618 * This can show when that happens. 00619 */ 00620 extern uint8_t rf230_calibrated; 00621 if (rf230_calibrated) { 00622 PRINTA("\nRF230 calibrated!\n"); 00623 rf230_calibrated=0; 00624 } 00625 #endif 00626 00627 #if TESTRTIMER 00628 /* Timeout can be increased up to 8 seconds maximum. 00629 * A one second cycle is convenient for triggering the various debug printouts. 00630 * The triggers are staggered to avoid printing everything at once. 00631 * My Jackdaw is 4% slow. 00632 */ 00633 if (rtimerflag) { 00634 rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL); 00635 rtimerflag=0; 00636 00637 #if STAMPS 00638 if ((rtime%STAMPS)==0) { 00639 PRINTA("%us ",rtime); 00640 if (rtime%STAMPS*10) PRINTA("\n"); 00641 } 00642 #endif 00643 rtime+=1; 00644 00645 #if PINGS && UIP_CONF_IPV6_RPL 00646 extern void raven_ping6(void); 00647 if ((rtime%PINGS)==1) { 00648 PRINTA("**Ping\n"); 00649 raven_ping6(); 00650 } 00651 #endif 00652 00653 #if ROUTES && UIP_CONF_IPV6_RPL 00654 if ((rtime%ROUTES)==2) { 00655 00656 extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; 00657 extern uip_ds6_route_t uip_ds6_routing_table[]; 00658 extern uip_ds6_netif_t uip_ds6_if; 00659 00660 uint8_t i,j; 00661 PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); 00662 for (i=0;i<UIP_DS6_ADDR_NB;i++) { 00663 if (uip_ds6_if.addr_list[i].isused) { 00664 uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); 00665 PRINTA("\n"); 00666 } 00667 } 00668 PRINTA("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB); 00669 for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) { 00670 if(uip_ds6_nbr_cache[i].isused) { 00671 uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr); 00672 PRINTA("\n"); 00673 j=0; 00674 } 00675 } 00676 if (j) PRINTA(" <none>"); 00677 PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); 00678 for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { 00679 if(uip_ds6_routing_table[i].isused) { 00680 uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr); 00681 PRINTA("/%u (via ", uip_ds6_routing_table[i].length); 00682 uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop); 00683 // if(uip_ds6_routing_table[i].state.lifetime < 600) { 00684 PRINTA(") %lus\n", uip_ds6_routing_table[i].state.lifetime); 00685 // } else { 00686 // PRINTA(")\n"); 00687 // } 00688 j=0; 00689 } 00690 } 00691 if (j) PRINTA(" <none>"); 00692 PRINTA("\n---------\n"); 00693 } 00694 #endif 00695 00696 #if STACKMONITOR && CONFIG_STACK_MONITOR 00697 if ((rtime%STACKMONITOR)==3) { 00698 extern uint16_t __bss_end; 00699 uint16_t p=(uint16_t)&__bss_end; 00700 do { 00701 if (*(uint16_t *)p != 0x4242) { 00702 PRINTA("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); 00703 break; 00704 } 00705 p+=100; 00706 } while (p<RAMEND-10); 00707 } 00708 #endif 00709 00710 } 00711 #endif /* TESTRTIMER */ 00712 00713 //Use with RF230BB DEBUGFLOW to show path through driver 00714 #if RF230BB&&0 00715 extern uint8_t debugflowsize,debugflow[]; //in rf230bb.c 00716 if (debugflowsize) { 00717 debugflow[debugflowsize]=0; 00718 PRINTA("%s",debugflow); 00719 debugflowsize=0; 00720 } 00721 #endif 00722 00723 } 00724 return 0; 00725 }