Пример #1
0
void tmr0_isr(void) {
	if(bit_is_set(*TMR(0,CSCTRL),TCF1)) {
		current_clock++;
		if((current_clock % CLOCK_CONF_SECOND) == 0) {
			seconds++;

/* ADC can be serviced every tick or every second */
#if CLOCK_CONF_SAMPLEADC > 1
			adc_service();
#endif
		}
#if CLOCK_CONF_SAMPLEADC == 1
		adc_service();
#endif
		if(etimer_pending() &&
		   (etimer_next_expiration_time() - current_clock - 1) > MAX_TICKS) {
 			etimer_request_poll();
 		}


		/* clear the compare flags */
		clear_bit(*TMR(0,SCTRL),TCF);
		clear_bit(*TMR(0,CSCTRL),TCF1);
		clear_bit(*TMR(0,CSCTRL),TCF2);
		return;
	} else {
		/* this timer didn't create an interrupt condition */
		return;
	}
}
Пример #2
0
Java_se_sics_cooja_corecomm_[CLASS_NAME]_tick(JNIEnv *env, jobject obj)
{
  /* Let all simulation interfaces act first */
  simNoYield = 1;
  doActionsBeforeTick();
  simNoYield = 0;

  /* Poll etimer process */
  if (etimer_pending()) {	
    etimer_request_poll();
  }

  /* Let Contiki handle a few events.
  	This call stores the process_run() return value */
  cooja_mt_exec(&process_run_thread);

  /* Let all simulation interfaces act before returning to java */
  simNoYield = 1;
  doActionsAfterTick();
  simNoYield = 0;

  /* Look for new e-timers */
  simEtimerPending = etimer_pending();

  /* Save nearest event timer expiration time */
  if (simEtimerPending) {
    simNextExpirationTime = etimer_next_expiration_time() - simCurrentTime;
  }
}
Java_se_sics_cooja_corecomm_[CLASS_NAME]_tick(JNIEnv *env, jobject obj)
{
  /* Let all simulation interfaces act first */
  simNoYield = 1;
  doActionsBeforeTick();
  simNoYield = 0;

  /* Check if any e-timers are pending (save result for state decisions) */
  if (etimer_pending()) {
    /* Poll etimers */
    etimer_request_poll();
    simEtimerPending = 1;
  } else {
    simEtimerPending = 0;
  }

  /* Let Contiki execute one or a part of the process_run()-function via the thread.
  	This call stores the process_run() return value */
  cooja_mt_exec(&process_run_thread);

  /* Let all simulation interfaces act before returning to java */
  simNoYield = 1;
  doActionsAfterTick();
  simNoYield = 0;

  /* Look for new e-timers */
  if (!simEtimerPending && etimer_pending()) {
    /* Poll etimers */
    etimer_request_poll();
    simEtimerPending = 1;
  }

  /* Save nearest event timer expiration time (0 if no timers) */
  simNextExpirationTime = etimer_next_expiration_time();
}
Пример #4
0
void tmr3_isr(void) {
	if(bit_is_set(*TMR(3,CSCTRL),TCF1)) {
		current_clock++;
		if((current_clock % CLOCK_CONF_SECOND) == 0) {
			seconds++;
#if BLINK_SECONDS
			leds_toggle(LEDS_GREEN);
#endif
		}
		
		if(etimer_pending() &&
		   (etimer_next_expiration_time() - current_clock - 1) > MAX_TICKS) {
 			etimer_request_poll();
 		}


		/* clear the compare flags */
		clear_bit(*TMR(3,SCTRL),TCF);                
		clear_bit(*TMR(3,CSCTRL),TCF1);                
		clear_bit(*TMR(3,CSCTRL),TCF2);                
		return;
	} else {
		/* this timer didn't create an interrupt condition */
		return;
	}
}
Пример #5
0
/*---------------------------------------------------------------------------*/
int
main(void)
{
  printf("Starting Contiki\n");
  process_init();
  ctimer_init();

  netstack_init();
  
  procinit_init();

  serial_line_init();
  
  autostart_start(autostart_processes);

  
  /* Make standard output unbuffered. */
  setvbuf(stdout, (char *)NULL, _IONBF, 0);
  
  while(1) {
    fd_set fds;
    int n;
    struct timeval tv;
    
    clock_time_t next_event;
	
    n = process_run();
    next_event = etimer_next_expiration_time()-clock_time();

#if DEBUG_SLEEP
    if(n > 0) {
      printf("%d events pending\n",n);
    } else {
      printf("next event: T-%.03f\n",(double)next_event/(double)CLOCK_SECOND);
    }
#endif

	if(next_event>CLOCK_SECOND*2)
		next_event = CLOCK_SECOND*2;
    tv.tv_sec = n?0:next_event/CLOCK_SECOND;
    tv.tv_usec = n?0:next_event%1000*1000;

    FD_ZERO(&fds);
    FD_SET(STDIN_FILENO, &fds);
    select(1, &fds, NULL, NULL, &tv);

    if(FD_ISSET(STDIN_FILENO, &fds)) {
      char c;
      if(read(STDIN_FILENO, &c, 1) > 0) {
	serial_line_input_byte(c);
      }
    }
    
    etimer_request_poll();
  }
  
  return 0;
}
Пример #6
0
// alarm timer interrupt handler
ALARM_TIMER_INTERRUPT()
{
    // read & unset the highest bit
    volatile uint16_t x = TIMER_INTERRUPT_VECTOR;
    (void) x;

    if (isInSleepMode) {
        // wakeup and return
        EXIT_SLEEP_MODE();
        return;
    }

    uint16_t tar = ALARM_TIMER_READ();

    // Advance jiffies (MansOS time counter) while counter register <= counter
    // Spurios interrupts may happen when the alarm timer is restarted after stopping!
    while (!timeAfter16(ALARM_TIMER_REGISTER, tar)) {
        jiffies += JIFFY_TIMER_MS;
        ALARM_TIMER_REGISTER += PLATFORM_ALARM_TIMER_PERIOD;
    }

#if PLATFORM_HAS_CORRECTION_TIMER
    //
    // On MSP430 platforms binary ACLK oscillator usually is used.
    // It has constant rate 32768 Hz (the ACLK_SPEED define)
    // When ACLK ticks are converted to milliseconds, rounding error is introduced.
    // When TIMER_INTERRUPT_HZ = 1000, there are 32 ACLK ticks per millisecond;
    // The clock error is (32768 / 32) - 1000 = 1024 - 1000 = 24 milliseconds.
    // We improve the precision by applying a fix 24/3 = 8 times per second.
    //
    while (!timeAfter16(CORRECTION_TIMER_REGISTER, tar)) {
        CORRECTION_TIMER_REGISTER += PLATFORM_TIME_CORRECTION_PERIOD;
        jiffies -= 3;
    }
#endif

#ifdef USE_ALARMS
    if (hasAnyReadyAlarms(jiffies)) {
        alarmsProcess();
    }
#endif
#ifdef USE_PROTOTHREADS
    if (etimer_pending() && !etimer_polled()
            && !timeAfter32(jiffies, etimer_next_expiration_time())) {
         etimer_request_poll();
         EXIT_SLEEP_MODE();
    }
#endif

    // If TAR still > TACCR0 at this point, we are in trouble:
    // the interrupt will not be generated until the next wraparound (2 seconds).
    // So avoid it at all costs.
    while (!timeAfter16(ALARM_TIMER_REGISTER, ALARM_TIMER_READ() + 2)) {
        jiffies += JIFFY_TIMER_MS;
        ALARM_TIMER_REGISTER += PLATFORM_ALARM_TIMER_PERIOD;
    }
}
Пример #7
0
void SysTick_handler(void) {
	(void)SysTick->CTRL;
	SCB->ICSR = SCB_ICSR_PENDSTCLR;
	current_clock++;
	if(etimer_pending() && etimer_next_expiration_time() <= current_clock) {
		etimer_request_poll();
	}
	if (--second_countdown == 0) {
		current_seconds++;
		second_countdown = CLOCK_SECOND;
	}
}
Пример #8
0
/*---------------------------------------------------------------------------*/
interrupt(TIMERA1_VECTOR) timera1 (void) {
  ENERGEST_ON(ENERGEST_TYPE_IRQ);

  if(TAIV == 2) {
	  etimer_interrupt();
	  if(etimer_pending() &&
	     (etimer_next_expiration_time() - count - 1) > MAX_TICKS) {
	    etimer_request_poll();
	    LPM4_EXIT;
	  }
   }

  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}
