contiki-raven-main.c

Go to the documentation of this file.
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 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((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  //   rpl_set_prefix(rpl_get_dag(RPL_ANY_INSTANCE), &ipaddr, 64);
00196  //   rpl_repair_dag(rpl_get_dag(RPL_ANY_INSTANCE));
00197 
00198   }
00199 
00200   PROCESS_END();
00201 }
00202 #endif /* RPL_BORDER_ROUTER */
00203 
00204 #endif /* UIP_CONF_IPV6_RPL */
00205 
00206 /*-------------------------------------------------------------------------*/
00207 /*----------------------Configuration of the .elf file---------------------*/
00208 #if 1
00209 /* The proper way to set the signature is */
00210 #include <avr/signature.h>
00211 #else
00212 /* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */
00213 typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t;
00214 #define SIGNATURE __signature_t __signature __attribute__((section (".signature")))
00215 SIGNATURE = {
00216   .B2 = 0x82,//SIGNATURE_2, //AT90USB128x
00217   .B1 = 0x97,//SIGNATURE_1, //128KB flash
00218   .B0 = 0x1E,//SIGNATURE_0, //Atmel
00219 };
00220 #endif
00221 
00222 FUSES ={.low = 0xde, .high = 0x99, .extended = 0xff,};
00223 
00224 /* Save the default settings into program flash memory */
00225 uint8_t default_mac_address[8] PROGMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
00226 #ifdef CHANNEL_802_15_4
00227 uint8_t default_channel PROGMEM = CHANNEL_802_15_4;
00228 #else
00229 uint8_t default_channel PROGMEM = 26;
00230 #endif
00231 #ifdef IEEE802154_PANID
00232 uint16_t default_panid PROGMEM = IEEE802154_PANID;
00233 #else
00234 uint16_t default_panid PROGMEM = 0xABCD;
00235 #endif
00236 #ifdef IEEE802154_PANADDR
00237 uint16_t default_panaddr PROGMEM = IEEE802154_PANID;
00238 #else
00239 uint16_t default_panaddr PROGMEM = 0;
00240 #endif
00241 #ifdef RF230_MAX_TX_POWER
00242 uint8_t default_txpower PROGMEM = RF230_MAX_TX_POWER;
00243 #else
00244 uint8_t default_txpower PROGMEM = 0;
00245 #endif
00246 
00247 #if JACKDAW_CONF_RANDOM_MAC
00248 #include "rng.h"
00249 static void
00250 generate_new_eui64(uint8_t eui64[8]) {
00251         eui64[0] = 0x02;
00252         eui64[1] = rng_get_uint8();
00253         eui64[2] = rng_get_uint8();
00254         eui64[3] = 0xFF;
00255         eui64[4] = 0xFE;
00256         eui64[5] = rng_get_uint8();
00257         eui64[6] = rng_get_uint8();
00258         eui64[7] = rng_get_uint8();
00259 }
00260 #endif /* JACKDAW_CONF_RANDOM_MAC */
00261 
00262 #if !JACKDAW_CONF_USE_SETTINGS
00263 /****************************No settings manager*****************************/
00264 /* If not using the settings manager, put the default values into EEMEM
00265  * These can be manually changed and kept over program reflash.
00266  * The channel and bit complement are used to check EEMEM integrity,
00267  * If corrupt all values will be rewritten with the default flash values.
00268  * To make this work, get the channel before anything else.
00269  */
00270 
00271 uint8_t eemem_mac_address[8] EEMEM = {0x02, 0x12, 0x13, 0xff, 0xfe, 0x14, 0x15, 0x16};
00272 #ifdef CHANNEL_802_15_4
00273 uint8_t eemem_channel[2] EEMEM = {CHANNEL_802_15_4, ~CHANNEL_802_15_4};
00274 #else
00275 uint8_t eemem_channel[2] EMEM = {26, ~26};
00276 #endif
00277 #ifdef IEEE802154_PANID
00278 uint16_t eemem_panid EEMEM = IEEE802154_PANID;
00279 #else
00280 uint16_t eemem_panid EEMEM = 0xABCD;
00281 #endif
00282 #ifdef IEEE802154_PANADDR
00283 uint16_t eemem_panaddr EEMEM = IEEE802154_PANID;
00284 #else
00285 uint16_t eemem_panaddr EEMEM = 0;
00286 #endif
00287 #ifdef RF230_MAX_TX_POWER
00288 uint8_t eemem_txpower EEMEM = RF230_MAX_TX_POWER;
00289 #else
00290 uint8_t eemem_txpower EEMEM = 0;
00291 #endif
00292 static uint8_t get_channel_from_eeprom() {
00293         uint8_t x[2];
00294         *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
00295     if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit
00296 /* Verification fails, rewrite everything */
00297     uint8_t mac[8];
00298 #if JACKDAW_CONF_RANDOM_MAC
00299     PRINTA("Generating random MAC address.\n");
00300     generate_new_eui64(&mac);
00301 #else
00302     {uint8_t i; for (i=0;i<8;i++) mac[i] = pgm_read_byte_near(default_mac_address+i);}
00303 #endif
00304         eeprom_write_block(&mac,  &eemem_mac_address, 8);
00305         eeprom_write_word(&eemem_panid  , pgm_read_word_near(&default_panid));
00306         eeprom_write_word(&eemem_panaddr, pgm_read_word_near(&default_panaddr));
00307     eeprom_write_byte(&eemem_txpower, pgm_read_byte_near(&default_txpower));
00308     x[0] = pgm_read_byte_near(&default_channel);
00309     x[1]= ~x[0];
00310     eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);    
00311   }
00312   return x[0];
00313 }
00314 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
00315         eeprom_read_block ((void *)macptr, &eemem_mac_address, 8);
00316         return macptr[0]!=0xFF;
00317 }
00318 static uint16_t get_panid_from_eeprom(void) {
00319         return eeprom_read_word(&eemem_panid);
00320 }
00321 static uint16_t get_panaddr_from_eeprom(void) {
00322         return eeprom_read_word (&eemem_panaddr);
00323 }
00324 static uint8_t get_txpower_from_eeprom(void)
00325 {
00326         return eeprom_read_byte(&eemem_txpower);
00327 }
00328 
00329 #else /* !JACKDAW_CONF_USE_SETTINGS */
00330 /******************************Settings manager******************************/
00331 static uint8_t get_channel_from_eeprom() {
00332         uint8_t x = settings_get_uint8(SETTINGS_KEY_CHANNEL, 0);
00333         if(!x) x = pgm_read_byte_near(&default_channel);
00334         return x;
00335 }
00336 static bool get_eui64_from_eeprom(uint8_t macptr[8]) {
00337         size_t size = 8;
00338         if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)macptr, &size)==SETTINGS_STATUS_OK) {
00339       PRINTD("<=Get EEPROM MAC address.\n");
00340       return true;              
00341     }
00342 #if JACKDAW_CONF_RANDOM_MAC
00343     PRINTA("--Generating random MAC address.\n");
00344     generate_new_eui64(macptr);
00345 #else
00346     {uint8_t i;for (i=0;i<8;i++) macptr[i] = pgm_read_byte_near(default_mac_address+i);}
00347 #endif
00348     settings_add(SETTINGS_KEY_EUI64,(unsigned char*)macptr,8);
00349     PRINTA("->Set EEPROM MAC address.\n");
00350         return true;
00351 }
00352 static uint16_t get_panid_from_eeprom(void) {
00353     uint16_t x;
00354     if (settings_check(SETTINGS_KEY_PAN_ID,0)) {
00355         x = settings_get_uint16(SETTINGS_KEY_PAN_ID,0);
00356         PRINTD("<-Get EEPROM PAN ID of %04x.\n",x);
00357     } else {
00358             x=pgm_read_word_near(&default_panid);
00359         if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) {
00360           PRINTA("->Set EEPROM PAN ID to %04x.\n",x);
00361         }
00362     }
00363         return x;
00364 }
00365 static uint16_t get_panaddr_from_eeprom(void) {
00366     uint16_t x;
00367     if (settings_check(SETTINGS_KEY_PAN_ADDR,0)) {
00368         x = settings_get_uint16(SETTINGS_KEY_PAN_ADDR,0);
00369         PRINTD("<-Get EEPROM PAN address of %04x.\n",x);
00370     } else {
00371             x=pgm_read_word_near(&default_panaddr);
00372         if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) {
00373           PRINTA("->Set EEPROM PAN address to %04x.\n",x);
00374         }
00375     }        
00376         return x;
00377 }
00378 static uint8_t get_txpower_from_eeprom(void) {
00379     uint8_t x;
00380     if (settings_check(SETTINGS_KEY_TXPOWER,0)) {
00381         x = settings_get_uint8(SETTINGS_KEY_TXPOWER,0);
00382         PRINTD("<-Get EEPROM tx power of %d. (0=max)\n",x);
00383     } else {
00384             x=pgm_read_byte_near(&default_txpower);
00385         if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) {
00386           PRINTA("->Set EEPROM tx power of %d. (0=max)\n",x);
00387         }
00388     }
00389         return x;
00390 }
00391 #endif /* !JACKDAW_CONF_USE_SETTINGS */
00392 
00393 /*-------------------------------------------------------------------------*/
00394 /*-----------------------------Low level initialization--------------------*/
00395 static void initialize(void) {
00396 
00397   watchdog_init();
00398   watchdog_start();
00399 
00400 #if CONFIG_STACK_MONITOR
00401   /* Simple stack pointer highwater monitor. The 'm' command in cdc_task.c
00402    * looks for the first overwritten magic number.
00403    */
00404 {
00405 extern uint16_t __bss_end;
00406 uint16_t p=(uint16_t)&__bss_end;
00407     do {
00408       *(uint16_t *)p = 0x4242;
00409       p+=100;
00410     } while (p<SP-100); //don't overwrite our own stack
00411 }
00412 #endif
00413 
00414   /* Initialize hardware */
00415   // Checks for "finger", jumps to DFU if present.
00416   init_lowlevel();
00417   
00418   /* Clock */
00419   clock_init();
00420 
00421   /* Leds are referred to by number to prevent any possible confusion :) */
00422   /* Led0 Blue Led1 Red Led2 Green Led3 Yellow */
00423   Leds_init();
00424   Led1_on();
00425   
00426 #if USB_CONF_RS232
00427   /* Use rs232 port for serial out (tx, rx, gnd are the three pads behind jackdaw leds */
00428   rs232_init(RS232_PORT_0, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8);
00429   /* Redirect stdout to second port */
00430   rs232_redirect_stdout(RS232_PORT_0);
00431 #if ANNOUNCE
00432   PRINTA("\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
00433 #endif
00434 #endif
00435         
00436   /* rtimer init needed for low power protocols */
00437   rtimer_init();
00438 
00439   /* Process subsystem. */
00440   process_init();
00441 
00442   /* etimer process must be started before USB or ctimer init */
00443   process_start(&etimer_process, NULL);
00444 
00445   Led2_on();
00446   /* Now we can start USB enumeration */
00447   process_start(&usb_process, NULL);
00448 
00449   /* Start CDC enumeration, bearing in mind that it may fail */
00450   /* Hopefully we'll get a stdout for startup messages, if we don't already */
00451 #if USB_CONF_SERIAL
00452   process_start(&cdc_process, NULL);
00453 {unsigned short i;
00454   for (i=0;i<65535;i++) {
00455     process_run();
00456     watchdog_periodic();
00457     if (stdout) break;
00458   }
00459 #if !USB_CONF_RS232
00460   PRINTA("\n\n*******Booting %s*******\n",CONTIKI_VERSION_STRING);
00461 #endif
00462 }
00463 #endif
00464   if (!stdout) Led3_on();
00465   
00466 #if RF230BB
00467 #if JACKDAW_CONF_USE_SETTINGS
00468   PRINTA("Settings manager will be used.\n");
00469 #else
00470 {uint8_t x[2];
00471         *(uint16_t *)x = eeprom_read_word((uint16_t *)&eemem_channel);
00472         if((uint8_t)x[0]!=(uint8_t)~x[1]) {
00473         PRINTA("Invalid EEPROM settings detected. Rewriting with default values.\n");
00474         get_channel_from_eeprom();
00475     }
00476 }
00477 #endif
00478 
00479   ctimer_init();
00480   /* Start radio and radio receive process */
00481   /* Note this starts RF230 process, so must be done after process_init */
00482   NETSTACK_RADIO.init();
00483 
00484   /* Set addresses BEFORE starting tcpip process */
00485 
00486   memset(&tmp_addr, 0, sizeof(rimeaddr_t));
00487 
00488   if(get_eui64_from_eeprom(tmp_addr.u8));
00489    
00490   //Fix MAC address
00491   init_net();
00492 
00493 #if UIP_CONF_IPV6
00494   memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8);
00495 #endif
00496 
00497   rf230_set_pan_addr(
00498         get_panid_from_eeprom(),
00499         get_panaddr_from_eeprom(),
00500         (uint8_t *)&tmp_addr.u8
00501   );
00502   
00503   rf230_set_channel(get_channel_from_eeprom());
00504   rf230_set_txpower(get_txpower_from_eeprom());
00505 
00506   rimeaddr_set_node_addr(&tmp_addr); 
00507 
00508   /* Initialize stack protocols */
00509   queuebuf_init();
00510   NETSTACK_RDC.init();
00511   NETSTACK_MAC.init();
00512   NETSTACK_NETWORK.init();
00513 
00514 #if ANNOUNCE
00515   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]);
00516   PRINTA("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel());
00517   if (NETSTACK_RDC.channel_check_interval) {
00518     unsigned short tmp;
00519     tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\
00520                         NETSTACK_RDC.channel_check_interval());
00521     if (tmp<65535) PRINTA(", check rate %u Hz",tmp);
00522   }
00523   PRINTA("\n");
00524 #endif
00525 
00526 #if UIP_CONF_IPV6_RPL
00527 #if RPL_BORDER_ROUTER
00528   process_start(&tcpip_process, NULL);
00529   process_start(&border_router_process, NULL);
00530   PRINTD ("RPL Border Router Started\n");
00531 #else
00532   process_start(&tcpip_process, NULL);
00533   PRINTD ("RPL Started\n");
00534 #endif
00535 #if RPL_HTTPD_SERVER
00536   extern struct process httpd_process;
00537   process_start(&httpd_process, NULL);
00538   PRINTD ("Webserver Started\n");
00539 #endif
00540 #endif /* UIP_CONF_IPV6_RPL */
00541 
00542 #else  /* RF230BB */
00543 /* The order of starting these is important! */
00544   process_start(&mac_process, NULL);
00545   process_start(&tcpip_process, NULL);
00546 #endif /* RF230BB */
00547 
00548   /* Start ethernet network and storage process */
00549   process_start(&usb_eth_process, NULL);
00550 #if USB_CONF_STORAGE
00551   process_start(&storage_process, NULL);
00552 #endif
00553 
00554 #if ANNOUNCE
00555 #if USB_CONF_RS232
00556   PRINTA("Online.\n");
00557 #else
00558   PRINTA("Online. Type ? for Jackdaw menu.\n");
00559 #endif
00560 #endif
00561 
00562 Leds_off();
00563 }
00564 
00565 /*-------------------------------------------------------------------------*/
00566 /*---------------------------------Main Routine----------------------------*/
00567 int
00568 main(void)
00569 {
00570   /* GCC depends on register r1 set to 0 (?) */
00571   asm volatile ("clr r1");
00572   
00573   /* Initialize in a subroutine to maximize stack space */
00574   initialize();
00575 
00576 #if DEBUG
00577 {struct process *p;
00578  for(p = PROCESS_LIST();p != NULL; p = ((struct process *)p->next)) {
00579   PRINTA("Process=%p Thread=%p  Name=\"%s\" \n",p,p->thread,PROCESS_NAME_STRING(p));
00580  }
00581 }
00582 #endif
00583 
00584   while(1) {
00585     process_run();
00586 
00587     watchdog_periodic();
00588 
00589 /* Print rssi of all received packets, useful for range testing */
00590 #ifdef RF230_MIN_RX_POWER
00591     uint8_t lastprint;
00592     if (rf230_last_rssi != lastprint) {        //can be set in halbb.c interrupt routine
00593         PRINTA("%u ",rf230_last_rssi);
00594         lastprint=rf230_last_rssi;
00595     }
00596 #endif
00597 
00598 #if 0
00599 /* Clock.c can trigger a periodic PLL calibration in the RF230BB driver.
00600  * This can show when that happens.
00601  */
00602     extern uint8_t rf230_calibrated;
00603     if (rf230_calibrated) {
00604       PRINTA("\nRF230 calibrated!\n");
00605       rf230_calibrated=0;
00606     }
00607 #endif
00608 
00609 #if TESTRTIMER
00610 /* Timeout can be increased up to 8 seconds maximum.
00611  * A one second cycle is convenient for triggering the various debug printouts.
00612  * The triggers are staggered to avoid printing everything at once.
00613  * My Jackdaw is 4% slow.
00614  */
00615     if (rtimerflag) {
00616       rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL);
00617       rtimerflag=0;
00618 
00619 #if STAMPS
00620 if ((rtime%STAMPS)==0) {
00621   PRINTA("%us ",rtime);
00622   if (rtime%STAMPS*10) PRINTA("\n");
00623 }
00624 #endif
00625       rtime+=1;
00626 
00627 #if PINGS && UIP_CONF_IPV6_RPL
00628 extern void raven_ping6(void);
00629 if ((rtime%PINGS)==1) {
00630   PRINTA("**Ping\n");
00631   raven_ping6();
00632 }
00633 #endif
00634 
00635 #if ROUTES && UIP_CONF_IPV6_RPL
00636 if ((rtime%ROUTES)==2) {
00637       
00638 extern uip_ds6_nbr_t uip_ds6_nbr_cache[];
00639 extern uip_ds6_route_t uip_ds6_routing_table[];
00640 extern uip_ds6_netif_t uip_ds6_if;
00641 
00642   uint8_t i,j;
00643   PRINTA("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB);
00644   for (i=0;i<UIP_DS6_ADDR_NB;i++) {
00645     if (uip_ds6_if.addr_list[i].isused) {
00646       uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
00647       PRINTA("\n");
00648     }
00649   }
00650   PRINTA("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB);
00651   for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) {
00652     if(uip_ds6_nbr_cache[i].isused) {
00653       uip_debug_ipaddr_print(&uip_ds6_nbr_cache[i].ipaddr);
00654       PRINTA("\n");
00655       j=0;
00656     }
00657   }
00658   if (j) PRINTA("  <none>");
00659   PRINTA("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB);
00660   for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) {
00661     if(uip_ds6_routing_table[i].isused) {
00662       uip_debug_ipaddr_print(&uip_ds6_routing_table[i].ipaddr);
00663       PRINTA("/%u (via ", uip_ds6_routing_table[i].length);
00664       uip_debug_ipaddr_print(&uip_ds6_routing_table[i].nexthop);
00665  //     if(uip_ds6_routing_table[i].state.lifetime < 600) {
00666         PRINTA(") %lus\n", uip_ds6_routing_table[i].state.lifetime);
00667  //     } else {
00668  //       PRINTA(")\n");
00669  //     }
00670       j=0;
00671     }
00672   }
00673   if (j) PRINTA("  <none>");
00674   PRINTA("\n---------\n");
00675 }
00676 #endif
00677 
00678 #if STACKMONITOR && CONFIG_STACK_MONITOR
00679 if ((rtime%STACKMONITOR)==3) {
00680   extern uint16_t __bss_end;
00681   uint16_t p=(uint16_t)&__bss_end;
00682   do {
00683     if (*(uint16_t *)p != 0x4242) {
00684       PRINTA("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end);
00685       break;
00686     }
00687     p+=100;
00688   } while (p<RAMEND-10);
00689 }
00690 #endif
00691 
00692     }
00693 #endif /* TESTRTIMER */
00694 
00695 //Use with RF230BB DEBUGFLOW to show path through driver
00696 #if RF230BB&&0
00697 extern uint8_t debugflowsize,debugflow[];  //in rf230bb.c
00698   if (debugflowsize) {
00699     debugflow[debugflowsize]=0;
00700     PRINTA("%s",debugflow);
00701     debugflowsize=0;
00702    }
00703 #endif
00704 
00705   }
00706   return 0;
00707 }

Generated on Mon Apr 11 14:23:42 2011 for Contiki 2.5 by  doxygen 1.6.1