Beispiel #1
0
void error(err_t code) {
#if defined(UNIX) || defined(__CC65__)
  printf("NanoVM error: %s\n", error_msg[code]);
  exit(-1);
#else

  uart_putc('E');
  uart_putc('R');
  uart_putc('R');
  uart_putc(':');
  uart_putc('A'+code);
  uart_putc('\n');

  for(;;) {
    // reset watchdog here if in use

#ifdef ASURO
    // yellow/red blinking status led
    PORTD |= _BV(2);
    PORTB |= _BV(0);
    delay(MILLISEC(250));
    PORTB &= ~_BV(0);
    delay(MILLISEC(250));
#endif
  }
#endif
}
Beispiel #2
0
/*
 * radar_update_bmap
 *
 * updates the bnode map of the given `level' the root_node bnode in the bmap
 * will also point to the gnode of level `gnode_level'+1 that is
 * `rq'->quadg.gnode[_EL(gnode_level+1)].
 */
void
radar_update_bmap(struct radar_queue *rq, int level, int gnode_level)
{
    map_gnode *gnode;
    map_node *root_node;
    map_rnode *rnode, rn;
    int bm, rnode_pos, root_node_pos;
    void *void_map;

    if (level == me.cur_quadg.levels - 1)
        return;

    qspn_set_map_vars(level, 0, &root_node, &root_node_pos, 0);
    void_map = me.ext_map;
    gnode = rq->quadg.gnode[_EL(gnode_level + 1)];

    bm = map_find_bnode(me.bnode_map[level], me.bmap_nodes[level],
                        root_node_pos);
    if (bm == -1) {
        bm = map_add_bnode(&me.bnode_map[level], &me.bmap_nodes[level],
                           root_node_pos, 0);
        rnode_pos = -1;
    } else
        rnode_pos = rnode_find(&me.bnode_map[level][bm], &gnode->g);

    if (rnode_pos == -1) {
        setzero(&rn, sizeof(map_rnode));
        rn.r_node = (int *) &gnode->g;
        rnode_add(&me.bnode_map[level][bm], &rn);
        rnode_pos = 0;
    }

    rnode = &me.bnode_map[level][bm].r_node[rnode_pos];
    rnode->trtt = MILLISEC(rq->final_rtt);
}
Beispiel #3
0
/*
 * final_radar_queue
 *
 * analyses the received ECHO_REPLY pkt and write the
 * average rtt of each found node in the radar_queue.
 */
void
final_radar_queue(void)
{
    struct radar_queue *rq;
    int e;
    struct timeval sum;
    u_int f_rtt;

    setzero(&sum, sizeof(struct timeval));

    rq = radar_q;
    list_for(rq) {
        if (!rq->node)
            continue;

        /* Sum the rtt of all the received pongs */
        for (e = 0; e < rq->pongs; e++)
            timeradd(&rq->rtt[e], &sum, &sum);

        /* Add penality rtt for each pong lost */
        for (; e < MAX_RADAR_SCANS; e++)
            timeradd(&rq->rtt[e - rq->pongs], &sum, &sum);

        f_rtt = MILLISEC(sum) / MAX_RADAR_SCANS;
        MILLISEC_TO_TV(f_rtt, rq->final_rtt);
    }

    my_echo_id = 0;
}
Beispiel #4
0
void error(err_t code) {
#if defined(UNIX) || defined(__CC65__)
  printf("NanoVM error: %s\n", error_msg[code]);
  exit(-1);
#else

  uart_putc('E');
  uart_putc('R');
  uart_putc('R');
  uart_putc(':');
  uart_putc('A'+code);
  uart_putc('\n');

  for(;;) {
    // reset watchdog here if in use

#ifdef ASURO
    // yellow/red blinking status led
    PORTD |= _BV(2);
    PORTB |= _BV(0);
    delay(MILLISEC(250));
    PORTB &= ~_BV(0);
    delay(MILLISEC(250));
#endif

#ifdef NIBOBEE
    uint8_t cnt;
    for (cnt=5; cnt; cnt--) {
      PORTB &= 0xf0;
      PORTB |= _BV(1);
      _delay_ms(100);
      PORTB &= 0xf0;
      PORTB &= _BV(2);
      _delay_ms(100);
    }
    PORTB &= 0xf0;
    _delay_ms(1000);
    PORTB |= 0x0f&code;
    _delay_ms(1000);
#endif
  }

  
#endif
}
Beispiel #5
0
/*
 * radar_exec_reply
 *
 * It reads the received ECHO_REPLY pkt and updates the radar
 * queue, storing the calculated rtt and the other infos relative to the sender
 * node.
 */