Пример #9
0
/*---------------------------------------------------------------------------*/
ISR(TIMERA1, timera1)
{
  ENERGEST_ON(ENERGEST_TYPE_IRQ);

  watchdog_start();

  if(TAIV == 2) {

    /* HW timer bug fix: Interrupt handler called before TR==CCR.
     * Occurs when timer state is toggled between STOP and CONT. */
    while(TACTL & MC1 && TACCR1 - TAR == 1);

    /* Make sure interrupt time is future */
    do {
      TACCR1 += INTERVAL;
      ++count;

      /* Make sure the CLOCK_CONF_SECOND is a power of two, to ensure
	 that the modulo operation below becomes a logical and and not
	 an expensive divide. Algorithm from Wikipedia:
	 http://en.wikipedia.org/wiki/Power_of_two */
#if (CLOCK_CONF_SECOND & (CLOCK_CONF_SECOND - 1)) != 0
#error CLOCK_CONF_SECOND must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...).
#error Change CLOCK_CONF_SECOND in contiki-conf.h.
#endif
      if(count % CLOCK_CONF_SECOND == 0) {
	++seconds;
        energest_flush();
      }
    } while((TACCR1 - TAR) > INTERVAL);

    last_tar = TAR;

    if(etimer_pending() &&
       (etimer_next_expiration_time() - count - 1) > MAX_TICKS) {
      etimer_request_poll();
      LPM4_EXIT;
    }

  }
  /*  if(process_nevents() >= 0) {
    LPM4_EXIT;
    }*/

  watchdog_stop();

  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}
Пример #10
0
static void clock_alarm(handler_arg_t arg)
{
    (void)arg;
    clock_cnt ++;
    clock_sec_cnt ++;

    if (etimer_pending() && etimer_next_expiration_time() <= clock_cnt) 
    {
	etimer_request_poll();
    }

    if (clock_sec_cnt == CLOCK_SECOND) 
    {
	clock_sec ++;
	clock_sec_cnt = 0;
    }
}
Пример #11
0
void SysTick_Handler(void)
{
	INT_Disable( );
	
	current_clock++;
	if(etimer_pending() && etimer_next_expiration_time() <= current_clock) 
	{
		etimer_request_poll();
	}
	if (--second_countdown == 0) 
	{
		current_seconds++;
		second_countdown = CLOCK_SECOND;
	}
	
	INT_Enable( );
}
Пример #12
0
/**
 * \brief      Let mote execute one "block" of code (tick mote).
 *
 *             Let mote defined by the active contiki processes and current
 *             process memory execute some program code. This code must not block
 *             or else this function will never return. A typical contiki
 *             process will return when it executes PROCESS_WAIT..() statements.
 *
 *             Before the control is left to contiki processes, any messages
 *             from the Java part are handled. These may for example be
 *             incoming network data. After the contiki processes return control,
 *             messages to the Java part are also handled (those which may need
 *             special attention).
 *
 *             This is a JNI function and should only be called via the
 *             responsible Java part (MoteType.java).
 */
