contiki-z1-main.c

00001 /*
00002  * Copyright (c) 2006, Swedish Institute of Computer Science
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  * @(#)$Id: contiki-z1-main.c,v 1.4 2010/08/26 22:08:11 nifi Exp $
00030  */
00031 
00032 #include <signal.h>
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <stdarg.h> 
00036 
00037 #include <io.h>
00038 
00039 #include "contiki.h"
00040 
00041 #include "dev/cc2420.h"
00042 #include "dev/leds.h"
00043 #include "dev/serial-line.h"
00044 #include "dev/slip.h"
00045 #include "dev/uart0.h"
00046 #include "dev/watchdog.h"
00047 #include "dev/xmem.h"
00048 #include "lib/random.h"
00049 #include "net/netstack.h"
00050 #include "net/mac/frame802154.h"
00051 #include "dev/button-sensor.h"
00052 
00053 #if WITH_UIP6
00054 #include "net/uip-ds6.h"
00055 #endif /* WITH_UIP6 */
00056 
00057 #include "net/rime.h"
00058 
00059 #include "node-id.h"
00060 #include "cfs-coffee-arch.h"
00061 #include "cfs/cfs-coffee.h"
00062 #include "sys/autostart.h"
00063 #include "sys/profile.h"
00064 
00065 
00066 #include "dev/battery-sensor.h"
00067 #include "dev/button-sensor.h"
00068 #include "dev/sht11-sensor.h"
00069 
00070 SENSORS(&button_sensor);
00071 
00072 
00073 #if DCOSYNCH_CONF_ENABLED
00074 static struct timer mgt_timer;
00075 #endif
00076 
00077 #ifndef WITH_UIP
00078 #define WITH_UIP 0
00079 #endif
00080 
00081 #if WITH_UIP
00082 #include "net/uip.h"
00083 #include "net/uip-fw.h"
00084 #include "net/uip-fw-drv.h"
00085 #include "net/uip-over-mesh.h"
00086 static struct uip_fw_netif slipif =
00087   {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)};
00088 static struct uip_fw_netif meshif =
00089   {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
00090 
00091 #endif /* WITH_UIP */
00092 
00093 #define UIP_OVER_MESH_CHANNEL 8
00094 #if WITH_UIP
00095 static uint8_t is_gateway;
00096 #endif /* WITH_UIP */
00097 
00098 #ifdef EXPERIMENT_SETUP
00099 #include "experiment-setup.h"
00100 #endif
00101 
00102 #define DEBUG 1
00103 #if DEBUG
00104 #include <stdio.h>
00105 #define PRINTF(...) printf(__VA_ARGS__)
00106 #else
00107 #define PRINTF(...)
00108 #endif
00109 
00110 void init_platform(void);
00111 
00112 /*---------------------------------------------------------------------------*/
00113 #if 0
00114 int
00115 force_float_inclusion()
00116 {
00117   extern int __fixsfsi;
00118   extern int __floatsisf;
00119   extern int __mulsf3;
00120   extern int __subsf3;
00121 
00122   return __fixsfsi + __floatsisf + __mulsf3 + __subsf3;
00123 }
00124 #endif
00125 /*---------------------------------------------------------------------------*/
00126 void uip_log(char *msg) { puts(msg); }
00127 /*---------------------------------------------------------------------------*/
00128 #ifndef RF_CHANNEL
00129 #define RF_CHANNEL              26
00130 #endif
00131 /*---------------------------------------------------------------------------*/
00132 #if 0
00133 void
00134 force_inclusion(int d1, int d2)
00135 {
00136   snprintf(NULL, 0, "%d", d1 % d2);
00137 }
00138 #endif
00139 /*---------------------------------------------------------------------------*/
00140 static void
00141 set_rime_addr(void)
00142 {
00143   rimeaddr_t addr;
00144   int i;
00145 
00146   memset(&addr, 0, sizeof(rimeaddr_t));
00147 #if UIP_CONF_IPV6
00148   memcpy(addr.u8, node_mac, sizeof(addr.u8));
00149 #else
00150   if(node_id == 0) {
00151     for(i = 0; i < sizeof(rimeaddr_t); ++i) {
00152       addr.u8[i] = node_mac[7 - i];
00153     }
00154   } else {
00155     addr.u8[0] = node_id & 0xff;
00156     addr.u8[1] = node_id >> 8;
00157   }
00158 #endif
00159   rimeaddr_set_node_addr(&addr);
00160   printf("Rime started with address ");
00161   for(i = 0; i < sizeof(addr.u8) - 1; i++) {
00162     printf("%d.", addr.u8[i]);
00163   }
00164   printf("%d\n", addr.u8[i]);
00165 }
00166 /*---------------------------------------------------------------------------*/
00167 static void
00168 print_processes(struct process * const processes[])
00169 {
00170   /*  const struct process * const * p = processes;*/
00171   printf("Starting");
00172   while(*processes != NULL) {
00173     printf(" '%s'", (*processes)->name);
00174     processes++;
00175   }
00176   putchar('\n');
00177 }
00178 /*--------------------------------------------------------------------------*/
00179 #if WITH_UIP
00180 static void
00181 set_gateway(void)
00182 {
00183   if(!is_gateway) {
00184     leds_on(LEDS_RED);
00185     printf("%d.%d: making myself the IP network gateway.\n\n",
00186            rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00187     printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
00188            uip_ipaddr_to_quad(&uip_hostaddr));
00189     uip_over_mesh_set_gateway(&rimeaddr_node_addr);
00190     uip_over_mesh_make_announced_gateway();
00191     is_gateway = 1;
00192   }
00193 }
00194 #endif /* WITH_UIP */
00195 /*---------------------------------------------------------------------------*/
00196 int
00197 main(int argc, char **argv)
00198 {
00199   /*
00200    * Initalize hardware.
00201    */
00202   msp430_cpu_init();
00203   clock_init();
00204   leds_init();
00205   leds_on(LEDS_RED);
00206 
00207   clock_wait(100);
00208 
00209   uart0_init(BAUD2UBR(115200)); /* Must come before first printf */
00210 #if WITH_UIP
00211   slip_arch_init(BAUD2UBR(115200));
00212 #endif /* WITH_UIP */
00213 
00214     
00215   xmem_init();
00216 
00217   rtimer_init();
00218   /*
00219    * Hardware initialization done!
00220    */
00221 
00222   /* Restore node id if such has been stored in external mem */
00223   node_id_restore();
00224 
00225   /* Overwrite node MAC if desired at compile time */
00226 #ifdef MACID 
00227   #warning "***** CHANGING DEFAULT MAC *****"
00228   node_mac[0] = 0xC1;  // Hardcoded for Z1
00229   node_mac[1] = 0x0C;  // Hardcoded for Revision C
00230   node_mac[2] = 0x00;  // Hardcoded to arbitrary even number so that the 802.15.4 MAC address 
00231                        // is compatible with an Ethernet MAC address - byte 0 (byte 2 in the DS ID)
00232   node_mac[3] = 0x00;  // Hardcoded 
00233   node_mac[4] = 0x00;  // Hardcoded 
00234   node_mac[5] = 0x00;  // Hardcoded
00235   node_mac[6] = MACID >> 8;
00236   node_mac[7] = MACID & 0xff;
00237 #endif
00238 
00239 
00240   /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */
00241 #ifdef IEEE_802154_MAC_ADDRESS
00242   {
00243     uint8_t ieee[] = IEEE_802154_MAC_ADDRESS;
00244     memcpy(node_mac, ieee, sizeof(uip_lladdr.addr));
00245     node_mac[7] = node_id & 0xff;
00246   }
00247 #endif
00248 
00249   
00250    /*
00251    * Initialize Contiki and our processes.
00252    */
00253   process_init();
00254   process_start(&etimer_process, NULL);
00255 
00256   ctimer_init();
00257 
00258   init_platform(); 
00259 
00260   set_rime_addr();
00261 
00262   cc2420_init();
00263   accm_init();
00264 
00265   {
00266     uint8_t longaddr[8];
00267     uint16_t shortaddr;
00268     
00269     shortaddr = (rimeaddr_node_addr.u8[0] << 8) +
00270       rimeaddr_node_addr.u8[1];
00271     memset(longaddr, 0, sizeof(longaddr));
00272     rimeaddr_copy((rimeaddr_t *)&longaddr, &rimeaddr_node_addr);
00273     printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
00274            longaddr[0], longaddr[1], longaddr[2], longaddr[3],
00275            longaddr[4], longaddr[5], longaddr[6], longaddr[7]);
00276     
00277     cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr);
00278   }
00279   cc2420_set_channel(RF_CHANNEL);
00280 
00281   leds_off(LEDS_ALL);
00282 
00283   PRINTF(CONTIKI_VERSION_STRING " started. ");
00284 
00285   if(node_id > 0) {
00286     PRINTF("Node id is set to %u.\n", node_id);
00287   } else {
00288     PRINTF("Node id is not set.\n");
00289   }
00290 
00291 
00292 #if WITH_UIP6
00293   memcpy(&uip_lladdr.addr, node_mac, sizeof(uip_lladdr.addr));
00294   /* Setup nullmac-like MAC for 802.15.4 */
00295 /*   sicslowpan_init(sicslowmac_init(&cc2420_driver)); */
00296 /*   printf(" %s channel %u\n", sicslowmac_driver.name, RF_CHANNEL); */
00297 
00298   /* Setup X-MAC for 802.15.4 */
00299   queuebuf_init();
00300 
00301   NETSTACK_RDC.init();
00302   NETSTACK_MAC.init();
00303   NETSTACK_NETWORK.init();
00304 
00305   printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
00306          NETSTACK_MAC.name, NETSTACK_RDC.name,
00307          CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
00308                          NETSTACK_RDC.channel_check_interval()),
00309          RF_CHANNEL);
00310 
00311   process_start(&tcpip_process, NULL);
00312 
00313   printf("Tentative link-local IPv6 address ");
00314   {
00315     uip_ds6_addr_t *lladdr;
00316     int i;
00317     lladdr = uip_ds6_get_link_local(-1);
00318     for(i = 0; i < 7; ++i) {
00319       printf("%02x%02x:", lladdr->ipaddr.u8[i * 2],
00320              lladdr->ipaddr.u8[i * 2 + 1]);
00321     }
00322     printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
00323   }
00324   
00325   if(!UIP_CONF_IPV6_RPL) {
00326     uip_ipaddr_t ipaddr;
00327     int i;
00328     uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
00329     uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
00330     uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
00331     printf("Tentative global IPv6 address ");
00332     for(i = 0; i < 7; ++i) {
00333       printf("%02x%02x:",
00334              ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
00335     }
00336     printf("%02x%02x\n",
00337            ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
00338   }
00339 
00340 #else /* WITH_UIP6 */
00341 
00342   NETSTACK_RDC.init();
00343   NETSTACK_MAC.init();
00344   NETSTACK_NETWORK.init();
00345 
00346   printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
00347          NETSTACK_MAC.name, NETSTACK_RDC.name,
00348          CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1:
00349                          NETSTACK_RDC.channel_check_interval()),
00350          RF_CHANNEL);
00351 #endif /* WITH_UIP6 */
00352 
00353 #if !WITH_UIP && !WITH_UIP6
00354   uart0_set_input(serial_line_input_byte);
00355   serial_line_init();
00356 #endif
00357 
00358 #if PROFILE_CONF_ON
00359   profile_init();
00360 #endif /* PROFILE_CONF_ON */
00361 
00362   leds_off(LEDS_GREEN);
00363 
00364 #if TIMESYNCH_CONF_ENABLED
00365   timesynch_init();
00366   timesynch_set_authority_level(rimeaddr_node_addr.u8[0]);
00367 #endif /* TIMESYNCH_CONF_ENABLED */
00368 
00369 #if WITH_UIP
00370   process_start(&tcpip_process, NULL);
00371   process_start(&uip_fw_process, NULL); /* Start IP output */
00372   process_start(&slip_process, NULL);
00373 
00374   slip_set_input_callback(set_gateway);
00375 
00376   {
00377     uip_ipaddr_t hostaddr, netmask;
00378 
00379     uip_init();
00380 
00381     uip_ipaddr(&hostaddr, 172,16,
00382                rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
00383     uip_ipaddr(&netmask, 255,255,0,0);
00384     uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
00385 
00386     uip_sethostaddr(&hostaddr);
00387     uip_setnetmask(&netmask);
00388     uip_over_mesh_set_net(&hostaddr, &netmask);
00389     /*    uip_fw_register(&slipif);*/
00390     uip_over_mesh_set_gateway_netif(&slipif);
00391     uip_fw_default(&meshif);
00392     uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
00393     printf("uIP started with IP address %d.%d.%d.%d\n",
00394            uip_ipaddr_to_quad(&hostaddr));
00395   }
00396 #endif /* WITH_UIP */
00397 
00398   energest_init();
00399   ENERGEST_ON(ENERGEST_TYPE_CPU);
00400 
00401   print_processes(autostart_processes);
00402   autostart_start(autostart_processes);
00403 
00404   /*
00405    * This is the scheduler loop.
00406    */
00407 #if DCOSYNCH_CONF_ENABLED
00408   timer_set(&mgt_timer, DCOSYNCH_PERIOD * CLOCK_SECOND);
00409 #endif
00410   watchdog_start();
00411   /*  watchdog_stop();*/
00412   while(1) {
00413     int r;
00414 #if PROFILE_CONF_ON
00415     profile_episode_start();
00416 #endif /* PROFILE_CONF_ON */
00417     do {
00418       /* Reset watchdog. */
00419       watchdog_periodic();
00420       r = process_run();
00421     } while(r > 0);
00422 #if PROFILE_CONF_ON
00423     profile_episode_end();
00424 #endif /* PROFILE_CONF_ON */
00425 
00426     /*
00427      * Idle processing.
00428      */
00429     int s = splhigh();          /* Disable interrupts. */
00430     /* uart0_active is for avoiding LPM3 when still sending or receiving */
00431     if(process_nevents() != 0 || uart0_active()) {
00432       splx(s);                  /* Re-enable interrupts. */
00433     } else {
00434       static unsigned long irq_energest = 0;
00435 
00436 #if DCOSYNCH_CONF_ENABLED
00437       /* before going down to sleep possibly do some management */
00438       if (timer_expired(&mgt_timer)) {
00439         timer_reset(&mgt_timer);
00440         msp430_sync_dco();
00441       }
00442 #endif
00443 
00444       /* Re-enable interrupts and go to sleep atomically. */
00445       ENERGEST_OFF(ENERGEST_TYPE_CPU);
00446       ENERGEST_ON(ENERGEST_TYPE_LPM);
00447       /* We only want to measure the processing done in IRQs when we
00448          are asleep, so we discard the processing time done when we
00449          were awake. */
00450       energest_type_set(ENERGEST_TYPE_IRQ, irq_energest);
00451       watchdog_stop();
00452       _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This
00453                                               statement will block
00454                                               until the CPU is
00455                                               woken up by an
00456                                               interrupt that sets
00457                                               the wake up flag. */
00458 
00459       /* We get the current processing time for interrupts that was
00460          done during the LPM and store it for next time around.  */
00461       dint();
00462       irq_energest = energest_type_time(ENERGEST_TYPE_IRQ);
00463       eint();
00464       watchdog_start();
00465       ENERGEST_OFF(ENERGEST_TYPE_LPM);
00466       ENERGEST_ON(ENERGEST_TYPE_CPU);
00467     }
00468   }
00469 
00470   return 0;
00471 }
00472 /*---------------------------------------------------------------------------*/
00473 #if LOG_CONF_ENABLED
00474 void
00475 log_message(char *m1, char *m2)
00476 {
00477   printf("%s%s\n", m1, m2);
00478 }
00479 #endif /* LOG_CONF_ENABLED */
00480 

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