int
radar_exec_reply(PACKET pkt)
{
    struct timeval t;
    struct radar_queue *rq;
    u_int rtt_ms = 0;
    int dev_pos;

    gettimeofday(&t, 0);

    /*
     * Get the radar_queue struct relative to pkt.from
     */
    rq = add_radar_q(pkt);

    dev_pos = ifs_get_pos(me.cur_ifs, me.cur_ifs_n, pkt.dev);
    if (dev_pos < 0)
        debug(DBG_NORMAL, "The 0x%x ECHO_REPLY pkt was received by a non "
              "existent interface", pkt.hdr.id);

    if (me.cur_node->flags & MAP_HNODE) {
        if (pkt.hdr.flags & HOOK_PKT) {
            u_char scanning;
            memcpy(&scanning, pkt.msg, sizeof(u_char));

            /*
             * If the pkt.from node has finished his scan, and we
             * never received one of its ECHO_ME pkts, and we are
             * still scanning, set the hook_retry.
             */
            if (!scanning && !rq->pings &&
                    (radar_scan_mutex ||
                     radar_scans[dev_pos] <= MAX_RADAR_SCANS)) {
                hook_retry = 1;
            }
        }
    }

    if (rq->pongs < radar_scans[dev_pos]) {
        timersub(&t, &scan_start, &rq->rtt[(int) rq->pongs]);
        /*
         * Now we divide the rtt, because (t - scan_start) is the time
         * the pkt used to reach B from A and to return to A from B
         */
        rtt_ms = MILLISEC(rq->rtt[(int) rq->pongs]) / 2;
        MILLISEC_TO_TV(rtt_ms, rq->rtt[(int) rq->pongs]);

        rq->pongs++;
    }

    return 0;
}
int main(void)
/*****************************************************************************
*   Input    :
*   Output   :
*   Function : The super loop.
******************************************************************************/
{
  INT8U event;
  INT8U counter_value;

  disable_global_int();
  init_systick();
  init_gpio();
  enable_global_int();


  // Loop forever.
  while(1)
  {
	// System part of the super loop.
	// ------------------------------
	while( !ticks );


	// The following will be executed every 5mS
	ticks--;

	if( ! --alive_timer )
	{
    	alive_timer =	MILLISEC( 500 );
	  	GPIO_PORTD_DATA_R ^= 0x40;
	}

    // Protected operating system mode
    swt_ctrl();

    // Application mode
    task_rtc( TASK_RTC );
    task_button( TASK_BUTTON );
    task_set_time( TASK_SET_TIME );
    task_lcd( TASK_LCD );
  }
}
Beispiel #7
0
void native_nvmcomm_invoke(u08_t mref) {
  if(mref == NATIVE_METHOD_SEND) {
    uint8_t len = (uint8_t)stack_pop_int();
    uint8_t *buf = (uint8_t *)stack_pop_addr();
    uint8_t dest = (uint8_t)stack_pop_int();
    DEBUGF_COMM("native send to "DBG8"\n", dest);
    DEBUGF_COMM(""DBG8" bytes:", len);
    for (uint8_t i=1; i<len+1; i++)
      DEBUGF_COMM("["DBG8"] ", buf[i]);
    DEBUGF_COMM("\n");
    stack_push(nvmcomm_send(dest, NVMCOMM_CMD_APPMSG, buf+1, len)); // +1 to skip the first byte which indicates the type of the array
  } else if(mref == NATIVE_METHOD_RECEIVE) {
    nvm_int_t waitmsec=stack_pop_int();
    DEBUGF_COMM("native nvmcomm.receive: waiting "DBG16" msec\n", waitmsec);
    while (nvc3_appmsg_size==0 && waitmsec>0) {
      delay(MILLISEC(1));
      // Check if there's any packet coming in that we need to handle before processing the next VM instruction.
      // Need to do this here because the VM's main loop is stopped.
      // TODO: Reconsider this when we have a better design for receiving messages.
      nvmcomm_poll();
      waitmsec--;
    }
    if (nvc3_appmsg_size==0) {
      // Nothing was received, return NULL;
      stack_push(0);
      DEBUGF_COMM("native nvmcomm.receive: timeout\n");
    } else {
      DEBUGF_COMM("native nvmcomm.receive: received "DBG8" bytes\n", nvc3_appmsg_size);
      // TODO: copy the data to a Java array and return it.
      heap_id_t array = array_new(nvc3_appmsg_size, T_BYTE);
      for (uint8_t i=0; i<nvc3_appmsg_size; i++)
        array_bastore(array, i, nvc3_appmsg_buf[i]);
      stack_push(array | NVM_TYPE_HEAP);
      nvc3_appmsg_size = 0; // Buffer available for next message
    }
  } else
    error(ERROR_NATIVE_UNKNOWN_METHOD);
}
Beispiel #8
0
void uart_write_byte(u08_t byte) {
  /* Wait for empty transmit buffer */
  while(!(UCSRA & _BV(UDRE)));

  // asuro needs echo cancellation, since the ir receiver "sees"
  // the transmitter
#ifdef ASURO
  // disable receiver
  UCSRB &= ~(_BV(RXEN) | _BV(RXCIE));
#endif

  // start transmission
  UDR = byte;

#ifdef ASURO
  // Wait for empty transmit buffer
  while(!(UCSRA & _BV(UDRE)));
  delay(MILLISEC(5));

  // re-enable receiver
  UCSRB |= _BV(RXEN) | _BV(RXCIE);
#endif
}
#include "systick.h"
#include "gpio.h"
#include "swtimers.h"
#include "task_rtc.h"
#include "task_button.h"
#include "task_lcd.h"
#include "task_set_time.h"