JNIEXPORT void JNICALL
Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj)
{
  clock_time_t nextEtimer;
  rtimer_clock_t nextRtimer;

  simProcessRunValue = 0;

  /* Let all simulation interfaces act first */
  doActionsBeforeTick();

  /* Poll etimer process */
  if (etimer_pending()) {
    etimer_request_poll();
  }

  /* Let rtimers run.
   * Sets simProcessRunValue */
  cooja_mt_exec(&rtimer_thread);

  if(simProcessRunValue == 0) {
    /* Rtimers done: Let Contiki handle a few events.
     * Sets simProcessRunValue */
    cooja_mt_exec(&process_run_thread);
  }

  /* Let all simulation interfaces act before returning to java */
  doActionsAfterTick();

  /* Do we have any pending timers */
  simEtimerPending = etimer_pending() || rtimer_arch_pending();
  if(!simEtimerPending) {
    return;
  }

  /* Save nearest expiration time */
  nextEtimer = etimer_next_expiration_time() - (clock_time_t) simCurrentTime;
  nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime;
  if(etimer_pending() && rtimer_arch_pending()) {
    simNextExpirationTime = MIN(nextEtimer, nextRtimer);
  } else if (etimer_pending()) {
    simNextExpirationTime = nextEtimer;
  } else if (rtimer_arch_pending()) {
    simNextExpirationTime = nextRtimer;
  }
}
Пример #13
0
/*---------------------------------------------------------------------------*/
interrupt(TIMERA1_VECTOR) timera1 (void) {
  ENERGEST_ON(ENERGEST_TYPE_IRQ);

  int taiv = TAIV;

  if(taiv == 2) {
	  etimer_interrupt();
	  if(etimer_pending() &&
	     (etimer_next_expiration_time() - count - 1) > MAX_TICKS) {
	    etimer_request_poll();
	    LPM4_EXIT;
	  }
   } else {
	  if (taiv == TAIV_TACCR2) {
		  radio_abort_rx();
		  LPM4_EXIT;
	  }
  }

  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}
Пример #14
0
void SimluateRun(CuTest* tc)
{
 /*
  * Initialize Contiki and our processes.
  */
  process_init();
  process_start(&etimer_process, NULL);
  ctimer_init();

  energest_init();
  ENERGEST_ON(ENERGEST_TYPE_CPU);

  window_init(0xff);  

  autostart_start(autostart_processes);

  process_start(&event_process, NULL);
  while(run) {
    int r;
    do {
      /* Reset watchdog. */
      r = process_run();
    } while(r > 0);

#if 0
    int n = etimer_next_expiration_time();
    if (n > 0)
    {
      int p = n - clock_time();
      if (p > 0)
      nanosleep(p);
    }
    else
    {
      nanosleep(1000);
    }
#endif
    etimer_request_poll();
  }
}
/*---------------------------------------------------------------------------*/
int
main(void)
{

  /* Hardware initialization */
  bus_init();//ʱÖÓ³õʼ»¯
  rtimer_init();//¼ÆʱÆ÷³õʼ»¯

  /* model-specific h/w init. */
  io_port_init();

  /* Init LEDs here */
  leds_init();//LED³õʼ»¯
  /*LEDS_GREEN indicate LEDs Init finished*/
  fade(LEDS_GREEN);

  /* initialize process manager. */
  process_init();//½ø³Ì¹ÜÀí³õʼ»¯

  /* Init UART0
   * Based on the EJOY MCU CC2430 Circuit Design
   *  */
  uart0_init();//UART0´®¿Ú³õʼ»¯

#if DMA_ON
  dma_init();//DMA³õʼ»¯
#endif

#if SLIP_ARCH_CONF_ENABLE
  /* On cc2430, the argument is not used */
  slip_arch_init(0);//SLIP³õʼ»¯
#else
  uart1_set_input(serial_line_input_byte);
  serial_line_init();
#endif

  PUTSTRING("##########################################\n");
  putstring(CONTIKI_VERSION_STRING "\n");
//  putstring(SENSINODE_MODEL " (CC24");
  puthex(((CHIPID >> 3) | 0x20));
  putstring("-" FLASH_SIZE ")\n");

#if STARTUP_VERBOSE
#ifdef HAVE_SDCC_BANKING
  PUTSTRING("  With Banking.\n");
#endif /* HAVE_SDCC_BANKING */
#ifdef SDCC_MODEL_LARGE
  PUTSTRING("  --model-large\n");
#endif /* SDCC_MODEL_LARGE */
#ifdef SDCC_MODEL_HUGE
  PUTSTRING("  --model-huge\n");
#endif /* SDCC_MODEL_HUGE */
#ifdef SDCC_STACK_AUTO
  PUTSTRING("  --stack-auto\n");
#endif /* SDCC_STACK_AUTO */

  PUTCHAR('\n');

  PUTSTRING(" Net: ");
  PUTSTRING(NETSTACK_NETWORK.name);
  PUTCHAR('\n');
  PUTSTRING(" MAC: ");
  PUTSTRING(NETSTACK_MAC.name);
  PUTCHAR('\n');
  PUTSTRING(" RDC: ");
  PUTSTRING(NETSTACK_RDC.name);
  PUTCHAR('\n');

  PUTSTRING("##########################################\n");
#endif

  watchdog_init();//¿´ÃŹ·³õʼ»¯

  /* Initialise the cc2430 RNG engine. */
  random_init(0);//Ëæ»úÊýÉú³ÉÆ÷³õʼ»¯

  /* start services */
  process_start(&etimer_process, NULL);//
  ctimer_init();//ctimer³õʼ»¯

  /* initialize the netstack */
  netstack_init();//ÍøÂçµ×²ãÕ»³õʼ»¯
  set_rime_addr();//rimeµØÖ·ÉèÖÃ

//there is no sensor for us maintenance
#if BUTTON_SENSOR_ON || ADC_SENSOR_ON
  process_start(&sensors_process, NULL);
  sensinode_sensors_activate();
#endif

//IPV6,YES!
#if UIP_CONF_IPV6
  memcpy(&uip_lladdr.addr, &rimeaddr_node_addr, sizeof(uip_lladdr.addr));
  queuebuf_init();
  process_start(&tcpip_process, NULL);
//DISCO
#if DISCO_ENABLED
  process_start(&disco_process, NULL);
#endif /* DISCO_ENABLED */
//VIZTOOL
#if VIZTOOL_CONF_ON
  process_start(&viztool_process, NULL);
#endif

#if (!UIP_CONF_IPV6_RPL)
  {
    uip_ipaddr_t ipaddr;
    uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0);
    uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
    uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
  }
