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