/*---------------------------------------------------------------------------*/ PROCESS_THREAD(tcpip_process, ev, data, buf) { PROCESS_BEGIN(); #if UIP_TCP { static unsigned char i; for(i = 0; i < UIP_LISTENPORTS; ++i) { s.listenports[i].port = 0; } s.p = PROCESS_CURRENT(); } #endif tcpip_event = process_alloc_event(); #if UIP_CONF_ICMP6 tcpip_icmp6_event = process_alloc_event(); #endif /* UIP_CONF_ICMP6 */ etimer_set(&periodic, CLOCK_SECOND / 2); uip_init(); #ifdef UIP_FALLBACK_INTERFACE UIP_FALLBACK_INTERFACE.init(); #endif /* initialize RPL if configured for using RPL */ #if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL rpl_init(); #endif /* UIP_CONF_IPV6_RPL */ while(1) { PROCESS_YIELD(); eventhandler(ev, data, buf); } PROCESS_END(); }
PROCESS_THREAD(end_node_process, ev, data) { PROCESS_BEGIN(); static struct etimer et; etimer_set(&et, CLOCK_SECOND); printf("Using NodeId: %X\n\r", get_nodeid()); /* Turn off AES */ netstack_aes_set_active(1); /* Allocate events */ reconnect_event = process_alloc_event(); /* Reconnect from here */ while(1) { if(simple_rpl_parent() == NULL) { printf("\r\n Connecting to a Wireless Network...\r\n"); etimer_set(&et, CLOCK_SECOND / 1); while(simple_rpl_parent() == NULL) { PROCESS_YIELD_UNTIL(etimer_expired(&et)); etimer_reset(&et); } printf("\r\n Connected to Wireless network\r\n"); } process_start(&prox_agent_process, NULL); /* Reset reconnecting flag */ reconnecting = 0; /* Main loop */ while(1) { PROCESS_WAIT_EVENT(); if(ev == reconnect_event) { reconnecting = 1; etimer_set(&reconnect_timer, CLOCK_SECOND*10); } if(reconnecting && etimer_expired(&reconnect_timer)) { break; } } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ static void tcpip_handler(void) { char *appdata; unsigned char i; blink_event = process_alloc_event(); if(uip_newdata()) { appdata = (char *)uip_appdata; appdata[uip_datalen()] = 0; for(i = 0; i < 4; i++){ dht11data[i] = *(appdata + i); } PRINTF("DATA recv '%s' from ", appdata); PRINTF("%d", UIP_IP_BUF->srcipaddr.u8[sizeof(UIP_IP_BUF->srcipaddr.u8) - 1]); PRINTF("\n"); PRINTF("wendu is %c%c, shidu is %c%c \n", *appdata,*(appdata+1),*(appdata+2),*(appdata+3)); // PRINTF("DATA sending reply\n"); // uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); /* if(strncmp(appdata, "RED", 3) == 0) { leds_on(LEDS_RED); leds_off(LEDS_GREEN); sta = 0; } if(strncmp(appdata, "GREEN", 5) == 0) { leds_on(LEDS_GREEN); leds_off(LEDS_RED); sta = 0; } if(strncmp(appdata,"BLINK",5) == 0) { process_post(&udp_server_process, blink_event, NULL); sta = 1; } if(strncmp(appdata,"OFF",3) == 0) { leds_off(LEDS_RED | LEDS_GREEN); sta = 0; } #if SERVER_REPLY PRINTF("DATA sending reply\n"); uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); uip_udp_packet_send(server_conn, "Reply", sizeof("Reply")); uip_create_unspecified(&server_conn->ripaddr); #endif */ } }
/*---------------------------------------------------------------------------*/ void mqtt_init(void) { static uint8_t inited = 0; if(!inited) { mqtt_do_connect_tcp_event = process_alloc_event(); mqtt_do_connect_mqtt_event = process_alloc_event(); mqtt_do_disconnect_mqtt_event = process_alloc_event(); mqtt_do_subscribe_event = process_alloc_event(); mqtt_do_unsubscribe_event = process_alloc_event(); mqtt_do_publish_event = process_alloc_event(); mqtt_do_pingreq_event = process_alloc_event(); mqtt_continue_send_event = process_alloc_event(); mqtt_update_event = process_alloc_event(); list_init(mqtt_conn_list); process_start(&mqtt_process, NULL); inited = 1; } }
static void network_init(void) { struct uip_eth_addr macaddr; net_event = process_alloc_event(); #if CONFIG_DRIVERS_ENC28J60 // Set our MAC address memcpy_P(&macaddr, &mac, sizeof(mac)); // Set up ethernet enc28j60Init(&macaddr); enc28j60Write(ECOCON, 0 & 0x7); // Disable clock output _delay_ms(10); /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ // LEDA=green LEDB=yellow // // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit enc28j60PhyWrite(PHLCON, 0x476); _delay_ms(100); #endif #if CONFIG_DRIVERS_ENC424J600 // Initialise the hardware enc424j600Init(); // Disable clock output and set up LED stretch uint16_t econ2 = enc424j600ReadReg(ECON2); econ2 |= ECON2_STRCH; // stretch LED duration econ2 &= ~(ECON2_COCON3 | ECON2_COCON2 | ECON2_COCON1 | ECON2_COCON0); enc424j600WriteReg(ECON2, econ2); // Set up LEDs uint16_t eidled = enc424j600ReadReg(EIDLED); eidled &= 0x00ff; // and-out the high byte (LED config) eidled |= EIDLED_LACFG1 | EIDLED_LBCFG2 | EIDLED_LBCFG1; enc424j600WriteReg(EIDLED, eidled); // Get the MAC address enc424j600GetMACAddr(macaddr.addr); #endif #if !CONFIG_LIB_CONTIKI_IPV6 // Set up timers timer_set(&arp_timer, CLOCK_SECOND * 10); #endif uip_setethaddr(macaddr); }
// callback for receiving client's needed file ranges static void server_recv(struct broadcast_conn *c, const rimeaddr_t *from) { // store received data packet uint8_t *range_recv = (uint8_t *)packetbuf_dataptr(); //Get a pointer to the data in the packetbuf. // for debugging purposes printf("ranges received from %d.%d: '%d, %d'\n", from->u8[0], from->u8[1], range_recv[0], range_recv[1]); // allocate event that ranges are received ranges_ready = process_alloc_event(); //Allocate a global event number. // start the send files process and pass the received ranges process_post(&send_files, ranges_ready, range_recv); }
void drvr_init() { U8 part_num, ver_num, irq; U16 man_id = 0; memset(&dcb, 0, sizeof(at86_dcb_t)); delay_us(TIME_TO_ENTER_P_ON); hal_init(); // reset all regs in at86rf drvr_at86_reset(); part_num = hal_register_read(AT86_PART_NUM); ver_num = hal_register_read(AT86_VERSION_NUM); man_id |= hal_register_read(AT86_MAN_ID_1) << 8; man_id |= hal_register_read(AT86_MAN_ID_0); hal_register_write(AT86_IRQ_MASK, 0); irq = hal_register_read(AT86_IRQ_STATUS); // force transceiver off while we configure the intps hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF); delay_us(TIME_P_ON_TO_TRX_OFF); // wait for transceiver to transition to the off state while (drvr_get_trx_state() != TRX_OFF); hal_register_write(AT86_IRQ_MASK, (1<<IRQ_MASK_TRX_END) | (1<<IRQ_MASK_RX_START)); // configure the CSMA parameters drvr_config_csma(drvr_get_rand() & 0xf, drvr_get_rand() & 0xf, aMinBE, aMacMaxFrameRetries, aMaxCsmaBackoffs); // set the default channel drvr_set_channel(11); // set autocrc mode drvr_set_auto_crc(true); // start the contiki driver process and register the event number process_start(&drvr_process, NULL); event_drvr_conf = process_alloc_event(); // put trx in rx auto ack mode drvr_set_trx_state(RX_AACK_ON); while (drvr_get_trx_state() != RX_AACK_ON); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(serial_line_process, ev, data) { static char buf[BUFSIZE]; static int ptr; PROCESS_BEGIN(); serial_line_event_message = process_alloc_event(); ptr = 0; while(1) { /* Fill application buffer until newline or empty */ int c = ringbuf_get(&rxbuf); if(c == -1) { /* Buffer empty, wait for poll */ PROCESS_YIELD(); } else { if(c != END) { if(ptr < BUFSIZE-1) { buf[ptr++] = (uint8_t)c; } else { /* Ignore character (wait for EOL) */ } } else { /* Terminate */ buf[ptr++] = (uint8_t)'\0'; /* Broadcast event */ process_post(PROCESS_BROADCAST, serial_line_event_message, buf); /* Wait until all processes have handled the serial line event */ if(PROCESS_ERR_OK == process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL)) { PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE); } ptr = 0; } } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ void shell_init(void) { list_init(commands); shell_register_command(&help_command); shell_register_command(&question_command); shell_register_command(&killall_command); shell_register_command(&kill_command); shell_register_command(&null_command); shell_register_command(&exit_command); shell_register_command(&quit_command); shell_event_input = process_alloc_event(); process_start(&shell_process, NULL); process_start(&shell_server_process, NULL); front_process = &shell_process; }
// callback for receiving files static void files_recv(struct broadcast_conn *c, const rimeaddr_t *from) { process_exit(&timerout_proc); // storing file received uint8_t file_recv = *(uint8_t *)packetbuf_dataptr(); state = 2; //printf("state 2"); // debugging printf("%d", file_recv); // allocating event files_ready = process_alloc_event(); // sending event and file number received to recv_files process process_post(&recv_files, files_ready, &file_recv); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(sensors_process, ev, data) { static int i; static int events; PROCESS_BEGIN(); sensors_event = process_alloc_event(); for(i = 0; sensors[i] != NULL; ++i) { sensors_flags[i] = 0; sensors[i]->configure(SENSORS_HW_INIT, 0); } num_sensors = i; while(1) { PROCESS_WAIT_EVENT(); do { events = 0; for(i = 0; i < num_sensors; ++i) { if(sensors_flags[i] & FLAG_CHANGED) { if(process_post(PROCESS_BROADCAST, sensors_event, (void *)sensors[i]) == PROCESS_ERR_OK) { PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event); } sensors_flags[i] &= ~FLAG_CHANGED; events++; } } } while(events); } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(sensors_process, ev, data) { static int i; static int events; PROCESS_BEGIN(); for(i = 0; sensors[i] != NULL; ++i) { sensors_flags[i] = 0; sensors[i]->init(); } num_sensors = i; sensors_event = process_alloc_event(); irq_init(); while(1) { PROCESS_WAIT_EVENT(); do { events = 0; for(i = 0; i < num_sensors; ++i) { if(sensors_flags[i] & FLAG_CHANGED) { /* if(sensors_selecting_proc[i] == SELCOLL || sensors_selecting_proc[i] == NULL) process_post(PROCESS_BROADCAST, sensors_event, sensors[i]); else process_post(sensors_selecting_proc[i], sensors_event, sensors[i]);*/ if(process_post(PROCESS_BROADCAST, sensors_event, sensors[i]) == PROCESS_ERR_OK) { PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event); } sensors_flags[i] &= ~FLAG_CHANGED; events++; } } } while(events); } PROCESS_END(); }
/* * Initialize the various elements in the MAC layer. Reset the protocol * control block, start the mac process, init the events, and set the mac * info base to its default values. */ void mac_init() { mac_queue_init(); mac_indir_init(); mac_scan_init(); /* * Set up the processes. First start the mac process, * then allocate the rx event */ process_start(&mac_process, NULL); event_mac_rx = process_alloc_event(); /* init the pcb */ memset(&pcb, 0, sizeof(mac_pcb_t)); /* init the mac pib */ memset(&pib, 0, sizeof(mac_pib_t)); pib.ack_wait_duration = aMacAckWaitDuration; pib.resp_wait_time = aMacResponseWaitTime; pib.coord_addr.mode = SHORT_ADDR; pib.coord_addr.short_addr = 0xFFFF; pib.short_addr = 0xFFFF; pib.pan_id = 0xFFFF; pib.rx_on_when_idle = true; pib.assoc_permit = true; pib.max_csma_backoffs = 3; pib.min_be = 3; pib.dsn = (U8)drvr_get_rand(); #if (TEST_SIM == 1) pib.ext_addr = getpid(); #else pib.ext_addr = drvr_get_rand(); #endif /* set these in the hardware */ drvr_set_pan_id(pib.pan_id); drvr_set_short_addr(pib.short_addr); drvr_set_ext_addr(pib.ext_addr); }
/** * \brief Init function for the User button. * \param type SENSORS_ACTIVE: Activate / Deactivate the sensor (value == 1 * or 0 respectively) * * \param value Depends on the value of the type argument * \return Depends on the value of the type argument */ static int config_user(int type, int value) { switch(type) { case SENSORS_HW_INIT: button_press_duration_exceeded = process_alloc_event(); /* Software controlled */ GPIO_SOFTWARE_CONTROL(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); /* Set pin to input */ GPIO_SET_INPUT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); /* Enable edge detection */ GPIO_DETECT_EDGE(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); /* Both Edges */ GPIO_TRIGGER_BOTH_EDGES(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); ioc_set_over(BUTTON_USER_PORT, BUTTON_USER_PIN, IOC_OVERRIDE_PUE); gpio_register_callback(btn_callback, BUTTON_USER_PORT, BUTTON_USER_PIN); break; case SENSORS_ACTIVE: if(value) { GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); nvic_interrupt_enable(BUTTON_USER_VECTOR); } else { GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); nvic_interrupt_disable(BUTTON_USER_VECTOR); } return value; case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL: press_duration = (clock_time_t)value; break; default: break; } return 1; }
void ieee_init() { void *mac; MAC_Pib_s *pib; if (process_is_running(&ieee_process)) return; /* initialize ieee_eventhandler and event queue*/ rxq_init(); /* setup mac <-> app interface */ u32AppApiInit((PR_GET_BUFFER) rxq_mlme_alloc, (PR_POST_CALLBACK) ieee_process_poll, NULL, (PR_GET_BUFFER) rxq_mcps_alloc, (PR_POST_CALLBACK) ieee_process_poll, NULL); /* get mac and pib handles */ mac = pvAppApiGetMacHandle(); pib = MAC_psPibGetHandle(mac); /* do a full reset */ req_reset(true); /* set panid and default parameters */ MAC_vPibSetPanId(mac, IEEE802154_PANDID); MAC_vPibSetRxOnWhenIdle(mac, true, false); /* allocate an event for this process */ ieee_event = process_alloc_event(); pib->bAutoRequest = true; /* bandwidth control, smaller interframe gap and higher data rate, * this is not standard conform! */ #if defined(__BA2__) && defined(JENNIC_CONF_JN5148_FASTDATARATE) vAHI_BbcSetHigherDataRate(E_AHI_BBC_CTRL_DATA_RATE_1_MBPS); vAHI_BbcSetInterFrameGap(48); #endif process_start(&ieee_process, NULL); }
void mac_init() { mac_queue_init(); mac_indir_init(); mac_scan_init(); // Set up the processes. // First start the mac process, then allocate the rx event process_start(&mac_process, NULL); event_mac_rx = process_alloc_event(); // init the pcb memset(&pcb, 0, sizeof(mac_pcb_t)); // init the mac pib memset(&pib, 0, sizeof(mac_pib_t)); pib.ack_wait_duration = aMacAckWaitDuration; pib.resp_wait_time = aMacResponseWaitTime; pib.coord_addr.mode = SHORT_ADDR; pib.coord_addr.short_addr = 0xFFFF; pib.short_addr = 0xFFFF; pib.pan_id = 0xFFFF; pib.rx_on_when_idle = true; pib.assoc_permit = true; pib.max_csma_backoffs = 3; pib.min_be = 3; pib.dsn = (U8)drvr_get_rand(); #if (TEST_SIM == 1) //lint -e{732} Info 732: Loss of sign (assignment) (int to unsigned long long) pib.ext_addr = getpid(); #else pib.ext_addr = drvr_get_rand(); #endif // set these in the hardware drvr_set_pan_id(pib.pan_id); drvr_set_short_addr(pib.short_addr); drvr_set_ext_addr(pib.ext_addr); }
PROCESS_THREAD(led_on, ev, data) { static struct etimer etmr; WDTE=0xac; PROCESS_BEGIN(); etimer_set(&etmr, CLOCK_CONF_SECOND); event_led_on = process_alloc_event(); while(1) { PROCESS_WAIT_EVENT_UNTIL(ev==PROCESS_EVENT_TIMER); // offled = (~offled); // BELL = 0; process_post(&led_off, event_led_on, NULL); etimer_reset(&etmr); } PROCESS_END(); }
// callback for receiving Ns static void client_recv(struct broadcast_conn *c, const rimeaddr_t *from) { start_time = clock_time(); state = 1; // flag for receiving Ns initially if (flag==1) { // storing Ns from packet uint8_t ns_recv = *(uint8_t *)packetbuf_dataptr(); // for debugging purposes printf("*"); printf("Ns received from %d.%d: '%d'\n", from->u8[0], from->u8[1], ns_recv); // allocating event ns_ready = process_alloc_event(); // send event and Ns to client_broadcast process_post(&client_broadcast, ns_ready, &ns_recv); } }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(serial_line_process, ev, data) { PROCESS_BEGIN(); bufwptr = 0; buffer_full = 0; serial_line_event_message = process_alloc_event(); while(1) { PROCESS_YIELD(); if(buffer_full) { memcpy(appbuffer, buffer, bufwptr); process_post(PROCESS_BROADCAST, serial_line_event_message, appbuffer); bufwptr = 0; buffer_full = 0; } } PROCESS_END(); }
/*---------------------------------------------------------------------*/ PROCESS_THREAD(codeprop_process, ev, data) { PROCESS_BEGIN(); s.id = 0/*random_rand()*/; send_time = CLOCK_SECOND/4; PT_INIT(&s.udpthread_pt); PT_INIT(&s.recv_udpthread_pt); tcp_listen(HTONS(CODEPROP_DATA_PORT)); udp_conn = udp_broadcast_new(HTONS(CODEPROP_DATA_PORT), NULL); codeprop_event_quit = process_alloc_event(); s.state = STATE_NONE; s.received = 0; s.addr = 0; s.len = 0; while(1) { PROCESS_YIELD(); if(ev == EVENT_START_PROGRAM) { /* First kill old program. */ elfloader_unload(); elfloader_load(EEPROMFS_ADDR_CODEPROP); } else if(ev == tcpip_event) { uipcall(data); } else if(ev == PROCESS_EVENT_TIMER) { tcpip_poll_udp(udp_conn); } } PROCESS_END(); }
PROCESS_THREAD(accel_process, ev, data) { PROCESS_BEGIN(); { int16_t x, y, z; serial_shell_init(); shell_ps_init(); shell_file_init(); // for printing out files shell_text_init(); // for binprint /* Register the event used for lighting up an LED when interrupt strikes. */ ledOff_event = process_alloc_event(); /* Start and setup the accelerometer with default values, eg no interrupts enabled. */ accm_init(); /* Register the callback functions for each interrupt */ ACCM_REGISTER_INT1_CB(accm_ff_cb); ACCM_REGISTER_INT2_CB(accm_tap_cb); /* Set what strikes the corresponding interrupts. Several interrupts per pin is possible. For the eight possible interrupts, see adxl345.h and adxl345 datasheet. */ accm_set_irq(ADXL345_INT_FREEFALL, ADXL345_INT_TAP + ADXL345_INT_DOUBLETAP); while (1) { x = accm_read_axis(X_AXIS); y = accm_read_axis(Y_AXIS); z = accm_read_axis(Z_AXIS); printf("x: %d y: %d z: %d\n", x, y, z); etimer_set(&et, ACCM_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); } } PROCESS_END(); }
PROCESS_THREAD(proc_epoch_syncer, ev, data) { static struct etimer send_timer; static struct etimer epoch_timer; static const struct broadcast_callbacks broadcast_cbs = {__broadcast_recv_cb, __broadcast_sent_cb}; static struct broadcast_conn conn; PROCESS_EXITHANDLER(broadcast_close(&conn)); PROCESS_BEGIN(); #ifdef TRACK_CONNECTIONS /* Log the node id */ printf("board-id64 0x%.16llx\n", board_get_id64()); #endif #ifdef XFER_CRC16 /* Log the node id */ printf("xfer crc16\n"); #endif printf("epoch interval %ld ticks\n", EPOCH_INTERVAL); /* * Alloc the two syncer events */ evt_epoch_synced = process_alloc_event(); evt_end_of_epoch = process_alloc_event(); /* * Open a `connection` on the syncer broadcasting channel */ broadcast_open(&conn, BROADCAST_CHANNEL_TIMESYNC, &broadcast_cbs); /* * init the epoch-syncer instance */ epoch_syncer_init(&__epoch_syncer); /* * This is the main syncer loop. Initially we try to sync the * epoch between nodes without concurrently running any other * algo. After a period, at which time the network is synced, * we start generating epoch events which can be * consumed by, e.g., the estimator process. */ etimer_set(&epoch_timer, __epoch_syncer.epoch_interval); __epoch_syncer.epoch_start_time = clock_time(); __epoch_syncer.epoch_end_time = etimer_expiration_time(&epoch_timer); while (1) { /* * The start of a new epoch ! */ epoch_syncer_at_epoch_start(&__epoch_syncer); clock_time_t now; clock_time_t time_to_epoch_end; now = clock_time(); assert(__epoch_syncer.epoch_end_time == etimer_expiration_time(&epoch_timer)); assert(__epoch_syncer.epoch_end_time > now); time_to_epoch_end = __epoch_syncer.epoch_end_time - now; /* * Setup a random wait time before sending the sync packet * * ! we cannot let send_timer delay the epoch_timer, especially * when the next `end-of-epoch-time` has been anticipated by a lot * (this can happen at startup) */ if (time_to_epoch_end > __epoch_syncer.epoch_sync_start) { long int send_wait; long int send_wait_rnd; long int rnd; rnd = rand(); send_wait_rnd = (unsigned)rnd % (unsigned) __epoch_syncer.epoch_sync_xfer_interval; send_wait = __epoch_syncer.epoch_sync_start + send_wait_rnd; assert(send_wait >= __epoch_syncer.epoch_sync_start); assert(send_wait <= __epoch_syncer.epoch_sync_start + __epoch_syncer.epoch_sync_xfer_interval); if (send_wait > time_to_epoch_end) send_wait = __epoch_syncer.epoch_sync_start; assert(send_wait < time_to_epoch_end); etimer_set(&send_timer, send_wait); PROCESS_WAIT_UNTIL(etimer_expired(&send_timer)); /* * Acquire the radio lock * * ! we don't use WAIT/YIELD_UNTIL() because * 1) we do not want to yield if we can acquire the lock on the first try * 2) no kernel signal is generated when the lock is released (we would `deadlock') */ do { if (!radio_trylock()) break; PROCESS_PAUSE(); } while (1); { clock_time_t now; struct epoch_sync_packet packet; /* * broadcast the sync packet * * ! We put this part into its own block since non static stack * variables/allocations in the parent block wouldn't get preserved trough * kernel calls (e.g. the PROCESS_PAUSE() a few lines above) */ #ifdef TRACK_CONNECTIONS packet.board_id16 = board_get_id16(); #endif packet.epoch = __epoch_syncer.epoch; now = clock_time(); assert(now > __epoch_syncer.epoch_start_time); assert(__epoch_syncer.epoch_end_time > now); packet.time_from_epoch_start = now - __epoch_syncer.epoch_start_time; packet.time_to_epoch_end = __epoch_syncer.epoch_end_time - now; #ifdef XFER_CRC16 /* * Compute the packet crc with the .crc16 field zeroed */ { uint16_t crc16; packet.crc16 = 0; crc16 = crc16_data((const unsigned char *)&packet, sizeof(struct epoch_sync_packet), 0); packet.crc16 = crc16; } #endif packetbuf_copyfrom(&packet, sizeof(struct epoch_sync_packet)); broadcast_send(&conn); } } else { printf("epoch-syncer: skipping sync send\n"); } /* * We cannot YIELD here: if epoch_timer has already expired there won't be * any event to wake us up. * * FIXME: if we get here and the epoch timer has fired * already print by how much we are late: this can be terribly useful * to trace bugs in the epoch sync code or the kernel. */ if (etimer_expired(&epoch_timer)) { long int now; now = clock_time(); assert(now > __epoch_syncer.epoch_end_time); } else { char do_wait; do_wait = 1; if (__epoch_syncer.sum_sync_offsets) { long int avg_offset = __epoch_syncer.sum_sync_offsets / __epoch_syncer.nr_offsets; const long int threshold = CLOCK_SECOND; if (avg_offset > threshold) { /* * if we are late don't wait until the timer expires * ! this migth give us the opportunity to re-enter the right sync_xfer_interval */ do_wait = 0; } else if (avg_offset < -threshold) { /* * we are too fast, delay end of epoch */ clock_time_t now; clock_time_t time_to_epoch_end; now = clock_time(); assert(__epoch_syncer.epoch_end_time == etimer_expiration_time(&epoch_timer)); assert(__epoch_syncer.epoch_end_time > now); time_to_epoch_end = __epoch_syncer.epoch_end_time - now; long int delay = time_to_epoch_end + (-avg_offset/2); static struct etimer delay_timer; trace("epoch-syncer: delaying end-of-epoch by %ld ticks\n", (-avg_offset/2)); etimer_set(&delay_timer, delay); __epoch_syncer.epoch_end_time += (-avg_offset/2); PROCESS_WAIT_UNTIL(etimer_expired(&delay_timer)); } } if (do_wait) { PROCESS_WAIT_UNTIL(etimer_expired(&epoch_timer)); } else { trace("epoch-syncer: not waiting for end-of-epoch\n"); } } trace("epoch-syncer: epoch %d ended\n", __epoch_syncer.epoch); #ifdef TRACK_CONNECTIONS connection_print_and_zero(CONNECTION_TRACK_SYNC, __epoch_syncer.epoch); #endif /* * Re-Set the end-of-epoch timer */ if (__epoch_syncer.epoch == EPOCHS_UNTIL_SYNCED) { /* * We have hopefully achieved sync at this point * * 1) update the epoch timings, and set the epoch timer * * 2) signal the size-estimator process that the epoch is now synced */ __epoch_syncer.epoch_interval = EPOCH_INTERVAL; __epoch_syncer.epoch_sync_start = EPOCH_SYNC_START; __epoch_syncer.epoch_sync_xfer_interval = EPOCH_SYNC_XFER_INTERVAL; etimer_stop(&epoch_timer); etimer_set(&epoch_timer, __epoch_syncer.epoch_interval); /* * The epoch timer has been re-set: update the time until the next epoch end * Increase the epoch count. * ! these operations must happen in a block which cannot block in kernel calls */ __epoch_syncer.epoch_start_time = clock_time(); __epoch_syncer.epoch_end_time = etimer_expiration_time(&epoch_timer); __epoch_syncer.epoch++; process_post(&proc_size_estimator, evt_epoch_synced, NULL); } else { /* * Re-set and adjust the epoch timer using the data received trough sync packets * (in this epoch) * * ! using re-set (instead of, e.g., restart) is important here in order to avoid * drifting */ etimer_reset(&epoch_timer); /* * The epoch timer has been re-set: update the time until the next epoch end * Increase the epoch count. * ! these operations must happen in a block which cannot block in kernel calls */ //__epoch_syncer.epoch_start_time = epoch_timer.timer.start; __epoch_syncer.epoch_start_time = clock_time(); __epoch_syncer.epoch_end_time = etimer_expiration_time(&epoch_timer); __epoch_syncer.epoch++; if (__epoch_syncer.sum_sync_offsets) { long int avg_offset = __epoch_syncer.sum_sync_offsets / __epoch_syncer.nr_offsets; const long int threshold = 1;//(CLOCK_SECOND/32);//*3; #if __CONTIKI_NETSTACK_RDC==__CONTIKI_NETSTACK_RDC_NULL const int tx_delay = 0; #elif __CONTIKI_NETSTACK_RDC==__CONTIKI_NETSTACK_RDC_CXMAC /* * When the cxmac RDC is used we must consider an added delay due to the fact that when * other nodes radios are turned off the sync packet must be re-sent. */ const int tx_delay = 8; #endif /* * estimate the avg tx delay */ avg_offset += tx_delay; trace("epoch-syncer: sync offsets %d ~ %ld < %ld < %ld\n", __epoch_syncer.nr_offsets, __epoch_syncer.min_offset + tx_delay, avg_offset, __epoch_syncer.max_offset+tx_delay); if ((avg_offset < -threshold) || (avg_offset > threshold)) { clock_time_t new_expiration_time; const long int adjust_threshold = CLOCK_SECOND/2; long int adjust; /* * feedback control the next expiration time */ adjust = -avg_offset/2; adjust = min(adjust, adjust_threshold); adjust = max(adjust, -adjust_threshold); if (adjust) etimer_adjust(&epoch_timer, adjust); new_expiration_time = etimer_expiration_time(&epoch_timer); __epoch_syncer.epoch_end_time = new_expiration_time; } } if (__epoch_syncer.epoch > EPOCHS_UNTIL_SYNCED) { /* * Signal the estimator-process that this epoch has ended */ process_post(&proc_size_estimator, evt_end_of_epoch, NULL); } } } PROCESS_END(); }
/* this process handle the reception of messages */ PROCESS_THREAD(delugeGroupP, ev, data) { int fd; char* buf; uint8_t nr_pages_local; static struct etimer et; static struct jsonparse_state jsonState; static ContainerRoot * newModel; static uip_ipaddr_t addr; PROCESS_BEGIN(); /* keep track of the singleton instance */ instance = (DelugeGroup*)data; /* register new event types */ NEW_AVAILABLE_OA_MODEL = process_alloc_event(); NEW_OA_MODEL_DOWNLOADED = process_alloc_event(); /* initialize model announcement's system */ simple_udp_register(&deluge_group_broadcast, 34555, NULL, 34555, model_version_recv); /* set announcement's initial value*/ instance->info.version = 0; instance->info.nr_pages = 0; /* set timer for announcements */ etimer_set(&et, CLOCK_SECOND * instance->interval); while (1) { /* Listen for announcements every interval seconds. */ PROCESS_WAIT_EVENT(); if (ev == PROCESS_EVENT_TIMER) { /* announce my model */ uip_create_linklocal_allnodes_mcast(&addr); simple_udp_sendto(&deluge_group_broadcast, &instance->info, sizeof(struct ModelInfo), &addr); etimer_restart(&et); } else if (ev == NEW_AVAILABLE_OA_MODEL){ /* receive the new over the air model */ /* contains the number of pages */ nr_pages_local = instance->info.nr_pages; /* create the file with the required number of pages */ cfs_remove(instance->fileNameWithModel); fd = cfs_open(instance->fileNameWithModel, CFS_WRITE); buf = (char*) malloc(S_PAGE); memset(buf, '0' , S_PAGE); PRINTF("Number of pages is %d\n", nr_pages_local); while(nr_pages_local) { cfs_seek(fd, 0, CFS_SEEK_END); cfs_write(fd, buf, S_PAGE); nr_pages_local--; } free(buf); cfs_close(fd); /* Deluge-based dissemination */ if (deluge_disseminate(instance->fileNameWithModel, 0, modelDownloaded)) { PRINTF("ERROR: some problem waiting for new version of the file\n"); } else { PRINTF("INFO: Waiting for new version of the file \n"); } } else if (ev == NEW_OA_MODEL_DOWNLOADED) { /* deserialize the model received over the air */ PRINTF("New model %s received in group with instance %p\n", instance->fileNameWithModel, instance); newModel = NULL; /* TODO: check if the file exists */ /* parse model from json file */ jsonparse_setup(&jsonState, instance->fileNameWithModel); newModel = JSONKevDeserializer(&jsonState, jsonparse_next(&jsonState)); cfs_close(jsonState.fd); PRINTF("INFO: Deserialization finished in Deluge Group %p\n", newModel); /* save a reference to the new model */ instance->lastReceivedModel = newModel; /* Afterwards, just call notifyNewModel */ if (newModel != NULL && notifyNewModel(newModel) == PROCESS_ERR_OK) { PRINTF("INFO: Model was successfully sent\n"); } else { PRINTF("ERROR: The model cannot be loaded!\n"); } } } PROCESS_END(); }
process_event_t wismo218_command_event; static wismo218_status_t WismoStatus; static arnGsmRemoteCommand_t* CurrentCommand; PROCESS(commandmanager_process, "CommandManager"); //AUTOSTART_PROCESSES(&commandmanager_process); PROCESS_THREAD(commandmanager_process, ev, data) { PROCESS_EXITHANDLER(goto exit); PROCESS_BEGIN(); wismo218_command_event = process_alloc_event(); WismoStatus = init_none; printf("CommandManager started.\n\r"); while(1) { PROCESS_WAIT_EVENT(); if (ev == serial_line_event_message) { if (data != NULL) { char* Dt = data; char* CommandParameters; CurrentCommand = arnCommand(Dt); //printf("%s:%s\n\r",__FUNCTION__,Dt); if ((WismoStatus == init_done) && CurrentCommand) { char* pres; CommandParameters = arnCommandParameters(CurrentCommand,Dt); if (CurrentCommand->Command_handler) {
PROCESS_THREAD(cetic_6lbr_process, ev, data) { static struct etimer timer; static int addr_number; PROCESS_BEGIN(); /* Step 0: Basic infrastructure initialization */ LOG6LBR_NOTICE("Starting 6LBR version " CETIC_6LBR_VERSION " (" CONTIKI_VERSION_STRING ")\n"); //Turn off radio until 6LBR is properly configured NETSTACK_MAC.off(0); cetic_6lbr_restart_event = process_alloc_event(); cetic_6lbr_reload_event = process_alloc_event(); cetic_6lbr_startup = clock_seconds(); #if CETIC_6LBR_MULTI_RADIO network_itf_init(); #endif /* Step 1: Platform specific initialization */ platform_init(); /* Step 2: Register configuration hooks and set default configuration */ #if CETIC_6LBR_NODE_INFO node_info_config(); #endif /* Step 3: Load configuration from NVM and configuration file */ platform_load_config(CONFIG_LEVEL_BOOT); #if !LOG6LBR_STATIC if(nvm_data.log_level != 0xFF) { Log6lbr_level = nvm_data.log_level; Log6lbr_services = nvm_data.log_services; } LOG6LBR_NOTICE("Log level: %d (services: %x)\n", Log6lbr_level, Log6lbr_services); #else LOG6LBR_NOTICE("Log level: %d (services: %x)\n", LOG6LBR_LEVEL, LOG6LBR_SERVICE_DEFAULT); #endif /* Step 4: Initialize radio and network interfaces */ #if CETIC_6LBR_FRAMER_WRAPPER framer_wrapper_init(); #endif #if CETIC_6LBR_MAC_WRAPPER mac_wrapper_init(); #endif #if CETIC_6LBR_MULTI_RADIO CETIC_6LBR_MULTI_RADIO_DEFAULT_MAC.init(); #endif #if !CETIC_6LBR_ONE_ITF platform_radio_init(); while(!radio_ready) { PROCESS_PAUSE(); } #endif eth_drv_init(); while(!ethernet_ready) { PROCESS_PAUSE(); } //Turn on radio and keep it always on NETSTACK_MAC.off(1); /* Step 5: Initialize Network stack */ #if CETIC_6LBR_LLSEC_WRAPPER #if CETIC_6LBR_WITH_ADAPTIVESEC llsec_strategy_wrapper_init(); #endif llsec_wrapper_init(); #endif #if CETIC_6LBR_MULTICAST_WRAPPER multicast_wrapper_init(); #endif //6LoWPAN init memcpy(addr_contexts[0].prefix, nvm_data.wsn_6lowpan_context_0, sizeof(addr_contexts[0].prefix)); //clean up any early packet uip_len = 0; process_start(&tcpip_process, NULL); PROCESS_PAUSE(); /* Step 6: Configure network interfaces */ packet_filter_init(); cetic_6lbr_init(); //Wait result of DAD on 6LBR addresses addr_number = uip_ds6_get_addr_number(-1); LOG6LBR_INFO("Checking addresses duplication\n"); etimer_set(&timer, CLOCK_SECOND); while(uip_ds6_get_addr_number(ADDR_TENTATIVE) > 0) { PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); etimer_set(&timer, CLOCK_SECOND); } //Can not use equality as autoconf address could be created when running DAD if(uip_ds6_get_addr_number(-1) < addr_number) { LOG6LBR_FATAL("Addresses duplication failed\n"); cetic_6lbr_restart_type = CETIC_6LBR_RESTART; platform_restart(); } /* Step 7: Finalize configuration of network interfaces */ cetic_6lbr_init_finalize(); /* Step 8: Initialize 6LBR core and base applications */ platform_load_config(CONFIG_LEVEL_CORE); PROCESS_PAUSE(); #if CETIC_6LBR_WITH_WEBSERVER webserver_init(); #endif #if CETIC_6LBR_NODE_INFO node_info_init(); #endif #if CETIC_6LBR_NODE_CONFIG node_config_init(); #endif /* Step 9: Initialize and configure 6LBR applications */ platform_load_config(CONFIG_LEVEL_BASE); PROCESS_PAUSE(); #if CETIC_6LBR_WITH_UDPSERVER udp_server_init(); #endif #if UDPCLIENT process_start(&udp_client_process, NULL); #endif #if WITH_TINYDTLS dtls_init(); #endif #if WITH_COAPSERVER if((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_COAP_SERVER) == 0) { coap_server_init(); } #endif #if WITH_DTLS_ECHO process_start(&dtls_echo_server_process, NULL); #endif #if CETIC_6LBR_WITH_NVM_PROXY nvm_proxy_init(); #endif #if CETIC_6LBR_WITH_DNS_PROXY dns_proxy_init(); #endif /* Step 10: Finalize platform configuration and load runtime configuration */ platform_finalize(); platform_load_config(CONFIG_LEVEL_APP); LOG6LBR_INFO("CETIC 6LBR Started\n"); PROCESS_WAIT_EVENT_UNTIL(ev == cetic_6lbr_restart_event); etimer_set(&timer, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); /* Shutdown 6LBR */ //Turn off radio NETSTACK_MAC.off(0); platform_restart(); PROCESS_END(); }
SOL_API struct sol_spi * sol_spi_open(unsigned int bus, const struct sol_spi_config *config) { struct sol_spi *spi; qm_spi_t max_bus_available; int ret; SOL_LOG_INTERNAL_INIT_ONCE; /* QM_SPI_NUM is always considering that both master and the slave * exist, so we can't use it to check the valid buses to use */ #if QUARK_SE max_bus_available = QM_SPI_MST_1; #else max_bus_available = QM_SPI_MST_0; #endif SOL_EXP_CHECK(bus >= max_bus_available, NULL); SOL_NULL_CHECK(config, NULL); #ifndef SOL_NO_API_VERSION if (unlikely(config->api_version != SOL_SPI_CONFIG_API_VERSION)) { SOL_WRN("Couldn't open SPI that has unsupported version '%u', " "expected version is '%u'", config->api_version, SOL_SPI_CONFIG_API_VERSION); return NULL; } #endif if (config->chip_select > 3) { SOL_WRN("Invalid chip_select value '%u'. Value must be between 0 and 3.", config->chip_select); return NULL; } if ((config->bits_per_word < 4) || (config->bits_per_word > 32)) { SOL_WRN("Invalid bits_per_word value '%" PRIu8 "'. Value must be " "between 4 and 32.", config->bits_per_word); return NULL; } spi = calloc(1, sizeof(*spi)); SOL_NULL_CHECK(spi, NULL); if (!spi_irq_event) { bool r; spi_irq_event = process_alloc_event(); r = sol_mainloop_contiki_event_handler_add(&spi_irq_event, NULL, spi_cb_dispatch, NULL); SOL_EXP_CHECK_GOTO(!r, error); } spi->bus = bus; spi->slave = BIT(config->chip_select); spi->config.frame_size = config->bits_per_word - 1; spi->config.transfer_mode = QM_SPI_TMOD_TX_RX; spi->config.bus_mode = config->mode; spi->config.clk_divider = 32000000 / config->frequency; switch (spi->bus) { case QM_SPI_MST_0: clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_SPI_M0_REGISTER); qm_irq_request(QM_IRQ_SPI_MASTER_0, qm_spi_master_0_isr); break; #if QUARK_SE case QM_SPI_MST_1: qm_irq_request(QM_IRQ_SPI_MASTER_1, qm_spi_master_1_isr); break; #endif case QM_SPI_SLV_0: case QM_SPI_NUM: /* We checked if we were passed the limit before, so we should never * hit this point. Using all the enum values and no default, however, * allows us to rely on the compiler to know if there are values * we are not considering (depending on warning levels) */ break; } ret = spi_set_gpio_ss(spi); SOL_INT_CHECK_GOTO(ret, < 0, error); return spi; error: free(spi); return NULL; }
int init_knot_network(){ KNOT_EVENT_SERVICE_FOUND = process_alloc_event(); KNOT_EVENT_DATA_READY = process_alloc_event(); init_link_layer(); return 1; }
SOL_API struct sol_i2c * sol_i2c_open_raw(uint8_t bus, enum sol_i2c_speed speed) { struct sol_i2c *i2c; qm_i2c_config_t cfg; qm_i2c_speed_t bus_speed; qm_rc_t ret; if (bus >= QM_I2C_NUM) { SOL_WRN("I2C bus #%" PRIu8 " doesn't exist.", bus); return NULL; } if ((i2c = buses[bus]) != NULL) return i2c; switch (speed) { case SOL_I2C_SPEED_10KBIT: case SOL_I2C_SPEED_100KBIT: bus_speed = QM_I2C_SPEED_STD; break; case SOL_I2C_SPEED_400KBIT: bus_speed = QM_I2C_SPEED_FAST; break; case SOL_I2C_SPEED_1MBIT: case SOL_I2C_SPEED_3MBIT_400KBIT: bus_speed = QM_I2C_SPEED_FAST_PLUS; break; default: SOL_WRN("Unsupported speed value: %d", speed); return NULL; }; switch (bus) { case QM_I2C_0: qm_irq_request(QM_IRQ_I2C_0, qm_i2c_0_isr); clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_I2C_M0_REGISTER); break; #if QUARK_SE case QM_I2C_1: qm_irq_request(QM_IRQ_I2C_1, qm_i2c_1_isr); clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_I2C_M1_REGISTER); break; #endif case QM_I2C_NUM: /* We checked if we were passed the limit before, so we should never * hit this point. Using all the enum values and no default, however, * allows us to rely on the compiler to know if there are values * we are not considering (depending on warning levels) */ break; } i2c = calloc(1, sizeof(*i2c)); SOL_NULL_CHECK(i2c, NULL); i2c->bus = bus; ret = qm_i2c_get_config(i2c->bus, &cfg); SOL_EXP_CHECK_GOTO(ret != QM_RC_OK, error); cfg.speed = bus_speed; cfg.address_mode = QM_I2C_7_BIT; cfg.mode = QM_I2C_MASTER; cfg.slave_addr = 0; ret = qm_i2c_set_config(i2c->bus, &cfg); SOL_EXP_CHECK_GOTO(ret != QM_RC_OK, error); if (!i2c_irq_event) { bool r; i2c_irq_event = process_alloc_event(); r = sol_mainloop_contiki_event_handler_add(&i2c_irq_event, NULL, i2c_cb_dispatch, NULL); SOL_EXP_CHECK_GOTO(!r, error); } buses[i2c->bus] = i2c; return i2c; error: free(i2c); return NULL; }
PROCESS_THREAD(cetic_6lbr_process, ev, data) { PROCESS_BEGIN(); cetic_6lbr_restart_event = process_alloc_event(); cetic_6lbr_startup = clock_seconds(); #if CONTIKI_TARGET_NATIVE slip_config_handle_arguments(contiki_argc, contiki_argv); if (watchdog_interval) { process_start(&native_6lbr_watchdog, NULL); } else { LOG6LBR_WARN("6LBR Watchdog disabled\n"); } #endif LOG6LBR_INFO("Starting 6LBR version " CETIC_6LBR_VERSION " (" CONTIKI_VERSION_STRING ")\n"); load_nvm_config(); platform_init(); process_start(ð_drv_process, NULL); while(!ethernet_ready) { PROCESS_PAUSE(); } //clean up any early packet uip_len = 0; process_start(&tcpip_process, NULL); PROCESS_PAUSE(); #if CETIC_NODE_INFO node_info_init(); #endif packet_filter_init(); cetic_6lbr_init(); #if WEBSERVER process_start(&webserver_nogui_process, NULL); #endif #if UDPSERVER process_start(&udp_server_process, NULL); #endif #if UDPCLIENT process_start(&udp_client_process, NULL); #endif #if WITH_COAP process_start(&coap_server_process, NULL); #endif #if WITH_NVM_PROXY nvm_proxy_init(); #endif #if CONTIKI_TARGET_NATIVE plugins_load(); #endif LOG6LBR_INFO("CETIC 6LBR Started\n"); PROCESS_WAIT_EVENT_UNTIL(ev == cetic_6lbr_restart_event); etimer_set(&reboot_timer, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); #if CONTIKI_TARGET_NATIVE switch (cetic_6lbr_restart_type) { case CETIC_6LBR_RESTART: LOG6LBR_INFO("Exiting...\n"); exit(0); break; case CETIC_6LBR_REBOOT: LOG6LBR_INFO("Rebooting...\n"); system("reboot"); break; case CETIC_6LBR_HALT: LOG6LBR_INFO("Halting...\n"); system("halt"); break; default: //We should never end up here... exit(1); } //We should never end up here... exit(1); #else LOG6LBR_INFO("Rebooting...\n"); watchdog_reboot(); #endif PROCESS_END(); }