#endif /* UIP_CONF_IPV6_RPL */
#endif /* UIP_CONF_IPV6 */

  /*
   * Acknowledge the UART1 RX interrupt
   * now that we're sure we are ready to process it
   *
   * We don't need it. by MW
   */
//  model_uart_intr_en();

  energest_init();
  ENERGEST_ON(ENERGEST_TYPE_CPU);

  fade(LEDS_RED);

#if BATMON_CONF_ON
  process_start(&batmon_process, NULL);
#endif

  autostart_start(autostart_processes);

  watchdog_start();

  while(1) {
    do {
      /* Reset watchdog and handle polls and events */
      watchdog_periodic();

      /**/
#if !CLOCK_CONF_ACCURATE
      if(sleep_flag) {
        if(etimer_pending() &&
            (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { /*core/sys/etimer.c*/
          etimer_request_poll();
        }
        sleep_flag = 0;
      }
#endif
      r = process_run();
    } while(r > 0);
#if SHORTCUTS_CONF_NETSTACK
    len = NETSTACK_RADIO.pending_packet();
    if(len) {
      packetbuf_clear();
      len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE);
      if(len > 0) {
        packetbuf_set_datalen(len);
        NETSTACK_RDC.input();
      }
    }
#endif

#if LPM_MODE
#if (LPM_MODE==LPM_MODE_PM2)
    SLEEP &= ~OSC_PD;            /* Make sure both HS OSCs are on */
    while(!(SLEEP & HFRC_STB));  /* Wait for RCOSC to be stable */
    CLKCON |= OSC;               /* Switch to the RCOSC */
    while(!(CLKCON & OSC));      /* Wait till it's happened */
    SLEEP |= OSC_PD;             /* Turn the other one off */
#endif /* LPM_MODE==LPM_MODE_PM2 */

    /*
     * Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM
     * Sleep Timer will wake us up in no more than 7.8ms (max idle interval)
     */
    SLEEP = (SLEEP & 0xFC) | (LPM_MODE - 1);

#if (LPM_MODE==LPM_MODE_PM2)
    /*
     * Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or
     * no interrupt occurred and we can safely power down
     */
    __asm
      nop
      nop
      nop
    __endasm;

    if (SLEEP & SLEEP_MODE0) {
#endif /* LPM_MODE==LPM_MODE_PM2 */

      ENERGEST_OFF(ENERGEST_TYPE_CPU);
      ENERGEST_ON(ENERGEST_TYPE_LPM);

      /* We are only interested in IRQ energest while idle or in LPM */
      ENERGEST_IRQ_RESTORE(irq_energest);

      /* Go IDLE or Enter PM1 */
      PCON |= IDLE;

      /* First instruction upon exiting PM1 must be a NOP */
      __asm
        nop
      __endasm;

      /* Remember energest IRQ for next pass */
      ENERGEST_IRQ_SAVE(irq_energest);

      ENERGEST_ON(ENERGEST_TYPE_CPU);
      ENERGEST_OFF(ENERGEST_TYPE_LPM);

#if (LPM_MODE==LPM_MODE_PM2)
      SLEEP &= ~OSC_PD;            /* Make sure both HS OSCs are on */
      while(!(SLEEP & XOSC_STB));  /* Wait for XOSC to be stable */
      CLKCON &= ~OSC;              /* Switch to the XOSC */
      /*
       * On occasion the XOSC is reported stable when in reality it's not.
       * We need to wait for a safeguard of 64us or more before selecting it
       */
      clock_delay(10);
      while(CLKCON & OSC);         /* Wait till it's happened */
    }
#endif /* LPM_MODE==LPM_MODE_PM2 */
#endif /* LPM_MODE */
  }
}
Пример #16
0
/*---------------------------------------------------------------------------*/
int
main(void)
{
  clock_init();
#if UIP_CONF_IPV6
/* A hard coded address overrides the stack default MAC address to
   allow multiple instances. uip6.c defines it as
   {0x00,0x06,0x98,0x00,0x02,0x32} giving an ipv6 address of
   [fe80::206:98ff:fe00:232] We make it simpler, {0x02,0x00,0x00 + the
   last three bytes of the hard coded address (if any are nonzero).
   HARD_CODED_ADDRESS can be defined in the contiki-conf.h file, or
   here to allow quick builds using different addresses.  If
   HARD_CODED_ADDRESS has a prefix it also applied, unless built as a
   RPL end node.  E.g. bbbb::12:3456 becomes fe80::ff:fe12:3456 and
   prefix bbbb::/64 if non-RPL ::10 becomes fe80::ff:fe00:10 and
   prefix awaits RA or RPL formation bbbb:: gives an address of
   bbbb::206:98ff:fe00:232 if non-RPL */
#ifdef HARD_CODED_ADDRESS
  {
  uip_ipaddr_t ipaddr;
  uiplib_ipaddrconv(HARD_CODED_ADDRESS, &ipaddr);
  if((ipaddr.u8[13] != 0) ||
     (ipaddr.u8[14] != 0) ||
     (ipaddr.u8[15] != 0)) {
    if(sizeof(uip_lladdr) == 6) {  /* Minimal-net uses ethernet MAC */
      uip_lladdr.addr[0] = 0x02;
      uip_lladdr.addr[1] = 0;
      uip_lladdr.addr[2] = 0;
      uip_lladdr.addr[3] = ipaddr.u8[13];
      uip_lladdr.addr[4] = ipaddr.u8[14];
      uip_lladdr.addr[5] = ipaddr.u8[15];
    }
  }
 }
#endif /* HARD_CODED_ADDRESS */
#endif /* UIP_CONF_IPV6 */

  process_init();
/* procinit_init initializes RPL which sets a ctimer for the first DIS */
/* We must start etimers and ctimers,before calling it */
  process_start(&etimer_process, NULL);
  ctimer_init();

#if RPL_BORDER_ROUTER
  process_start(&border_router_process, NULL);
  printf("Border Router Process started\n");
#elif UIP_CONF_IPV6_RPL
  printf("RPL enabled\n");
#endif

  procinit_init();
  autostart_start(autostart_processes); 

  /* Set default IP addresses if not specified */
#if !UIP_CONF_IPV6
  {
    uip_ipaddr_t addr;

    uip_gethostaddr(&addr);
    if(addr.u8[0] == 0) {
      uip_ipaddr(&addr, 172,18,0,2);
    }
    printf("IP Address:  %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr));
    uip_sethostaddr(&addr);
    
    uip_getnetmask(&addr);
    if(addr.u8[0] == 0) {
      uip_ipaddr(&addr, 255,255,0,0);
      uip_setnetmask(&addr);
    }
    printf("Subnet Mask: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr));
    
    uip_getdraddr(&addr);
    if(addr.u8[0] == 0) {
      uip_ipaddr(&addr, 172,18,0,1);
      uip_setdraddr(&addr);
    }
    printf("Def. Router: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr));
  }
#else /* UIP_CONF_IPV6 */

#if !UIP_CONF_IPV6_RPL
  {
    uip_ipaddr_t ipaddr;
#ifdef HARD_CODED_ADDRESS
    uiplib_ipaddrconv(HARD_CODED_ADDRESS, &ipaddr);
#else
    uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
#endif
    if((ipaddr.u16[0] != 0) ||
       (ipaddr.u16[1] != 0) ||
       (ipaddr.u16[2] != 0) ||
       (ipaddr.u16[3] != 0)) {
#if UIP_CONF_ROUTER
      if(!uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0, 0, 0, 0)) {
        fprintf(stderr,"uip_ds6_prefix_add() failed.\n");
        exit(EXIT_FAILURE);
      }
#else /* UIP_CONF_ROUTER */
      if(!uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0)) {
        fprintf(stderr,"uip_ds6_prefix_add() failed.\n");
        exit(EXIT_FAILURE);
      }
#endif /* UIP_CONF_ROUTER */

      uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
      uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF);
    }
  }
#endif /* !UIP_CONF_IPV6_RPL */

#endif /* !UIP_CONF_IPV6 */

 // procinit_init();
 // autostart_start(autostart_processes); 

  /* Make standard output unbuffered. */
  setvbuf(stdout, (char *)NULL, _IONBF, 0);

  printf("\n*******%s online*******\n",CONTIKI_VERSION_STRING);

#if UIP_CONF_IPV6 && !RPL_BORDER_ROUTER  /* Border router process prints addresses later */
  {
    int i = 0;
    int interface_count = 0;
    for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
      if(uip_ds6_if.addr_list[i].isused) {
        printf("IPV6 Addresss: ");
        sprint_ip6(uip_ds6_if.addr_list[i].ipaddr);
        printf("\n");
        interface_count++;
      }
    }
    assert(0 < interface_count);
  }
