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(); }
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; } }
/** * \brief Update the software clock ticks and seconds * * This function is used to update the software tick counters whenever the * system clock might have changed, which can occur upon a SysTick ISR or upon * wake-up from PM1/2. * * For the software clock ticks counter, the Sleep Timer counter value is used * as the base tick value, and extended to a 64-bit value thanks to a detection * of wraparounds. * * For the seconds counter, the changes of the Sleep Timer counter value are * added to the reference time, which is either the startup time or the value * passed to clock_set_seconds(). * * This function polls the etimer process if an etimer has expired. */ static void update_ticks(void) { rtimer_clock_t now; uint64_t prev_rt_ticks_startup, cur_rt_ticks_startup; uint32_t cur_rt_ticks_startup_hi; now = RTIMER_NOW(); prev_rt_ticks_startup = rt_ticks_startup; cur_rt_ticks_startup_hi = prev_rt_ticks_startup >> 32; if(now < (rtimer_clock_t)prev_rt_ticks_startup) { cur_rt_ticks_startup_hi++; } cur_rt_ticks_startup = (uint64_t)cur_rt_ticks_startup_hi << 32 | now; rt_ticks_startup = cur_rt_ticks_startup; rt_ticks_epoch += cur_rt_ticks_startup - prev_rt_ticks_startup; /* * Inform the etimer library that the system clock has changed and that an * etimer might have expired. */ if(etimer_pending()) { etimer_request_poll(); } }
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; } }
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; } }
/** * \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; } }
// 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; } }
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; } }
void Contiki_SysTick_Handler(void) { ticks++; if((ticks % CLOCK_SECOND) == 0) { seconds++; energest_flush(); } if(etimer_pending()) { etimer_request_poll(); } }
/*---------------------------------------------------------------------------*/ void TIM4_IRQHandler(void) { TIM_ClearITPendingBit(TIM4, TIM_IT_Update); count++; if(etimer_pending()) { etimer_request_poll(); } if (--second_countdown == 0) { current_seconds++; second_countdown = CLOCK_SECOND; } }
/*---------------------------------------------------------------------------*/ void Timer0IntHandler(void) { ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); count++; if(etimer_pending()) { etimer_request_poll(); } if (--second_countdown == 0) { current_seconds++; second_countdown = CLOCK_SECOND; } }
/*---------------------------------------------------------------------------*/ void st_lib_sys_tick_handler(void) { ticks++; if((ticks % CLOCK_SECOND) == 0) { seconds++; energest_flush(); } HAL_IncTick(); if(etimer_pending()) { etimer_request_poll(); } }
/*---------------------------------------------------------------------------*/ void SysTick_Handler(void) { count++; if(etimer_pending()) { etimer_request_poll(); } if(--second_countdown == 0) { current_seconds++; second_countdown = CLOCK_SECOND; } }
/*---------------------------------------------------------------------------*/ 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); }
/*---------------------------------------------------------------------------*/ void LETIMER0_IRQHandler(void) { LETIMER0->IFC = LETIMER_IEN_UF; count++; if(etimer_pending()) { etimer_request_poll(); } if(--second_countdown == 0) { current_seconds++; second_countdown = CLOCK_SECOND; } }
/*---------------------------------------------------------------------------*/ 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); }
/*---------------------------------------------------------------------------*/ void _TC3_Handler(void)//void TCC0_Handler(void) { ENERGEST_ON(ENERGEST_TYPE_IRQ); ticks++; if((ticks % CLOCK_SECOND) == 0) { seconds++; energest_flush(); // printf("seconds, ticks %d\n", tc_get_count_value(&tc_instance)); } if(etimer_pending()) { etimer_request_poll(); } ENERGEST_OFF(ENERGEST_TYPE_IRQ); }
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; } }
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( ); }
/*---------------------------------------------------------------------------*/ static void clock_irq_callback( struct tc_module *const module_inst) { // ENERGEST_ON(ENERGEST_TYPE_IRQ); ticks++; //port_pin_toggle_output_level(PIN_PA23); if((ticks % CLOCK_SECOND) == 0) { seconds++; //energest_flush(); // printf("seconds, ticks %d\n", tc_get_count_value(&tc_instance)); } if(etimer_pending()) { etimer_request_poll(); } //ENERGEST_OFF(ENERGEST_TYPE_IRQ); }
/*---------------------------------------------------------------------------*/ 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); }
/*---------------------------------------------------------------------------*/ 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 */ } }
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; }
/*---------------------------------------------------------------------------*/ clock_time_t etimer_next_expiration_time(void) { return etimer_pending() ? next_expiration : 0; }
/*---------------------------------------------------------------------------*/ 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 */ } }
/*---------------------------------------------------------------------------*/ 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; }