/*****************************    Defines    *******************************/

/*****************************   Constants   *******************************/

/*****************************   Variables   *******************************/
extern volatile INT16S ticks;
INT16S alive_timer = MILLISEC(500);

/*****************************   Functions   *******************************/


int main(void)
/*****************************************************************************
*   Input    :
*   Output   :
*   Function : The super loop.
******************************************************************************/
{
  INT8U event;
  INT8U counter_value;

  disable_global_int();
Beispiel #10
0
/*
 * radar_update_map
 *
 * it updates the int_map and the ext_map if any bnodes are found.
 * Note that the rnodes in the map are held in a different way. First of all the qspn
 * is not applied to them (we already know how to reach them ;) and they have only
 * one rnode... ME. So me.cur_node->r_node[x].r_node->r_node[0] == me.cur_node.
 * Gotcha?
 */
void
radar_update_map(void)
{
    struct qspn_buffer *qb;
    struct radar_queue *rq;
    ext_rnode_cache *erc;
    map_gnode *gnode = 0;
    map_node *node, *root_node;
    map_rnode rnn, *new_root_rnode;
    ext_rnode *e_rnode;

    int i, diff, rnode_pos;
    u_char rnode_added[MAX_LEVELS / 8], rnode_deleted[MAX_LEVELS / 8];
    int level, external_node, total_levels, root_node_pos, node_update;
    void *void_map;
    const char *ntop;
    char updated_rnodes, routes_update, devs_update;

    updated_rnodes = routes_update = devs_update = 0;
    setzero(rnode_added, sizeof(rnode_added));
    setzero(rnode_deleted, sizeof(rnode_deleted));

    /**
     * Let's consider all our rnodes void, in this way we'll know what
     * rnodes will remain void after the update.
     */
    for (i = 0; i < me.cur_node->links; i++) {
        node = (map_node *) me.cur_node->r_node[i].r_node;
        node->flags |= MAP_VOID | MAP_UPDATE;
    }
    /**/ rq = radar_q;
    list_for(rq) {
        if (!rq->node)
            continue;
        if (!(me.cur_node->flags & MAP_HNODE) && (rq->flags & MAP_HNODE))
            continue;

        /*
         * We need to know if it is a node which is not in the gnode
         * where we are (external_rnode).
         */
        if ((int) rq->node == RADQ_EXT_RNODE) {
            external_node = 1;
            total_levels = rq->quadg.levels;
        } else {
            external_node = 0;
            total_levels = 1;
        }

        for (level = total_levels - 1; level >= 0; level--) {
            qspn_set_map_vars(level, 0, &root_node, &root_node_pos, 0);
            node_update = devs_update = 0;

            if (!level) {
                void_map = me.int_map;
                node = rq->node;
            } else {
                /* Skip the levels where the ext_rnode belongs
                 * to our same gids */
                if (!quadg_gids_cmp(rq->quadg, me.cur_quadg, level))
                    continue;

                /* Update only the gnodes which belongs to
                 * our same gid of the upper level, because
                 * we don't keep the internal info of the
                 * extern gnodes. */
                if ((level < rq->quadg.levels - 1) &&
                        quadg_gids_cmp(rq->quadg, me.cur_quadg, level + 1)) {
                    rq->quadg.gnode[_EL(level)] = 0;
                    continue;
                }

                /* Ehi, we are a bnode */
                root_node->flags |= MAP_BNODE;
                me.cur_node->flags |= MAP_BNODE;

                void_map = me.ext_map;
                gnode = rq->quadg.gnode[_EL(level)];
                node = &gnode->g;
            }

            if (external_node && !level && me.cur_erc_counter) {
                erc = e_rnode_find(me.cur_erc, &rq->quadg, 0);
                if (!erc)
                    rnode_pos = -1;
                else {
                    rnode_pos = erc->rnode_pos;
                    node = (map_node *) erc->e;
                }
            } else
                rnode_pos = rnode_find(root_node, node);

            if (rnode_pos == -1) {	/* W00t, we've found a new rnode! */
                node_update = 1;
                rnode_pos = root_node->links;

                ntop = inet_to_str(rq->quadg.ipstart[level]);
                if (server_opt.dbg_lvl || !level)
                    loginfo
                    ("Radar: New node found: %s, ext: %d, level: %d",
                     ntop, external_node, level);

                if (external_node && !level) {
                    /*
                     * If this node we are processing is external, at level 0,
                     * in the root_node's rnodes we add a rnode which point
                     * to a ext_rnode struct.
                     */

                    setzero(&rnn, sizeof(map_rnode));
                    e_rnode = xzalloc(sizeof(ext_rnode));

                    memcpy(&e_rnode->quadg, &rq->quadg,
                           sizeof(quadro_group));
                    e_rnode->node.flags =
                        MAP_BNODE | MAP_GNODE | MAP_RNODE | MAP_ERNODE;
                    rnn.r_node = (int *) e_rnode;
                    node = rq->node = &e_rnode->node;
                    new_root_rnode = &rnn;

                    /* Update the external_rnode_cache list */
                    e_rnode_add(&me.cur_erc, e_rnode, rnode_pos,
                                &me.cur_erc_counter);
                } else {
                    /*We purge all the node's rnodes. */
                    rnode_destroy(node);

                    /*
                     * This node has only one rnode,
                     * and that is the root_node.
                     */
                    setzero(&rnn, sizeof(map_rnode));
                    rnn.r_node = (int *) root_node;
                    rnode_add(node, &rnn);

                    /* It is a border node */
                    if (level)
                        node->flags |= MAP_BNODE | MAP_GNODE;
                    node->flags |= MAP_RNODE;

                    /*
                     * Fill the rnode to be added in the
                     * root_node.
                     */
                    setzero(&rnn, sizeof(map_rnode));
                    rnn.r_node = (int *) node;
                    new_root_rnode = &rnn;
                }

                /*
                 * The new node is added in the root_node's
                 * rnodes.
                 */
                rnode_add(root_node, new_root_rnode);


                /* Update the qspn_buffer */
                if (!external_node || level) {
                    qb = xzalloc(sizeof(struct qspn_buffer));
                    qb->rnode = node;
                    qspn_b[level] = list_add(qspn_b[level], qb);

                    send_qspn_now[level] = 1;
                }

                /* If the new rnode wasn't present in the map,
                 * then it is also a new node in the map, so
                 * update the seeds counter too */
                if (!level && !external_node && (node->flags & MAP_VOID)) {
                    gnode_inc_seeds(&me.cur_quadg, level);
                    qspn_inc_gcount(qspn_gnode_count, level + 1, 1);
                }

                SET_BIT(rnode_added, level);
            } else {
                /*
                 * Nah, We have the node in the map. Let's see if
                 * its rtt is changed
                 */

                if (!send_qspn_now[level] && node->links) {
                    diff = abs(root_node->r_node[rnode_pos].trtt -
                               MILLISEC(rq->final_rtt));
                    if (diff >= RTT_DELTA) {
                        node_update = 1;
                        send_qspn_now[level] = 1;
                        debug(DBG_NOISE, "node %s rtt changed, diff: %d",
                              inet_to_str(rq->ip), diff);
                    }
                }
            }

            /* Restore the flags */
            if (level)
                gnode->flags &= ~GMAP_VOID;
            node->flags &= ~MAP_VOID & ~MAP_UPDATE & ~QSPN_OLD;


            /*
             * Update the devices list of the rnode
             */
            if (!level) {
                devs_update = rnl_update_devs(&rlist, &rlist_counter,
                                              node, rq->dev, rq->dev_n);
                if (devs_update)
                    routes_update++;
            }


            /* Nothing is really changed */
            if (!node_update)
                continue;

            /* Update the rtt */
            root_node->r_node[rnode_pos].trtt = MILLISEC(rq->final_rtt);

            /* Bnode map stuff */
            if (external_node && level) {
                /*
                 * All the root_node bnodes which are in the
                 * bmaps of level smaller than `level' points to
                 * the same gnode which is rq->quadg.gnode[_EL(level-1+1)].
                 * This is because the inferior levels cannot
                 * have knowledge about the bordering gnode
                 * which is in an upper level, but it's necessary that
                 * they know which who the root_node borders on,
                 * so the get_route algorithm can descend to
                 * the inferior levels and it will still know
                 * what is the border node which is linked
                 * to the target gnode.
                 */
                for (i = 0; i < level; i++)
                    radar_update_bmap(rq, i, level - 1);
                send_qspn_now[level - 1] = 1;
            }

            if (node_update || devs_update)
                node->flags |= MAP_UPDATE;

        }						/*for(level=0, ...) */

        updated_rnodes++;
    }							/*list_for(rq) */

    /* Burn the deads */
    if (updated_rnodes < me.cur_node->links)
        radar_remove_old_rnodes((char *) rnode_deleted);

    /* <<keep your room tidy... order, ORDER>> */
    if (!is_bufzero(rnode_added, sizeof(rnode_added)) ||
            !is_bufzero(rnode_deleted, sizeof(rnode_deleted))) {

        /***
         * qsort the rnodes of me.cur_node and me.cur_quadg comparing
         * their trtt */
        rnode_trtt_order(me.cur_node);

        for (i = 1; i < me.cur_quadg.levels; i++)
            if (TEST_BIT(rnode_added, i) || TEST_BIT(rnode_deleted, i))
                rnode_trtt_order(&me.cur_quadg.gnode[_EL(i)]->g);
        /**/
        /* adjust the rnode_pos variables in the ext_rnode_cache list */
        erc_reorder_rnodepos(&me.cur_erc, &me.cur_erc_counter,
                             me.cur_node);
    }

    /* Give a refresh to the kernel */
    if ((!is_bufzero(rnode_added, sizeof(rnode_added)) ||
            routes_update) && !(me.cur_node->flags & MAP_HNODE))
        rt_rnodes_update(1);
}