#endif

  while(1) {
    fd_set fds;
    int n;
    struct timeval tv;
    clock_time_t next_event;
    
    n = process_run();
    next_event = etimer_next_expiration_time() - clock_time();

#if DEBUG_SLEEP
    if(n > 0)
      printf("sleep: %d events pending\n",n);
    else
      printf("sleep: next event @ T-%.03f\n",(double)next_event / (double)CLOCK_SECOND);
#endif

#ifdef __CYGWIN__
    /* wpcap doesn't appear to support select, so
     * we can't idle the process on windows. */
    next_event = 0;
#endif

    if(next_event > (CLOCK_SECOND * 2))
      next_event = CLOCK_SECOND * 2;
    tv.tv_sec = n ? 0 : (next_event / CLOCK_SECOND);
    tv.tv_usec = n ? 0 : ((next_event % 1000) * 1000);

    FD_ZERO(&fds);
    FD_SET(STDIN_FILENO, &fds);
#ifdef __CYGWIN__
    select(1, &fds, NULL, NULL, &tv);
#else
    FD_SET(tapdev_fd(), &fds);
    if(0 > select(tapdev_fd() + 1, &fds, NULL, NULL, &tv)) {
      perror("Call to select() failed.");
      exit(EXIT_FAILURE);
    }
#endif

    if(FD_ISSET(STDIN_FILENO, &fds)) {
      char c;
      if(read(STDIN_FILENO, &c, 1) > 0) {
	serial_line_input_byte(c);
      }
    }
#ifdef __CYGWIN__
    process_poll(&wpcap_process);
#else
    process_poll(&tapdev_process);
#endif
    etimer_request_poll();
  }
  
  return 0;
}
/*---------------------------------------------------------------------------*/
int
main(void)
{
    /* Hardware initialization */
    clock_init();
    soc_init();
    rtimer_init();

    /* Init LEDs here */
    leds_init();
    leds_off(LEDS_ALL);
    fade(LEDS_GREEN);

    /* initialize process manager. */
    process_init();

    /* Init UART */
    uart0_init();

#if DMA_ON
    dma_init();
#endif

#if SLIP_ARCH_CONF_ENABLE
    slip_arch_init(0);
#else
    uart0_set_input(serial_line_input_byte);
    serial_line_init();
#endif
    fade(LEDS_RED);

    PUTSTRING("##########################################\n");
    putstring(CONTIKI_VERSION_STRING "\n");
    putstring("TI SmartRF05 EB\n");
    switch(CHIPID) {
    case 0xA5:
        putstring("cc2530");
        break;
    case 0xB5:
        putstring("cc2531");
        break;
    case 0x95:
        putstring("cc2533");
        break;
    case 0x8D:
        putstring("cc2540");
        break;
    }

    putstring("-F");
    switch(CHIPINFO0 & 0x70) {
    case 0x40:
        putstring("256, ");
        break;
    case 0x30:
        putstring("128, ");
        break;
    case 0x20:
        putstring("64, ");
        break;
    case 0x10:
        putstring("32, ");
        break;
    }
    puthex(CHIPINFO1 + 1);
    putstring("KB SRAM\n");

    PUTSTRING("\nSDCC Build:\n");
#if STARTUP_VERBOSE
#ifdef HAVE_SDCC_BANKING
    PUTSTRING("  With Banking.\n");
#endif /* HAVE_SDCC_BANKING */
#ifdef SDCC_MODEL_LARGE
    PUTSTRING("  --model-large\n");
#endif /* SDCC_MODEL_LARGE */
#ifdef SDCC_MODEL_HUGE
    PUTSTRING("  --model-huge\n");
#endif /* SDCC_MODEL_HUGE */
#ifdef SDCC_STACK_AUTO
    PUTSTRING("  --stack-auto\n");
#endif /* SDCC_STACK_AUTO */

    PUTCHAR('\n');

    PUTSTRING(" Net: ");
    PUTSTRING(NETSTACK_NETWORK.name);
    PUTCHAR('\n');
    PUTSTRING(" MAC: ");
    PUTSTRING(NETSTACK_MAC.name);
    PUTCHAR('\n');
    PUTSTRING(" RDC: ");
    PUTSTRING(NETSTACK_RDC.name);
    PUTCHAR('\n');

    PUTSTRING("##########################################\n");
#endif

    watchdog_init();

    /* Initialise the H/W RNG engine. */
    random_init(0);

    /* start services */
    process_start(&etimer_process, NULL);
    ctimer_init();

    /* initialize the netstack */
    netstack_init();
    set_rime_addr();

#if BUTTON_SENSOR_ON || ADC_SENSOR_ON
    process_start(&sensors_process, NULL);
    BUTTON_SENSOR_ACTIVATE();
    ADC_SENSOR_ACTIVATE();
#endif

#if UIP_CONF_IPV6
    memcpy(&uip_lladdr.addr, &rimeaddr_node_addr, sizeof(uip_lladdr.addr));
    queuebuf_init();
    process_start(&tcpip_process, NULL);
#endif /* UIP_CONF_IPV6 */

#if VIZTOOL_CONF_ON
    process_start(&viztool_process, NULL);
#endif

    energest_init();
    ENERGEST_ON(ENERGEST_TYPE_CPU);

    autostart_start(autostart_processes);

    watchdog_start();

    fade(LEDS_YELLOW);

    while(1) {
        do {
            /* Reset watchdog and handle polls and events */
            watchdog_periodic();

#if CLOCK_CONF_STACK_FRIENDLY
            if(sleep_flag) {
                if(etimer_pending() &&
                        (etimer_next_expiration_time() - clock_time() - 1) > MAX_TICKS) {
                    etimer_request_poll();
                }
                sleep_flag = 0;
            }
#endif
            r = process_run();
        } while(r > 0);
        len = NETSTACK_RADIO.pending_packet();
        if(len) {
            packetbuf_clear();
            len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE);
            if(len > 0) {
                packetbuf_set_datalen(len);
                NETSTACK_RDC.input();
            }
        }

#if LPM_MODE
#if (LPM_MODE==LPM_MODE_PM2)
        SLEEP &= ~OSC_PD;            /* Make sure both HS OSCs are on */
        while(!(SLEEP & HFRC_STB));  /* Wait for RCOSC to be stable */
        CLKCON |= OSC;               /* Switch to the RCOSC */
        while(!(CLKCON & OSC));      /* Wait till it's happened */
        SLEEP |= OSC_PD;             /* Turn the other one off */
#endif /* LPM_MODE==LPM_MODE_PM2 */

        /*
         * Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM
         * Sleep Timer will wake us up in no more than 7.8ms (max idle interval)
         */
        SLEEPCMD = (SLEEPCMD & 0xFC) | (LPM_MODE - 1);

#if (LPM_MODE==LPM_MODE_PM2)
        /*
         * Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or
         * no interrupt occurred and we can safely power down
         */
        __asm
        nop
        nop
        nop
        __endasm;

        if(SLEEPCMD & SLEEP_MODE0) {
#endif /* LPM_MODE==LPM_MODE_PM2 */

            ENERGEST_OFF(ENERGEST_TYPE_CPU);
            ENERGEST_ON(ENERGEST_TYPE_LPM);

            /* We are only interested in IRQ energest while idle or in LPM */
            ENERGEST_IRQ_RESTORE(irq_energest);

            /* Go IDLE or Enter PM1 */
            PCON |= PCON_IDLE;

            /* First instruction upon exiting PM1 must be a NOP */
            __asm
            nop
            __endasm;

            /* Remember energest IRQ for next pass */
            ENERGEST_IRQ_SAVE(irq_energest);

            ENERGEST_ON(ENERGEST_TYPE_CPU);
            ENERGEST_OFF(ENERGEST_TYPE_LPM);

#if (LPM_MODE==LPM_MODE_PM2)
            SLEEPCMD &= ~SLEEP_OSC_PD;            /* Make sure both HS OSCs are on */
            while(!(SLEEPCMD & SLEEP_XOSC_STB));  /* Wait for XOSC to be stable */
            CLKCONCMD &= ~CLKCONCMD_OSC;              /* Switch to the XOSC */
            /*
             * On occasion the XOSC is reported stable when in reality it's not.
             * We need to wait for a safeguard of 64us or more before selecting it
             */
            clock_delay(10);
            while(CLKCONCMD & CLKCONCMD_OSC);         /* Wait till it's happened */
        }
#endif /* LPM_MODE==LPM_MODE_PM2 */
#endif /* LPM_MODE */
    }
}
Пример #18
0
int
main(int argc, char **argv)
{
  clock_init();

#if NETSTACK_CONF_WITH_IPV6
#if UIP_CONF_IPV6_RPL
  printf(CONTIKI_VERSION_STRING " started with IPV6, RPL\n");
#else
  printf(CONTIKI_VERSION_STRING " started with IPV6\n");
#endif
#else
  printf(CONTIKI_VERSION_STRING " started\n");
#endif

  /* crappy way of remembering and accessing argc/v */
  contiki_argc = argc;
  contiki_argv = argv;

  /* native under windows is hardcoded to use the first one or two args */
  /* for wpcap configuration so this needs to be "removed" from         */
  /* contiki_args (used by the native-border-router) */
#ifdef __CYGWIN__
  contiki_argc--;
  contiki_argv++;
#ifdef UIP_FALLBACK_INTERFACE
  contiki_argc--;
  contiki_argv++;
#endif
#endif

  process_init();
  process_start(&etimer_process, NULL);
  ctimer_init();
  rtimer_init();

  prepare_network();

  serial_line_init();

  /* Make standard output unbuffered. */
  setvbuf(stdout, (char *)NULL, _IONBF, 0);

  select_set_callback(STDIN_FILENO, &stdin_fd);
  while(1) {
    fd_set fdr;
    fd_set fdw;
    int maxfd;
    int i;
    int retval;
    struct timeval tv;

    retval = process_run();

    tv.tv_sec = 0;
    tv.tv_usec = 0;
    if(!retval) {

      if(etimer_pending()) {
        clock_time_t t = etimer_next_expiration_time() - clock_time() - 1;
        if(t < MAX_TICKS) {
          tv.tv_sec = t / CLOCK_SECOND;
          tv.tv_usec = (t % CLOCK_SECOND) * 1000;
          if(tv.tv_usec == 0 && tv.tv_sec == 0) {
            /* Clock time resolution is milliseconds. Avoid millisecond
               busy loops. */
            tv.tv_usec = 250;
          }
        }
      } else {
        tv.tv_sec = 60;
      }

      /* TODO Replace the busy polling used to read data from the slip pthread */
      if(tv.tv_sec)  {
	tv.tv_sec = 0;
	tv.tv_usec = 10000;
      } else if(tv.tv_usec > 10000) {
	tv.tv_usec = 10000;
      }
    }

    FD_ZERO(&fdr);
    FD_ZERO(&fdw);
    maxfd = 0;
    for(i = 0; i <= select_max; i++) {
      if(select_callback[i] != NULL && select_callback[i]->set_fd(&fdr, &fdw)) {
        maxfd = i;
      }
    }

    retval = select(maxfd + 1, &fdr, &fdw, NULL, &tv);
    if(retval < 0) {
      if(errno != EINTR) {
        perror("select");
      }
    } else if(retval > 0) {
      /* timeout => retval == 0 */
      for(i = 0; i <= maxfd; i++) {
        if(select_callback[i] != NULL) {
          select_callback[i]->handle_fd(&fdr, &fdw);
        }
      }
    }

    if(etimer_pending() &&
       (etimer_next_expiration_time() - clock_time() - 1) > MAX_TICKS) {
      etimer_request_poll();
    }
  }

  return 0;
}
Пример #19
0
/*---------------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
    PRINTF(">> %s:main()\n", __FILE__);

start:
    /* Yield once during bootup */
    kleenet_schedule_state(MILLISECOND);
    kleenet_yield_state();
    simCurrentTime = NODE_TIME();

    PRINTF("> Executing Contiki at simulation time %lu\n", clock_time());

    /* Code from contiki-cooja-main.c:process_run_thread_loop (before loop) */
    doActionsBeforeTick();
    contiki_init();
    doActionsAfterTick();

    while (1) {

        /* reboot */
        if ((clock_seconds() >= failure_delay()) && reboot_once) {
            /* symbolic node reboot every 10 seconds */
            if (clock_seconds() % 10 == 0) {
                if (failure_reboot_node()) {
                    PRINTF("main(): rebooting node once @ %lu, %lu seconds\n",
                           clock_time(), clock_seconds());
                    reboot_once = 0;
                    exit_all_processes();
                    goto start;
                }
            }
        }
        /* halt */
        if ((clock_seconds() >= failure_delay()) && halt_once) {
            /* symbolic node outage every 10 seconds */
            if (clock_seconds() % 10 == 0) {
                if (failure_halt_node()) {
                    PRINTF("main(): halting node once @ %lu, %lu seconds\n",
                           clock_time(), clock_seconds());
                    halt_once = 0;
                    exit_all_processes();
                    /* loop forerver */
                    while(1) {
                        kleenet_schedule_state(MILLISECOND);
                        kleenet_yield_state();
                    }
                }
            }
        }

        /* Update time */
        simCurrentTime = NODE_TIME();
        simProcessRunValue = 0;

        /* Do actions before tick */
        doActionsBeforeTick();

        /* Poll etimer process */
        if (etimer_pending()) {
            etimer_request_poll();
        }

        /* Code from contiki-cooja-main.c:process_run_thread_loop */
        simProcessRunValue = process_run();
        while(simProcessRunValue-- > 0) {
            process_run();
        }
        simProcessRunValue = process_nevents();

        /* Do actions after tick */
        doActionsAfterTick();

        /* Request next tick for remaining events / timers */
        if (simProcessRunValue != 0) {
            kleenet_schedule_state(MILLISECOND);
            kleenet_yield_state();
            continue;
        }

        /* Request tick next wakeup time */
        if (etimer_pending()) {
            simNextExpirationTime = etimer_next_expiration_time() - simCurrentTime;
        } else {
            simNextExpirationTime = 0;
            PRINTF("WARNING: No more timers pending\n");
            kleenet_schedule_state(MILLISECOND);
            kleenet_yield_state();
            continue;
        }

        /* check next expiration time */
        if (simNextExpirationTime <= 0) {
            PRINTF("WARNING: Event timer already expired, but has been delayed: %lu\n",
                   simNextExpirationTime);
            kleenet_schedule_state(MILLISECOND);
        } else {
            kleenet_schedule_state(simNextExpirationTime*MILLISECOND);
        }

        /* yield active state */
        kleenet_yield_state();

    }
    return 0;
}
Пример #20
0
/*---------------------------------------------------------------------------*/
void
lpm_drop()
{
  lpm_registered_module_t *module;
  uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
  uint8_t module_pm;
  clock_time_t next_event;

  uint32_t domains = LOCKABLE_DOMAINS;

  if(RTIMER_CLOCK_LT(soc_rtc_get_next_trigger(),
                     RTIMER_NOW() + STANDBY_MIN_DURATION)) {
    lpm_sleep();
    return;
  }

  /* Collect max allowed PM permission from interested modules */
  for(module = list_head(modules_list); module != NULL;
      module = module->next) {
    if(module->request_max_pm) {
      module_pm = module->request_max_pm();
      if(module_pm < max_pm) {
        max_pm = module_pm;
      }
    }
  }

  /* Check if any events fired during this process. Last chance to abort */
  if(process_nevents()) {
    return;
  }

  /* Drop */
  if(max_pm == LPM_MODE_SLEEP) {
    lpm_sleep();
  } else {
    /* Critical. Don't get interrupted! */
    ti_lib_int_master_disable();

    /*
     * Reschedule AON RTC CH1 to fire an event N ticks before the next etimer
     * event
     */
    next_event = etimer_next_expiration_time();

    if(next_event) {
      next_event = next_event - clock_time();
      soc_rtc_schedule_one_shot(AON_RTC_CH1, RTIMER_NOW() +
          (next_event * (RTIMER_SECOND / CLOCK_SECOND)));
    }

    /*
     * Notify all registered modules that we are dropping to mode X. We do not
     * need to do this for simple sleep.
     *
     * This is a chance for modules to delay us a little bit until an ongoing
     * operation has finished (e.g. uart TX) or to configure themselves for
     * deep sleep.
     *
     * At this stage, we also collect power domain locks, if any.
     * The argument to PRCMPowerDomainOff() is a bitwise OR, so every time
     * we encounter a lock we just clear the respective bits in the 'domains'
     * variable as required by the lock. In the end the domains variable will
     * just hold whatever has not been cleared
     */
    for(module = list_head(modules_list); module != NULL;
        module = module->next) {
      if(module->shutdown) {
        module->shutdown(max_pm);
      }

      /* Clear the bits specified in the lock */
      domains &= ~module->domain_lock;
    }

    /* Pat the dog: We don't want it to shout right after we wake up */
    watchdog_periodic();

    /* Clear unacceptable bits, just in case a lock provided a bad value */
    domains &= LOCKABLE_DOMAINS;

    /*
     * Freeze the IOs on the boundary between MCU and AON. We only do this if
     * PERIPH is not needed
     */
    if(domains & PRCM_DOMAIN_PERIPH) {
      ti_lib_aon_ioc_freeze_enable();
    }

    /*
     * Among LOCKABLE_DOMAINS, turn off those that are not locked
     *
     * If domains is != 0, pass it as-is
     */
    if(domains) {
      ti_lib_prcm_power_domain_off(domains);
    }

    /*
     * Before entering Deep Sleep, we must switch off the HF XOSC. The HF XOSC
     * is predominantly controlled by the RF driver. In a build with radio
     * cycling (e.g. ContikiMAC), the RF driver will request the XOSC before
     * using the Freq. Synth, and switch back to the RC when it is about to
     * turn back off.
     *
     * If the radio is on, we won't even reach here, and if it's off the HF
     * clock source should already be the HF RC.
     *
     * Nevertheless, request the switch to the HF RC explicitly here.
     */
    oscillators_switch_to_hf_rc();

    /* Configure clock sources for MCU and AUX: No clock */
    ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK);
    ti_lib_aon_wuc_aux_power_down_config(AONWUC_NO_CLOCK);

    /* Full RAM retention. */
    ti_lib_aon_wuc_mcu_sram_config(MCU_RAM0_RETENTION | MCU_RAM1_RETENTION |
                                   MCU_RAM2_RETENTION | MCU_RAM3_RETENTION);

    /* Disable retention of AUX RAM */
    ti_lib_aon_wuc_aux_sram_config(false);

    /*
     * Always turn off RFCORE, CPU, SYSBUS and VIMS. RFCORE should be off
     * already
     */
    ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_CPU |
                                 PRCM_DOMAIN_VIMS | PRCM_DOMAIN_SYSBUS);

    /* Request JTAG domain power off */
    ti_lib_aon_wuc_jtag_power_off();

    /* Turn off AUX */
    ti_lib_aux_wuc_power_ctrl(AUX_WUC_POWER_OFF);
    ti_lib_aon_wuc_domain_power_down_enable();
    while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON);

    /* Configure the recharge controller */
    ti_lib_sys_ctrl_set_recharge_before_power_down(XOSC_IN_HIGH_POWER_MODE);

    /*
     * If both PERIPH and SERIAL PDs are off, request the uLDO as the power
     * source while in deep sleep.
     */
    if(domains == LOCKABLE_DOMAINS) {
      ti_lib_pwr_ctrl_source_set(PWRCTRL_PWRSRC_ULDO);
    }

    /* We are only interested in IRQ energest while idle or in LPM */
    ENERGEST_IRQ_RESTORE(irq_energest);
    ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);

    /* Sync the AON interface to ensure all writes have gone through. */
    ti_lib_sys_ctrl_aon_sync();

    /*
     * Explicitly turn off VIMS cache, CRAM and TRAM. Needed because of
     * retention mismatch between VIMS logic and cache. We wait to do this
     * until right before deep sleep to be able to use the cache for as long
     * as possible.
     */
    ti_lib_prcm_cache_retention_disable();
    ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_OFF);

    /* Deep Sleep */
    ti_lib_prcm_deep_sleep();

    /*
     * When we reach here, some interrupt woke us up. The global interrupt
     * flag is off, hence we have a chance to run things here. We will wake up
     * the chip properly, and then we will enable the global interrupt without
     * unpending events so the handlers can fire
     */
    wake_up();

    ti_lib_int_master_enable();
  }
}