Exemplo n.º 1
0
Arquivo: main.c Projeto: vishnudh/RTOS
void Task1()
{
        uint16_t i,j;
	uint32_t it;
	nrk_time_t time, time2, time3;
	while(1) {
        nrk_led_set(RED_LED);
	nrk_gpio_toggle(NRK_DEBUG_0);
	nrk_kprintf("Task 1\r\n");

//for (i = 0; i < 10; i++) {
//        nrk_time_get(&time);
//        nrk_time_get(&time2);
//        nrk_time_sub(&time3, time2, time);
//	printf("%lu.%09lu\r\n", time3.secs, time3.nano_secs);
	nrk_time_get(&time);
	printf("%lu.%09lu\r\n", time.secs, time.nano_secs);
	for(it=0;it<115200;it++);
	nrk_time_get(&time);
	printf("%lu.%09lu\r\n", time.secs, time.nano_secs);
//        nrk_time_get(&time2);
//        nrk_time_sub(&time3, time2, time);
//	printf("%lu.%09lu\r\n", time3.secs, time3.nano_secs);
//}

//	nrk_time_get(&time);
//	for(i=0;i<256;i++) for(j=0;j<65000;j++); // wait 1 second
//	nrk_time_get(&time2);
//	nrk_time_sub(&time3, time2, time);
//	printf("%lu.%lu\r\n", time3.secs, time3.nano_secs);
        nrk_kprintf("Task 1 done\r\n");
	nrk_wait_until_next_period();
	}
}
Exemplo n.º 2
0
int8_t nrk_wait_until (nrk_time_t t)
{
    nrk_time_t ct;
    int8_t v;
//    uint8_t c;

    //c = _nrk_os_timer_get ();
    //do{
    //}while(_nrk_os_timer_get()==c);

    //ttt=c+1;
    nrk_time_get (&ct);

    v = nrk_time_sub (&t, t, ct);
    //nrk_time_compact_nanos(&t);
    if (v == NRK_ERROR)
    {
        return NRK_ERROR;
    }
//if(t.secs<ct.secs) return 0;
//if(t.secs==ct.secs && t.nano_secs<ct.nano_secs) return 0;

//t.secs-=ct.secs;
//t.nano_secs-=ct.nano_secs;
//
    nrk_wait (t);

    return NRK_OK;
}
Exemplo n.º 3
0
void handle_discover_response(pkt_t *pkt)
{
    node_id_t origin = pkt->payload[PKT_RESPONSE_ORIGIN_OFFSET];
    uint8_t seq = pkt->payload[PKT_RESPONSE_SEQ_OFFSET];
    nrk_time_t delay;
    uint8_t attempt;

    if (!IS_VALID_NODE_ID(origin)) {
        LOG("WARN: invalid origin in response: ");
        LOGP("%d\r\n", origin);
        return;
    }

    LOG("response: orig "); LOGP("%u", origin);
    LOGA(" seq "); LOGP("%u", seq);
    LOGA(" src "); LOGP("%u", pkt->src);
    LOGA(": ");

    nrk_time_get(&last_activity);

    if (origin == this_node_id) {
        LOGA("reached origin\r\n");

        add_path_to_graph(pkt);
        print_graph(&network);
    } else { /* we're not the destination: forward to gateway */
        attempt = 0;
        do {
            forward_response(pkt, attempt);
            choose_delay(&delay, &discover_req_delay);
            nrk_wait(delay);
        } while (++attempt < discover_send_attempts);
    }
}
Exemplo n.º 4
0
int main ()
{
    nrk_setup_ports();
    nrk_setup_uart(UART_BAUDRATE_115K2);

    nrk_init();

    nrk_time_set(0,0);

    nrk_time_get(seed);
    srand(seed->nano_secs);

    //Initialize tasks 
    //Higher value higher priority`
    // INITIALIZE_TASK(1, BASIC_TASK);
    // INITIALIZE_TASK(2, CBS_TASK);
    // INITIALIZE_TASK(3, BASIC_TASK);

	INITIALIZE_TASK(1, CBS_TASK);
    	INITIALIZE_TASK(2, BASIC_TASK);
    	INITIALIZE_TASK(3, CBS_TASK);

    nrk_start();

    return 0;
}
Exemplo n.º 5
0
void tdma_stats_ts_packet(uint8_t * tx_buf)
{
    nrk_time_t old, cur, lat;
    nrk_time_get(&cur);
    nrk_time_compact_nanos(&cur);

    //memcpy(&lat, &tx_buf[TDMA_DATA_START+8],  sizeof(lat));
    memcpy(&lat, &tx_buf[TDMA_DATA_START+8],  sizeof(lat));

    //memcpy(&old, &tx_buf[TDMA_DATA_START+16],  sizeof(old));
    memcpy(&old, &tx_buf[TDMA_DATA_START+16],  sizeof(old));

    //printf("MTTS %lu %lu %lu %lu\r\n", lat.secs, lat.nano_secs, old.secs, old.nano_secs);
    
    // subtract current time from arrival time (old)
    if (nrk_time_sub(&cur, cur, old) == NRK_ERROR)
    {
        cur.secs = 0;
        cur.nano_secs = 0;
    }
    // add that difference to the total latency
    nrk_time_add(&lat, lat, cur);


    // finally, add the cumulative latency back in
    memcpy(&tx_buf[TDMA_DATA_START+8], &lat, sizeof(lat));
}
Exemplo n.º 6
0
// This is an interrupts routine that handles the button press.
// It has a 300ms debounce
void button_handler()
{
    int8_t v;

// Make sure button is depressed for at least 50 us
    nrk_spin_wait_us(50);
    v=nrk_gpio_get(NRK_PORTD_0);
    if(v!=0) return;
    nrk_time_get(&button_cur_press);
    nrk_time_sub(&button_tmp_press, button_cur_press, button_last_press );
    if(button_tmp_press.secs>=1 || button_tmp_press.nano_secs>=(300*NANOS_PER_MS))
    {

// Reboot the node...

        socket_0_disable();
        power_socket_disable(0);
        nrk_int_disable();
        while(1);

        if(socket_0_active==1)
        {
            plug_led_green_clr();
            power_socket_disable(0);
        }
        else
        {
            plug_led_green_set();
            power_socket_enable(0);
        }
        button_last_press.secs=button_cur_press.secs;
        button_last_press.nano_secs=button_cur_press.nano_secs;
    }

}
Exemplo n.º 7
0
void handle_discover_request(pkt_t *pkt)
{
    node_id_t origin;
    uint8_t seq, depth;
    nrk_time_t delay;
    uint8_t attempt;
    int8_t rc;

    origin = pkt->payload[PKT_REQUEST_ORIGIN_OFFSET];
    seq = pkt->payload[PKT_REQUEST_SEQ_OFFSET];
    depth = pkt->payload[PKT_REQUEST_DEPTH_OFFSET];

    if (!IS_VALID_NODE_ID(origin)) {
        LOG("WARN: invalid origin node id in response: ");
        LOGP("%d\r\n", origin);
        return;
    }

    LOG("request:");
    LOGA(" src "); LOGP("%u", pkt->src);
    LOGA(" orig "); LOGP("%u", origin);
    LOGA(" seq "); LOGP("%d (%d)", seq, discovered_seq);
    LOGA(" depth "); LOGP("%d\r\n", depth);

    nrk_time_get(&last_activity);

    choose_delay(&delay, &discover_req_delay);
    nrk_wait(delay);

    /* Discover this node: mark and broadcast to neighbors */
    if (discovered_seq != seq) {
        discovered_seq = seq;
        route_to_origin = pkt->src;

        LOG("discovered: orig "); LOGP("%d", origin);
        LOGA(" seq "); LOGP("%d", discovered_seq);
        LOGA(" hop "); LOGP("%d\r\n", route_to_origin);

        if (depth == 0 || pkt->hops < depth) {
            attempt = 0;
            do {
                rc = broadcast_request(origin, seq, depth, attempt);
                if (rc != NRK_OK)
                    LOG("WARN: failed to broadcast req\r\n");
                nrk_wait(delay);
            } while (++attempt < discover_send_attempts);
        } else {
            LOG("max depth reached: "); LOGP("%d\r\n", depth);
        }
    } else {
        LOG("already discovered: seq "); LOGP("%u\r\n", discovered_seq);
    }

    attempt = 0;
    do {
        send_response(origin, pkt->src, seq, attempt);
        nrk_wait(delay);
    } while (++attempt < discover_send_attempts);
}
Exemplo n.º 8
0
void tdma_stats_dump()
{

    nrk_time_t ct;
    nrk_time_get(&ct);
  // PRINTS OUT...
  //
  // My MAC address
  // time tdma task has spent awake (secs)
  // time tdma task has spent awake (nanosecs)
  // time tdma task used radio
  // number of slot steals
  // number of backoffs
  // number of rx syncs
  // number of sync slots

#ifdef NRK_STATS_TRACKER
  nrk_stats_get(tdma_pid, &tdma_stat_struct);

  tdma_cpu_time = _nrk_ticks_to_time(tdma_stat_struct.total_ticks);
    //printf("TCT %lu %lu %lu %lu\r\n", tdma_cpu_time.secs, tdma_cpu_time.nano_secs,
    //                tree_creation_time.secs, tree_creation_time.nano_secs);
  nrk_time_sub(&tdma_cpu_time, tdma_cpu_time, tree_creation_time);
#endif


  printf("SD %d %lu %lu %lu %lu %lu %u %u\r\n",
    tdma_mac_get(),
    tdma_cpu_time.secs,
    tdma_cpu_time.nano_secs,
    ticks_rdo,
    steal_cnt,
    backoff_cnt,
    sync_rx_cnt,
    sync_slot_cnt);

 printf("OSA %lu %lu %lu %lu\r\n",
        osa_time.secs, osa_time.nano_secs,
        ct.secs, ct.nano_secs);


#ifdef SYNC_HIST
  printf("SH %d %d %d %d %d %d %d %d %d %d %d\r\n",
    tdma_mac_get(),
    sync_hist[0],
    sync_hist[1],
    sync_hist[2],
    sync_hist[3],
    sync_hist[4],
    sync_hist[5],
    sync_hist[6],
    sync_hist[7],
    sync_hist[8],
    sync_hist[9]);
    
#endif
}
Exemplo n.º 9
0
Arquivo: main.c Projeto: vishnudh/RTOS
void Task3()
{
        uint16_t i,j;
	uint32_t it;
	nrk_time_t time;
  while(1) {
	nrk_led_set(BLUE_LED);
	nrk_gpio_toggle(NRK_DEBUG_2);
	nrk_kprintf("Task 3\r\n");

	nrk_time_get(&time);
	printf("%lu.%09lu\r\n", time.secs, time.nano_secs);
	for(it=0;it<345600;it++);//345600
	nrk_time_get(&time);
	printf("%lu.%09lu\r\n", time.secs, time.nano_secs);
	nrk_kprintf("Task 3 done\r\n");
	nrk_wait_until_next_period();
	}
}
Exemplo n.º 10
0
void Task1()
{
    nrk_kprintf( PSTR("Nano-RK Version ") );
    printf( "%d\r\n",NRK_VERSION );


    start_time.secs=0;
    start_time.nano_secs=0;
    end_time.secs=0;
    end_time.nano_secs=0;
    start_time_1.secs=0;
    start_time_1.nano_secs=0;
    end_time_1.secs=0;
    end_time_1.nano_secs=0;

    while (1) {

        // Measure time with code inbetween
        nrk_time_get(&start_time);
        nrk_time_get(&end_time);

        printf("####### NO WAIT BETWEEN READINGS #########\r\n");
        printf("start: %lu %lu\r\n",start_time.secs,start_time.nano_secs);
        printf("  end: %lu %lu\r\n",end_time.secs,end_time.nano_secs);
        printf("end.nano - start.nano: %lu\r\n",end_time.nano_secs-start_time.nano_secs);
        //printf("start.nano - end.nano: %lu\r\n",start_time.nano_secs-end_time.nano_secs);

        // Measure time with code inbetween
        nrk_time_get(&start_time_1);
        nrk_spin_wait_us(200);
        nrk_time_get(&end_time_1);


        printf("####### 200us BETWEEN READINGS #########\r\n");
        printf("start: %lu %lu\r\n",start_time_1.secs,start_time_1.nano_secs);
        printf("  end: %lu %lu\r\n",end_time_1.secs,end_time_1.nano_secs);
        printf("end.nano - start.nano: %lu\r\n",end_time_1.nano_secs-start_time_1.nano_secs);

        nrk_wait_until_next_period();
    }

}
Exemplo n.º 11
0
Arquivo: main.c Projeto: vishnudh/RTOS
void Task2()
{
        uint16_t i,j;
	uint32_t it;
	nrk_time_t time, time2, time3;
  while(1) {
    	nrk_led_set(GREEN_LED);
	nrk_gpio_toggle(NRK_DEBUG_1);
	nrk_kprintf("Task 2\r\n");
	nrk_time_get(&time);
	printf("%lu.%09lu\r\n", time.secs, time.nano_secs);

	for(it=0;it<400800;it++);//for(it=0;it<460800;it++);//460800
	nrk_time_get(&time);
	printf("%lu.%09lu\r\n", time.secs, time.nano_secs);
	nrk_kprintf("Task 2 done\r\n");

	nrk_wait_until_next_period();
	}
}
Exemplo n.º 12
0
int8_t probe(uint8_t depth)
{
    outstanding_seq++; 
    nrk_time_get(&last_activity);

    LOG("starting: orig "); LOGP("%d", this_node_id);
    LOGA(" seq "); LOGP("%d", outstanding_seq);
    LOGA(" depth "); LOGP("%d\r\n", depth);

    init_graph(&network);
    print_graph(&network);
    discovered_seq = outstanding_seq; // origin starts discovered
    return broadcast_request(this_node_id, outstanding_seq, depth, 0 /* attempt */);
}
Exemplo n.º 13
0
void sync_miss_log()
{
    if (sync_consec_miss < 10)
    {
        sync_consec_miss++;
        if (sync_consec_miss > 5)
        {
            nrk_time_t cur_time;
            nrk_time_get(&cur_time);
            nrk_time_compact_nanos(&cur_time);
            printf("SM %d %d %lu %lu\r\n", tdma_mac_get(), sync_consec_miss, cur_time.secs, cur_time.nano_secs);
        }
    }
}
Exemplo n.º 14
0
void debug_update()
{

nrk_time_get(&t);
debug_stats.uptime.secs=t.secs;
debug_stats.uptime.nano_secs=t.nano_secs;

nrk_stats_get_deep_sleep(&t);
debug_stats.deep_sleep.secs=t.secs;
debug_stats.deep_sleep.nano_secs=t.nano_secs;

nrk_stats_get(0, &t_stat);
t=_nrk_ticks_to_time(t_stat.total_ticks);
debug_stats.idle_time.secs=t.secs;
debug_stats.idle_time.nano_secs=t.nano_secs;
}
Exemplo n.º 15
0
static void periodic_heading_process(bool enabled,
    nrk_time_t *next_event, nrk_sig_mask_t *wait_mask)
{
    int16_t heading;
    int8_t rc;
    nrk_time_t now;

    if (!enabled)
        return;

    rc = get_heading(&heading);
    OUT("heading: ");
    show_heading(rc == NRK_OK ? &heading : NULL);

    nrk_time_get(&now);
    nrk_time_add(next_event, now, heading_period);
}
Exemplo n.º 16
0
int8_t nrk_wait_until(nrk_time_t t) {
	nrk_time_t ct;
	uint8_t v;

	nrk_time_get(&ct);

	v = nrk_time_sub(&t, t, ct);
	if (v == 0)
		return NRK_ERROR;
	//if(t.secs<ct.secs) return 0;
	//if(t.secs==ct.secs && t.nano_secs<ct.nano_secs) return 0;

	//t.secs-=ct.secs;
	//t.nano_secs-=ct.nano_secs;
	nrk_wait(t);

	return NRK_OK;
}
Exemplo n.º 17
0
void Task4()
{
uint16_t cnt;
nrk_time_t my_time;

  printf( "Task4 PID=%d\r\n",nrk_get_pid());
  cnt=0;
  while(1) {
	
	nrk_led_set(RED_LED);
	nrk_time_get(&my_time);
	printf( "Task4 cnt=%d\r\n",cnt );
	nrk_wait_until_next_period();
	nrk_led_clr(RED_LED);
	cnt++;
	nrk_wait_until_next_period();
	}
}
Exemplo n.º 18
0
void _nrk_reserve_update (uint8_t reserve_id)
{
  nrk_time_t t;

  nrk_int_disable ();
  nrk_time_get (&t);

  _nrk_reserve[reserve_id].cur_time = (int32_t) _nrk_time_to_ticks_long (t);
  if (_nrk_reserve[reserve_id].cur_time >= _nrk_reserve[reserve_id].set_time) {
    // If the reserve is passed its period then replenish it
    _nrk_reserve[reserve_id].set_time =
      _nrk_reserve[reserve_id].cur_time +
      _nrk_reserve[reserve_id].period_ticks;
    _nrk_reserve[reserve_id].cur_access = 0;
  }
  nrk_int_enable ();

}
Exemplo n.º 19
0
void heart_rate_int()
{
uint8_t bpm;
  nrk_led_set(BLUE_LED);
  nrk_time_get(&c);
  nrk_time_sub(&t,c,l);
  bpm=(uint16_t)60000 / (uint16_t)(t.nano_secs/1000000);
if(bpm>20 && bpm<220 )
  {
    bpm_list[bpm_index]=bpm;
    bpm_index++;
    if(bpm_index==BPM_LIST_SIZE)bpm_index=0;
  }

  l.secs=c.secs;
  l.nano_secs=c.nano_secs;
  nrk_led_clr(BLUE_LED);
}
Exemplo n.º 20
0
uint8_t hrm_get_value()
{
uint16_t acc;
uint8_t i,j,tmp;

  nrk_time_get(&c);
  nrk_time_sub(&t,c,l);

  if(t.secs>5) {
	for(i=0; i<BPM_LIST_SIZE; i++ ) bpm_list[i]=0;
	return 0;
	}

for(i=0; i<BPM_LIST_SIZE; i++ ) 
	{
	bpm_sort[i]=bpm_list[i];
	if(bpm_list[i]==0) return 0;
	}

for(i=0; i<BPM_LIST_SIZE; i++ )
  {
	for(j=0; j<BPM_LIST_SIZE-1; j++ )
		{
		if(bpm_sort[j]>bpm_sort[j+1] )
			{
			tmp=bpm_sort[j];
			bpm_sort[j]=bpm_sort[j+1];
			bpm_sort[j+1]=tmp;
			}
		}
  }
/*
for(i=0; i<BPM_LIST_SIZE; i++ ) 
	{
	if(bpm_index==i) printf( ">" );
	printf( "%u %d %d\r\n",i,bpm_sort[i],bpm_list[i]);
	}
*/
acc=0;
for(i=(BPM_LIST_SIZE/2)-2; i<(BPM_LIST_SIZE/2)+2; i++ )
   acc+=bpm_sort[BPM_LIST_SIZE/2];
//return bpm_sort[BPM_LIST_SIZE/2];
return (acc/4);
}
Exemplo n.º 21
0
int8_t nrk_reserve_set (uint8_t id, nrk_time_t * period, int16_t access_count,
                        void *errhandler)
{
  nrk_time_t tmp_time;

  if (id >= NRK_MAX_RESERVES)
    return NRK_ERROR;
  if (_nrk_reserve[id].active == -1)
    return NRK_ERROR;

  tmp_time.secs = period->secs;
  tmp_time.nano_secs = period->nano_secs;
  _nrk_reserve[id].period_ticks = _nrk_time_to_ticks_long (tmp_time);
  _nrk_reserve[id].set_access = access_count;
  _nrk_reserve[id].cur_access = 0;

  nrk_time_get (&tmp_time);
  _nrk_reserve[id].cur_time = (uint32_t) _nrk_time_to_ticks_long (tmp_time);
  _nrk_reserve[id].set_time =
    _nrk_reserve[id].cur_time + _nrk_reserve[id].period_ticks;
  _nrk_reserve[id].error = (void *) errhandler;

  return NRK_OK;
}
Exemplo n.º 22
0
void nl_rx_task()
{
	uint8_t len; 				   // to hold the size of the received packet, always = sizeof(NW_Packet) 
	int8_t rssi;  			   	// to hold rssi of received packet
	uint8_t *local_rx_buf;	   // pointer to receive buffer of link layer
	int8_t val;						// status variable to hold the return type of function calls
	int8_t flag;
	
	nrk_time_t start, end, elapsed;		// needed by nl_rx_task()
										// to decide when to send own NGB_LIST
	if(DEBUG_NL >= 1)
	{
		nrk_kprintf(PSTR("NL_RX_TASK PID = "));
		printf("%d\r\n",nrk_get_pid());
	}
	
	// initialise the timer
	nrk_time_get(&start);
	end.secs = start.secs;
	end.nano_secs = start.nano_secs;

	// initialise the link layer	
	val = bmac_init(25);
	if(val == NRK_ERROR)
	{
		nrk_int_disable();
		nrk_led_set(RED_LED);
		while(1)
			nrk_kprintf(PSTR("NL: Error returned by bmac_init()\r\n"));
	}	
		
	// give the link layer a rx buffer 	
	val = bmac_rx_pkt_set_buffer(rx_buf, RF_BUFFER_SIZE);
	if(val == NRK_ERROR)
	{
		nrk_int_disable();
		nrk_led_set(RED_LED);
		while(1)
			nrk_kprintf(PSTR("NL: Error returned by bmac_rx_pkt_set_buffer()\r\n"));
	}
		
	// start processing forever 
	while(1)
	{
		// decide whether it is time to send your own Ngb_List message
		if(CONNECTED_TO_GATEWAY == TRUE)
		{
			nrk_time_get(&end);
			val = nrk_time_sub(&elapsed, end, start);
			nrk_time_compact_nanos(&elapsed);
			if(elapsed.secs >= NGB_LIST_PERIOD)
			{
				ntg_pkt.type = SERIAL_NGB_LIST;
				ntg_pkt.length = SIZE_MSG_NGB_LIST;
				enter_cr(nl_sem, 34);
				pack_Msg_NgbList(ntg_pkt.data, &nl);
				leave_cr(nl_sem, 34);
				pack_NodeToGatewaySerial_Packet_header(to_gw_buf, &ntg_pkt);
				memcpy(to_gw_buf + SIZE_NODETOGATEWAYSERIAL_PACKET_HEADER, ntg_pkt.data, MAX_SERIAL_PAYLOAD);
				if(DEBUG_NL == 2)
				{
					nrk_kprintf(PSTR("Sending own NGB_LIST message to gateway\r\n"));
				}
				sendToSerial(to_gw_buf, SIZE_NODETOGATEWAYSERIAL_PACKET);
				
				// reset the timer
				start.secs = end.secs;
				start.nano_secs = end.nano_secs;
			} // end if
		} // end if
				
		if(DEBUG_NL >= 1)
		{
			nrk_kprintf(PSTR("Waiting for next pkt from link layer\r\n"));
		}
		
		flag = 0;
		// wait for the next packet 		
		while(bmac_rx_pkt_ready() == 0)
		{
			val = bmac_wait_until_rx_pkt();
			if(DEBUG_NL == 2)
			{
				nrk_kprintf(PSTR("NL: bmac_wait_until_rx_packet() returned "));
				printf("%d\n", val);
			}
		}
		
		// Get the packet 
	   	do
	   	{
	   		local_rx_buf = bmac_rx_pkt_get(&len,&rssi);
	   		if(local_rx_buf == NULL)
	   		{
	   			nrk_kprintf(PSTR("NL: NULL returned by bmac_rx_pkt_get()\r\n"));
	   		}
	   		
	   	} while(local_rx_buf == NULL);
	   	
	   	// sanity check for debugging 
	   	if(len != SIZE_NW_PACKET)	// this should not happen 
	   	{
	   		/* 
	   		nrk_int_disable();
	   		nrk_led_set(RED_LED);
	   		while(1)
	   		{
	   			nrk_kprintf(PSTR("NL: Wrong length of packet received: "));
	   			printf("%d\r\n", len);
	   		}
	   		*/
	   		if(DEBUG_NL >= 1)
	   		{
	   			nrk_kprintf(PSTR("NL: nl_rx_task(): Wrong length of packet received: "));
	   			printf("%d\r\n", len);
	   		}
	   		flag = 1;
	   	}
	   	
	   	nrk_led_set(GREEN_LED);
	   	
	   	if(DEBUG_NL == 2)// || flag == 1)
	   	{
				int8_t i; 
				nrk_kprintf(PSTR("NL: Contents of received packet are\r\n"));
				printf("[");
				for(i = 0; i < len; i++)
					printf("%d ", local_rx_buf[i]);
				printf("]\r\n");
		}  	
		if(flag == 1)
		{
			bmac_rx_pkt_release();	// drop the packet and go receive another
			nrk_led_clr(GREEN_LED);
			continue;
		}
			   	
			// unpack the packet header from the received buffer 
			unpack_NW_Packet_header(&pkt_rx, local_rx_buf);
			// copy the packet payload to the data field of the local packet
			memcpy(pkt_rx.data, local_rx_buf + SIZE_NW_PACKET_HEADER, MAX_NETWORK_PAYLOAD);
			// Release the RX buffer quickly so future packets can arrive
			bmac_rx_pkt_release();	
			
			// begin processing this packet
			if(pkt_type(&pkt_rx) == APPLICATION)	// its an application layer packet 
			{
				// case 1: Destination is NODE_ADDR or BCAST_ADDR
				if(pkt_rx.dest == NODE_ADDR || pkt_rx.dest == BCAST_ADDR)
					process_app_pkt(&pkt_rx, rssi);
					
				// case 2: I am enroute to the destination
				else if(pkt_rx.nextHop == NODE_ADDR)
					 {
					 	if(pkt_rx.src == NODE_ADDR)		// routing table corrupted
						{
							nrk_int_disable();
							nrk_led_set(RED_LED);
							while(1)
							{
								nrk_kprintf(PSTR("Routing table corrupted at "));
								printf("%d\r\n", NODE_ADDR);
							} // end while 
						} // end if 
						else
							route_packet(&pkt_rx);
					 } // end if 		
					 // case 3: Routing tables still not made
					 else if(pkt_rx.nextHop == BCAST_ADDR)	
					 			route_packet(&pkt_rx);
					 	  else
					 	  	;		 // drop all other packets								
			} // end if(type == APPLICATION)
			else 
			{
				if(pkt_type(&pkt_rx) == NW_CONTROL)	// its a network control packet 
				{
				  	// case 1: Destination is NODE_ADDR or BCAST_ADDR
				  	if(pkt_rx.dest == NODE_ADDR || pkt_rx.dest == BCAST_ADDR)
				  		process_nw_ctrl_pkt(&pkt_rx, rssi);
				  	
				  	// case 2: I am enroute to a destination
				  	else if(pkt_rx.nextHop == NODE_ADDR)
				  		 {
				  		 	if(pkt_rx.src == NODE_ADDR)		// routing table corrupted
				  		 	{
				  		 		nrk_int_disable();
								nrk_led_set(RED_LED);
								while(1)
								{
									nrk_kprintf(PSTR("Routing table corrupted at "));
									printf("%d\r\n", NODE_ADDR);
								} // end while 
							} // end if
							else
				  		 		route_packet(&pkt_rx);
				  		 } // end if
				  		// case 3: Routing tables still not made 
				  		 else if(pkt_rx.nextHop == BCAST_ADDR)
				  		 		route_packet(&pkt_rx);
				  		 	  else
				  		 		;	// drop all other packets
				  } // end if(type == NW_CONTROL)
				  else	// unknown packet type 
				  {
				  		nrk_kprintf(PSTR("NL: Unknown pkt type received = "));
				  		printf("%d\r\n", pkt_type(&pkt_rx));
				  }
			}
				
			nrk_led_clr(GREEN_LED);			
	 } // end while(1)
	
	return;
}	// end nl_rx_task
Exemplo n.º 23
0
void inline _nrk_scheduler()
{
    int8_t task_ID;
    uint16_t next_wake;
    //uint16_t start_time_stamp;
    /* _nrk_precision_os_timer_reset(); */
    /* nrk_int_disable(); */   // this should be removed...  Not needed

#ifndef NRK_NO_BOUNDED_CONTEXT_SWAP
    _nrk_high_speed_timer_reset();
    start_time_stamp=_nrk_high_speed_timer_get();
#endif
    _nrk_set_next_wakeup(MAX_SCHED_WAKEUP_TIME);
    // Set to huge number which will later get set to min

    next_wake=60000;
    // Safety zone starts here....


#ifdef NRK_WATCHDOG
    nrk_watchdog_reset();
#endif

#ifdef NRK_SW_WDT
    _nrk_sw_wdt_check();
#endif



#ifdef NRK_KERNEL_TEST
    //nrk_kprintf( PSTR("*"));
    //Check if OS tick was delayed...
    // if(_nrk_cpu_state!=CPU_SLEEP && _nrk_os_timer_get()!=0) {
    //		nrk_kprintf( PSTR("X" ));
    //printf( "%u ",_nrk_os_timer_get());
    //	}
    //printf( "%u\r\n",_nrk_prev_timer_val);
    if((_nrk_cpu_state!=CPU_ACTIVE) && (_nrk_os_timer_get()>nrk_max_sleep_wakeup_time))
        nrk_max_sleep_wakeup_time=_nrk_os_timer_get();
#endif
    //while(_nrk_time_trigger>0)
    //{
    nrk_system_time.nano_secs+=((uint32_t)_nrk_prev_timer_val*NANOS_PER_TICK);
    nrk_system_time.nano_secs-=(nrk_system_time.nano_secs%(uint32_t)NANOS_PER_TICK);

#ifdef NRK_STATS_TRACKER
    if(nrk_cur_task_TCB->task_ID==NRK_IDLE_TASK_ID)
    {
        if(_nrk_cpu_state==CPU_SLEEP) _nrk_stats_sleep(_nrk_prev_timer_val);
        _nrk_stats_task_preempted(nrk_cur_task_TCB->task_ID, _nrk_prev_timer_val);
        // Add 0 time since the preempted call before set the correct value
        _nrk_stats_task_suspend(nrk_cur_task_TCB->task_ID, 0);
    }
    else
    {
        if(nrk_cur_task_TCB->suspend_flag==1)
            _nrk_stats_task_suspend(nrk_cur_task_TCB->task_ID, _nrk_prev_timer_val);
        else
            _nrk_stats_task_preempted(nrk_cur_task_TCB->task_ID, _nrk_prev_timer_val);
    }
#endif

    while(nrk_system_time.nano_secs>=NANOS_PER_SEC)
    {
        nrk_system_time.nano_secs-=NANOS_PER_SEC;
        nrk_system_time.secs++;
        nrk_system_time.nano_secs-=(nrk_system_time.nano_secs%(uint32_t)NANOS_PER_TICK);
    }
    //  _nrk_time_trigger--;
    //}
    if(nrk_cur_task_TCB->suspend_flag==1 && nrk_cur_task_TCB->task_state!=FINISHED)
    {
        //	nrk_cur_task_TCB->task_state = EVENT_SUSPENDED;

        if(nrk_cur_task_TCB->event_suspend==RSRC_EVENT_SUSPENDED)
            nrk_cur_task_TCB->task_state = EVENT_SUSPENDED;
        else if( nrk_cur_task_TCB->event_suspend>0 && nrk_cur_task_TCB->nw_flag==0)
            nrk_cur_task_TCB->task_state = EVENT_SUSPENDED;
        else if( nrk_cur_task_TCB->event_suspend>0 && nrk_cur_task_TCB->nw_flag==1)
            nrk_cur_task_TCB->task_state = SUSPENDED;
        else
        {

	  nrk_cur_task_TCB->task_state = SUSPENDED;
            nrk_cur_task_TCB->event_suspend=0;
            nrk_cur_task_TCB->nw_flag=0;
        }
        nrk_rem_from_readyQ(nrk_cur_task_TCB->task_ID);
    }
    // nrk_print_readyQ();

    // Update cpu used value for ended task
    // If the task has used its reserve, suspend task
    // Don't disable IdleTask which is 0
    // Don't decrease cpu_remaining if reserve is 0 and hence disabled
    if(nrk_cur_task_TCB->cpu_reserve!=0 && nrk_cur_task_TCB->task_ID!=NRK_IDLE_TASK_ID)
    {
        // Update CASH and cpu_remaining
        // First use up any available CASH budget
        uint8_t ticksToAccountFor = _nrk_prev_timer_val;
        nrk_budget_t *budgetFromCASH = nrk_peek_budget();

        while (ticksToAccountFor > 0 && budgetFromCASH) {
            // We've found some cash budget
            uint8_t availableCASH = budgetFromCASH->amount_left;


            nrk_time_t system_time;
            nrk_time_get(&system_time);

            // We need to look at the deadline for the cash budget
            // If it has passed, we can only use the portion that came before the deadline
            if (nrk_time_compare(&system_time, &budgetFromCASH->expire_time) == 1) {
                nrk_time_t difference;
                nrk_time_sub(&difference, system_time, budgetFromCASH->expire_time);
                uint8_t differenceInTicks = _nrk_time_to_ticks(&difference);

                // Check if it expired before we got a chance to use it
                if (differenceInTicks > ticksToAccountFor) {
                    availableCASH = 0;
                } else {
                    uint8_t usableBudget = ticksToAccountFor - _nrk_time_to_ticks(&difference);
                    // Take the minimum of available vs usable
                    availableCASH = usableBudget < availableCASH ? usableBudget : availableCASH;
                }

                // pop it off the queue. Expired now.
                nrk_get_budget();
            }

            if (availableCASH > ticksToAccountFor) {
                budgetFromCASH->amount_left -= ticksToAccountFor;
                ticksToAccountFor = 0;
            } else {
                ticksToAccountFor -= availableCASH;
                // Pop the now empty cash budget off the queue
                nrk_get_budget();
            }
            budgetFromCASH = budgetFromCASH->Next;
        }

        // If we still have ticks to account for, take them off cpu_remaining
        if (ticksToAccountFor > 0) {
            nrk_cur_task_TCB->cpu_remaining -= ticksToAccountFor;
        }

        // For finished tasks that still have cpu remaining, give it to the CASH queue
        if (nrk_cur_task_TCB->task_state==FINISHED && nrk_cur_task_TCB->cpu_remaining > 0) {
            // Add to CASH queue
            nrk_add_nrk_budget(nrk_cur_task_TCB->absolute_deadline, nrk_cur_task_TCB->cpu_remaining);

        } else if (nrk_cur_task_TCB->cpu_remaining ==0 ) {
            // Support for Constant Bandwith Servers
            if(nrk_cur_task_TCB->task_type == CBS_TASK)
            {
                // Recharge budget
                nrk_cur_task_TCB->cpu_remaining = nrk_cur_task_TCB->cpu_reserve;

                // Increase the absolute deadline

                nrk_time_t increase = _nrk_ticks_to_time(nrk_cur_task_TCB->period);
                nrk_time_add(&nrk_cur_task_TCB->absolute_deadline, nrk_cur_task_TCB->absolute_deadline, increase);

                // Remove/re-add from ready queue to re-sort based on new absolute deadline
                nrk_rem_from_readyQ(nrk_cur_task_TCB->task_ID);
                nrk_add_to_readyQ(nrk_cur_task_TCB->task_ID);
            }
            else
            {
#ifdef NRK_STATS_TRACKER
                _nrk_stats_add_violation(nrk_cur_task_TCB->task_ID);
#endif
                nrk_kernel_error_add(NRK_RESERVE_VIOLATED,nrk_cur_task_TCB->task_ID);
                nrk_cur_task_TCB->task_state = SUSPENDED;
                nrk_rem_from_readyQ(nrk_cur_task_TCB->task_ID);
            }
        }
    }

    // Check I/O nrk_queues to add tasks with remaining cpu back...

    // Add eligable tasks back to the ready Queue
    // At the same time find the next earliest wakeup
    for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++)
    {
        if(nrk_task_TCB[task_ID].task_ID==-1) continue;
        nrk_task_TCB[task_ID].suspend_flag=0;
        if( nrk_task_TCB[task_ID].task_ID!=NRK_IDLE_TASK_ID && nrk_task_TCB[task_ID].task_state!=FINISHED )
        {
            if(  nrk_task_TCB[task_ID].next_wakeup >= _nrk_prev_timer_val )
                nrk_task_TCB[task_ID].next_wakeup-=_nrk_prev_timer_val;
            else
            {
                nrk_task_TCB[task_ID].next_wakeup=0;
            }
            // Do next period book keeping.
            // next_period needs to be set such that the period is kept consistent even if other
            // wait until functions are called.
            if( nrk_task_TCB[task_ID].next_period >= _nrk_prev_timer_val )
                nrk_task_TCB[task_ID].next_period-=_nrk_prev_timer_val;
            else
            {
                if(nrk_task_TCB[task_ID].period>_nrk_prev_timer_val)
                    nrk_task_TCB[task_ID].next_period= nrk_task_TCB[task_ID].period-_nrk_prev_timer_val;
                else
                    nrk_task_TCB[task_ID].next_period= _nrk_prev_timer_val % nrk_task_TCB[task_ID].period;
            }
            if(nrk_task_TCB[task_ID].next_period==0) nrk_task_TCB[task_ID].next_period=nrk_task_TCB[task_ID].period;

        }


        // Look for Next Task that Might Wakeup to interrupt current task
        if (nrk_task_TCB[task_ID].task_state == SUSPENDED )
        {


            // printf( "Task: %d nw: %d\n",task_ID,nrk_task_TCB[task_ID].next_wakeup);
            // If a task needs to become READY, make it ready
            if (nrk_task_TCB[task_ID].next_wakeup == 0)
            {
                // printf( "Adding back %d\n",task_ID );
                if(nrk_task_TCB[task_ID].event_suspend>0 && nrk_task_TCB[task_ID].nw_flag==1) nrk_task_TCB[task_ID].active_signal_mask=SIG(nrk_wakeup_signal);
                //if(nrk_task_TCB[task_ID].event_suspend==0) nrk_task_TCB[task_ID].active_signal_mask=0;
                nrk_task_TCB[task_ID].event_suspend=0;
                nrk_task_TCB[task_ID].nw_flag=0;
                nrk_task_TCB[task_ID].suspend_flag=0;
                if(nrk_task_TCB[task_ID].num_periods==1)
                {
                    nrk_task_TCB[task_ID].cpu_remaining = nrk_task_TCB[task_ID].cpu_reserve;
                    nrk_task_TCB[task_ID].task_state  = READY;
                    nrk_task_TCB[task_ID].next_wakeup = nrk_task_TCB[task_ID].next_period;
                    // If there is no period set, don't wakeup periodically
                    if(nrk_task_TCB[task_ID].period==0) nrk_task_TCB[task_ID].next_wakeup = MAX_SCHED_WAKEUP_TIME;
                    nrk_add_to_readyQ(task_ID);
                }
                else
                {
                    nrk_task_TCB[task_ID].cpu_remaining = nrk_task_TCB[task_ID].cpu_reserve;
                    //nrk_task_TCB[task_ID].next_wakeup = nrk_task_TCB[task_ID].next_period;
                    //nrk_task_TCB[task_ID].num_periods--;
                    nrk_task_TCB[task_ID].next_wakeup = (nrk_task_TCB[task_ID].period*(nrk_task_TCB[task_ID].num_periods-1));
                    nrk_task_TCB[task_ID].next_period = (nrk_task_TCB[task_ID].period*(nrk_task_TCB[task_ID].num_periods-1));
                    if(nrk_task_TCB[task_ID].period==0) nrk_task_TCB[task_ID].next_wakeup = MAX_SCHED_WAKEUP_TIME;
                    nrk_task_TCB[task_ID].num_periods=1;
                    //			printf( "np = %d\r\n",nrk_task_TCB[task_ID].next_wakeup);
                    //			nrk_task_TCB[task_ID].num_periods=1;
                }
            }

            if(nrk_task_TCB[task_ID].next_wakeup!=0 &&
                    nrk_task_TCB[task_ID].next_wakeup<next_wake )
            {
                // Find closest next_wake task
                next_wake=nrk_task_TCB[task_ID].next_wakeup;
            }

        }
    }


#ifdef NRK_STATS_TRACKER
    _nrk_stats_task_start(nrk_cur_task_TCB->task_ID);
#endif
    task_ID = nrk_get_high_ready_task_ID();
    nrk_high_ready_prio = nrk_task_TCB[task_ID].task_prio;
    nrk_high_ready_TCB = &nrk_task_TCB[task_ID];

    // next_wake should hold next time when a suspended task might get run
    // task_ID holds the highest priority READY task ID
    // So nrk_task_TCB[task_ID].cpu_remaining holds the READY task's end time

    // Now we pick the next wakeup (either the end of the current task, or the possible resume
    // of a suspended task)
    if(task_ID!=NRK_IDLE_TASK_ID)
    {
        // You are a non-Idle Task
        if(nrk_task_TCB[task_ID].cpu_reserve!=0 && nrk_task_TCB[task_ID].cpu_remaining<MAX_SCHED_WAKEUP_TIME)
        {
            if(next_wake>nrk_task_TCB[task_ID].cpu_remaining)
                next_wake=nrk_task_TCB[task_ID].cpu_remaining;
        }
        else
        {
            if(next_wake>MAX_SCHED_WAKEUP_TIME)  next_wake=MAX_SCHED_WAKEUP_TIME;
        }
    }
    else
    {
        // This is the idle task
        // Make sure you wake up from the idle task a little earlier
        // if you would go into deep sleep...
        // After waking from deep sleep, the next context swap must be at least
        // NRK_SLEEP_WAKEUP_TIME-1 away to make sure the CPU wakes up in time.
#ifndef NRK_NO_POWER_DOWN
        if(next_wake>NRK_SLEEP_WAKEUP_TIME)
        {
            if(next_wake-NRK_SLEEP_WAKEUP_TIME<MAX_SCHED_WAKEUP_TIME)
            {
                if(next_wake-NRK_SLEEP_WAKEUP_TIME<NRK_SLEEP_WAKEUP_TIME)
                {
                    next_wake=NRK_SLEEP_WAKEUP_TIME-1;
                }
                else
                {
                    next_wake=next_wake-NRK_SLEEP_WAKEUP_TIME;
                }
            }
            else if(next_wake>NRK_SLEEP_WAKEUP_TIME+MAX_SCHED_WAKEUP_TIME)
            {
                next_wake=MAX_SCHED_WAKEUP_TIME;
            }
            else
            {
                next_wake=MAX_SCHED_WAKEUP_TIME-NRK_SLEEP_WAKEUP_TIME;
            }
        }
#endif
    }

    /*
    // Some code to catch the case when the scheduler wakes up
    // from deep sleep and has to execute again before NRK_SLEEP_WAKEUP_TIME-1
    if(_nrk_cpu_state==2 && next_wake<NRK_SLEEP_WAKEUP_TIME-1)
    {
    nrk_int_disable();
    while(1)
    	{
    	nrk_spin_wait_us(60000);
    	nrk_led_toggle(RED_LED);
    	nrk_spin_wait_us(60000);
    	nrk_led_toggle(GREEN_LED);
    	printf( "crash: %d %d %d\r\n",task_ID,next_wake,_nrk_cpu_state);
    	}
    }*/


//  If we disable power down, we still need to wakeup before the overflow
#ifdef NRK_NO_POWER_DOWN
    if(next_wake>MAX_SCHED_WAKEUP_TIME)  next_wake=MAX_SCHED_WAKEUP_TIME;
#endif
    //printf( "nw = %d %d %d\r\n",task_ID,_nrk_cpu_state,next_wake);
    nrk_cur_task_prio = nrk_high_ready_prio;
    nrk_cur_task_TCB  = nrk_high_ready_TCB;

#ifdef NRK_KERNEL_TEST
    if(nrk_high_ready_TCB==NULL)
    {
        nrk_kprintf( PSTR( "KERNEL TEST: BAD TCB!\r\n" ));
    }
#endif
    //printf( "n %u %u %u %u\r\n",task_ID, _nrk_prev_timer_val, next_wake,_nrk_os_timer_get());

    _nrk_prev_timer_val=next_wake;


    if((_nrk_os_timer_get()+1)>=next_wake)  // just bigger then, or equal?
    {
        // FIXME: Terrible Terrible...
        // Need to find out why this is happening...
#ifdef NRK_KERNEL_TEST
        // Ignore if you are the idle task coming from deep sleep
        if(!(task_ID==NRK_IDLE_TASK_ID && _nrk_cpu_state==CPU_SLEEP))
            nrk_kernel_error_add(NRK_WAKEUP_MISSED,task_ID);
#endif
        // This is bad news, but keeps things running
        // +2 just in case we are on the edge of the last tick
        next_wake=_nrk_os_timer_get()+2;
        _nrk_prev_timer_val=next_wake;
    }

    if(task_ID!=NRK_IDLE_TASK_ID) _nrk_cpu_state=CPU_ACTIVE;

    _nrk_set_next_wakeup(next_wake);

#ifndef NRK_NO_BOUNDED_CONTEXT_SWAP
    // Bound Context Swap to 100us
    nrk_high_speed_timer_wait(start_time_stamp,CONTEXT_SWAP_TIME_BOUND);
#endif
    nrk_stack_pointer_restore();
    //nrk_int_enable();
    nrk_start_high_ready_task();

}
Exemplo n.º 24
0
void gateway_task ()
{
  uint8_t i, len;
  int8_t rssi, val;
  uint8_t *local_rx_tx_buf;
  uint16_t batt;
  nrk_time_t check_period, wait_time;
  uint16_t buf;
  int8_t fd;

  uint8_t j, cnt, level;
  nrk_sig_t tx_done_signal;
  nrk_sig_mask_t ret;
  nrk_time_t next_transmit_time;
  nrk_time_t current_time;
  nrk_time_t prev_time;
  char tmp[4];

  printf ("gateway_task PID=%d\r\n", nrk_get_pid ());

  next_transmit_time.secs 	= 0;
  next_transmit_time.nano_secs 	= 0;

  // init bmac on channel 25 
  bmac_init (26);

  // By default the RX check rate is 100ms
  // below shows how to change that
  check_period.secs=0;
  check_period.nano_secs=100*NANOS_PER_MS;
  val=bmac_set_rx_check_rate(check_period);

  // The default Clear Channel Assement RSSI threshold is -32
  // Setting this value higher means that you will only trigger
  // receive with a very strong signal.  Setting this lower means
  // bmac will try to receive fainter packets.  If the value is set
  // too high or too low performance will suffer greatly.
  // bmac_set_cca_thresh(-36); 
  
  if(val==NRK_ERROR) nrk_kprintf( PSTR("ERROR setting bmac rate\r\n" ));

  // This sets the next RX buffer.
  // This can be called at anytime before releaseing the packet
  // if you wish to do a zero-copy buffer switch
  bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE);
  
  // Get and register the tx_done_signal if you want to
  // do non-blocking transmits
  tx_done_signal = bmac_get_tx_done_signal ();
  nrk_signal_register (tx_done_signal);

  nrk_time_set(0, 0);
  cnt = 0;
  // Initially clear all the data buffers
  for(i=0; i<(MAX_NODES);i++)
  {
	for(j=0; j<(WORDS_PER_NODE); j++)
	{
		data_pkt.node_specific_data[i][j] = 0;		
	}
  }
  while (1) 
  {

  	nrk_time_get(&current_time);

	// If it is time to flood the network, send the control packets
	if(current_time.secs%FLOOD_RATE == 0 && prev_time.secs != current_time.secs || cnt == 0)
   	{
			
		prev_time = current_time;

		cnt ++;
	  	SET_PACKET_COUNT(pkt_buf.pkt_type_cnt, cnt);
#if MODE==DATA_MODE
		SET_PACKET_TYPE(pkt_buf.pkt_type_cnt, PKT_TYPE_CONTROL); 
#else
		SET_PACKET_TYPE(pkt_buf.pkt_type_cnt, PKT_TYPE_DIAG_CONTROL);
#endif
		pkt_buf.hop_number 		= 0;
	  	pkt_buf.time_to_flood		= TIME_TO_FLOOD_IN_SECS;
  		pkt_buf.bmac_check_rate 	= BMAC_CHECK_RATE_IN_MS;
	  	pkt_buf.maximum_depth 		= MAXIMUM_DEPTH;
  		pkt_buf.delay_at_each_level	= DELAY_AT_EACH_LEVEL_IN_SECS;
	  	pkt_buf.next_control_time	= NEXT_CONTROL_TIME;
  		pkt_buf.data_push_rate		= 0;	
	  	for(i=0; i<(MAX_NODES);i++)
  		{
			for(j=0; j<(WORDS_PER_NODE); j++)
			{
#if MODE==DATA_MODE
				pkt_buf.node_specific_data[i][j] = SENSOR;
#else
				pkt_buf.node_specific_data[i][j] = 0;
#endif
			}
	  	}	
	
  		memcpy(tx_buf, &pkt_buf, sizeof(pkt_buf));

		// Non-blocking send
	  	nrk_led_set (BLUE_LED);
  		val = bmac_tx_pkt_nonblocking (tx_buf, sizeof(struct message_packet));
	  	nrk_kprintf (PSTR ("Tx packet enqueued\r\n"));
  		ret = nrk_event_wait (SIG(tx_done_signal));
	  	if(ret & SIG(tx_done_signal) == 0 ) 
    			nrk_kprintf (PSTR ("TX done signal error\r\n"));
	  	nrk_led_clr (BLUE_LED);
	  }
  
	  // If a new packet has been received, then update the information
	  if(bmac_rx_pkt_ready())
	  {	
    		// Wait until an RX packet is received
		nrk_led_set (ORANGE_LED);
    	
		 // Get the RX packet 
		local_rx_tx_buf = bmac_rx_pkt_get (&len, &rssi);
    
    		for (i = 0; i < len; i++)
	      	printf ("%d", rx_buf[i]);
   		printf ("\r\n");

	    	memcpy(&pkt_buf, rx_buf, sizeof(pkt_buf));
	
    		nrk_led_clr (ORANGE_LED);
   
		// Release the RX buffer so future packets can arrive 
    		bmac_rx_pkt_release ();

		// If the received packet is a data packet then update the information, gateway just ignores the control packets
		if(GET_PACKET_TYPE(pkt_buf.pkt_type_cnt) == PKT_TYPE_DIAG_DATA || GET_PACKET_TYPE(pkt_buf.pkt_type_cnt) == PKT_TYPE_DATA)
		{
 
  	
			printf("Type 	= %d\n\r", GET_PACKET_TYPE(pkt_buf.pkt_type_cnt));
			printf("Count 	= %d\n\r", GET_PACKET_COUNT(pkt_buf.pkt_type_cnt));
			printf("Hop #	= %d\n\r", pkt_buf.hop_number);
			printf("TTF	= %d\n\r", pkt_buf.time_to_flood);
		  	printf("BCR	= %d\n\r", pkt_buf.bmac_check_rate);
		  	printf("Nmax 	= %d\n\r", pkt_buf.maximum_depth);
		  	printf("Dlev	= %d\n\r", pkt_buf.delay_at_each_level);
		  	printf("Nxt	= %d\n\r", pkt_buf.next_control_time);
		  	printf("Prate	= %d\n\r", pkt_buf.data_push_rate);		
  	
			for(i=0; i<(MAX_NODES);i++)
		  	{
				for(j=0; j<(WORDS_PER_NODE); j++)
				{
					if(pkt_buf.node_specific_data[i][j] != 0)
					data_pkt.node_specific_data[i][j] = pkt_buf.node_specific_data[i][j];		
				}
			}
			for(i=0; i<(MAX_NODES);i++)
		  	{
				printf("Value @ Node %d is %d  (cnt is %d)", i, ((int16_t)data_pkt.node_specific_data[i][1]<<4), (data_pkt.node_specific_data[i][0]&0x3F));
				printf("\n\r");
		  	}	
		}
	  }
   }	
}
Exemplo n.º 25
0
static void discover_task ()
{
    uint8_t periods_in_idle = discover_period_s / DISCOVER_TASK_PERIOD_S;
    nrk_time_t now, elapsed;
    int8_t rc;

    while (1) {
        switch (discover_state) {
            case DISCOVER_IDLE:
                if (auto_discover) {
                    if (periods_in_idle < periods_in_idle)
                        break;

                    set_state(DISCOVER_SCHEDULED);
                }
                break;

            case DISCOVER_SCHEDULED:
#if ENABLE_LED
                pulse_led(led_discover);
#endif
                set_state(DISCOVER_PENDING);
                nrk_event_signal(discover_signal);
                break;

            case DISCOVER_IN_PROGRESS:
                nrk_time_get(&now);
                nrk_time_sub(&elapsed, now, last_activity);
                if (time_cmp(&elapsed, &discover_time_out) < 0) {
                    LOG("silent for ");
                    LOGP("%lu ms\r\n", TIME_TO_MS(elapsed));
                    break;
                }

                LOG("finished, distrib routes: seq ");
                LOGP("%d\r\n", outstanding_seq);

                print_graph(&network);

                rc = calc_routes(&network, &routes);
                if (rc == NRK_OK) {
                    print_routes(&routes);
                    rc = broadcast_routes(&routes, outstanding_seq);
                    if (rc != NRK_OK)
                        LOG("WARN: failed to bcast routes\r\n");
                } else {
                    LOG("WARN: failed to calc routes\r\n");
                }
                set_state(DISCOVER_COMPLETED);
                nrk_event_signal(discover_signal);
                break;

            case DISCOVER_PENDING:
            case DISCOVER_COMPLETED:
                /* the router failed to do its part in one task period */
                set_state(DISCOVER_IDLE);
                break;

            default:
                ABORT("unexpected state\r\n");
        }
        periods_in_state++;
        nrk_wait_until_next_period();
    }
    ABORT("discover task exited\r\n");
}
Exemplo n.º 26
0
void nl_tx_task()
{
	TransmitBuffer *ptr = NULL; 				// pointer to the buffer to be transmitted 
	nrk_sig_t tx_done_signal;					// to hold the tx_done signal from the link layer 
	int8_t ret;										// to hold the return value of various functions 
	int8_t port_index;							// to store the index of the corresponding port element 
	int8_t sent;									// to count the number of times the HELLO msg was sent 
	int8_t isApplication;						// flag to indicate whether the packet in the transmit 
														// buffer is an APPLICATION / NW_CONTROL packet
	 
	nrk_time_t timeout;
	nrk_time_t start;								// used for sending network control messages 
	nrk_time_t end;	
	nrk_time_t elapsed;			
	
	// wait for the nl_rx_task to start bmac 	
	while(!bmac_started()) nrk_wait_until_next_period();
	
	// retrieve and register for the 'transmit done' signal from bmac 	
	tx_done_signal = bmac_get_tx_done_signal();
  	
  	if( nrk_signal_register(tx_done_signal) == NRK_ERROR )
  	{
  		nrk_int_disable();
  		nrk_led_set(RED_LED);
  		while(1)
  			nrk_kprintf(PSTR("NL: Error while registering for the bmax_tx_done_signal\r\n"));
  	}
	
	// initialise the timer
	nrk_time_get(&start);
	end.secs = start.secs;
	end.nano_secs = start.nano_secs;
	sent = 0;
	
	// set the radio power
	if( bmac_set_rf_power(10) == NRK_ERROR)
  	{
  		nrk_led_set(RED_LED);
  		nrk_int_disable();
  		while(1)
  			nrk_kprintf(PSTR("Error setting the transmit power\r\n"));
  	}
	while(1)
	{
		isApplication = FALSE;	// assume at the beginning that a nw_ctrl pkt will be transmitted 
				
		ret = nrk_time_sub(&elapsed, end, start);
		if(ret == 0)
		{
			nrk_int_disable();
			nrk_led_set(RED_LED);
			while(1)
				nrk_kprintf(PSTR("NL: Error returned by nrk_time_sub\r\n"));
		}
		
		nrk_time_compact_nanos(&elapsed);
		
		if(elapsed.secs >= HELLO_PERIOD)
		{	
			sent++;
			build_Msg_Hello(&mhe);				// build the 'HELLO' message
			if(DEBUG_NL == 2)
			{
				nrk_kprintf(PSTR("After building Msg_Hello, packet = "));
				print_pkt(&pkt_tx);
			}
				
			enter_cr(bm_sem, 34);
			ret = insert_tx_aq(&pkt_tx);  			// insert it into the transmit queue
			leave_cr(bm_sem, 34);
			
			if(DEBUG_NL == 2)
			{
				nrk_kprintf(PSTR("build_Msg_Hello() inserted packet."));
				print_tx_buffer();
				//print_pkt_header(&pkt_tx);
			}
			
			if(ret == NRK_ERROR && DEBUG_NL == 2)
			{
				nrk_kprintf(PSTR("HELLO msg was not inserted into the transmit queue\r\n"));
			}
			
			start.secs = end.secs;	
			start.nano_secs = end.nano_secs; // reinitialise the timer 		
		}

		if(sent >= 3) //NGB_LIST_PERIOD / HELLO_PERIOD)	// NGB_LIST period is always a multiple of HELLO_PERIOD		
		{
			build_Msg_NgbList(&mn);				// build the 'NGB_LIST' message 
									
			enter_cr(bm_sem, 34);
			ret = insert_tx_aq(&pkt_tx);  			// insert it into the transmit queue
			leave_cr(bm_sem, 34);
			
			if(DEBUG_NL == 2)
			{
				nrk_kprintf(PSTR("build_Msg_NgbList() inserted packet."));
				print_tx_buffer();
				//print_pkt_header(&pkt_tx);
			}
			
			if(ret == NRK_ERROR && DEBUG_NL == 2)
			{
				nrk_kprintf(PSTR("NGB_LIST msg was not inserted into the transmit queue\r\n"));
			}
			
			sent = 0;								// reset the value of 'sent'
		}					
		 
	
		if(rand() % 2 == 0)						// random number generator
			collect_queue_statistics();
		
		enter_cr(bm_sem, 34);		
		ptr = remove_tx_aq();
		leave_cr(bm_sem, 34);
		
		if(ptr == NULL)							// transmit queue is empty 
		{
			if(DEBUG_NL == 2)
				nrk_kprintf(PSTR("NL:Transmit queue is empty\r\n"));
			
			// update the end time 
			nrk_time_get(&end);		
				
			nrk_wait_until_next_period();	// FIX ME 
			continue;
		} 

		if(DEBUG_NL ==  2)
		{
			nrk_kprintf(PSTR("NL: nl_tx_task(): Packet removed. Packet = "));
			//print_pkt_header( &(ptr -> pkt) );
			print_pkt( &(ptr -> pkt) );
			//print_tx_buffer();
		}		
		
		// check to see the type of packet. It should be of type APPLICATION and be sent by this 
		// node  		
		if( (pkt_type(&(ptr -> pkt)) == APPLICATION) && ((ptr -> pkt).src == NODE_ADDR) )		 
		{ 		
			// remove the encapsulated TL segment from the packet 
			unpack_TL_UDP_header(&seg, (ptr -> pkt).data);
			memcpy(seg.data, (ptr -> pkt).data + SIZE_TRANSPORT_UDP_HEADER, MAX_APP_PAYLOAD);
			
			if(DEBUG_NL == 2)
			{
				nrk_kprintf(PSTR("NL: nl_tx_task(): Segment Removed = "));
				print_seg(&seg);
			}
			isApplication = TRUE;
		}	
			
		// pack the network packet header into the transmit buffer 
		pack_NW_Packet_header(tx_buf, &(ptr -> pkt));
		// append the network payload into the transmit buffer
		memcpy(tx_buf + SIZE_NW_PACKET_HEADER, (ptr -> pkt).data, MAX_NETWORK_PAYLOAD);
		
		enter_cr(bm_sem, 34);		
		insert_tx_fq(ptr);	// release the transmit buffer into the free queue 
		leave_cr(bm_sem, 34);
		if(DEBUG_NL == 2)
		{
			nrk_kprintf(PSTR("NL: nl_tx_task(): Released transmit buffer back into queue\n"));
			print_tx_buffer();
		}
		
		do
		{
			ret =  bmac_tx_pkt_nonblocking(tx_buf, SIZE_NW_PACKET);	// try to queue the buffer in link layer
			if(ret == NRK_ERROR)
				if(nrk_event_wait(SIG(tx_done_signal)) == 0)
				{
					nrk_int_disable();
					nrk_led_set(RED_LED);
					while(1)
						nrk_kprintf(PSTR("NL: Error returned by nrk_event_wait(tx_done_signal)\r\n"));
				}
		}while(ret == NRK_ERROR);
		
		// packet is queued at link layer
		timeout.secs = 10;				// set a wait period of maximum 10 seconds
		timeout.nano_secs = 0;
		if( nrk_signal_register(nrk_wakeup_signal) == NRK_ERROR )
		{
			nrk_int_disable();
			nrk_led_set(RED_LED);
			while(1)
				nrk_kprintf(PSTR("NL:nl_tx(): Error registering for nrk_wakeup_signal\r\n"));
		}
		if( nrk_set_next_wakeup(timeout) == NRK_ERROR)
		{
			nrk_int_disable();
			nrk_led_set(RED_LED);
			while(1)
				nrk_kprintf(PSTR("NL: nl_tx(): Error returned by nrk_set_next_wakeup()\r\n"));
		}		 
		nrk_led_set(BLUE_LED);
  		ret = nrk_event_wait (SIG(tx_done_signal) | SIG(nrk_wakeup_signal));	// wait for its transmission
  		if(ret == 0)
  		{
  			nrk_int_disable();
  			nrk_led_set(RED_LED);
  			while(1)
  				nrk_kprintf(PSTR("NL: Error returned by nrk_event_wait(tx_done_signal)\r\n"));
  		}
	   if(ret & SIG(tx_done_signal)) 	// bmac has successfully sent the packet over the radio 
		{
			if(isApplication == TRUE)		// it was an application layer packet 
			{
				enter_cr(tl_sem, 34);				
				port_index = port_to_port_index(seg.srcPort);
						
				if(port_index == NRK_ERROR)	// sanity check
				{
					nrk_int_disable();
					nrk_led_set(RED_LED);
					while(1)
						nrk_kprintf(PSTR("NL: nl_tx_task: Bug detected in implementation of port element array\r\n"));
				}
				// signal 'send done' signal 			
				if(nrk_event_signal(ports[port_index].send_done_signal) == NRK_ERROR)
				{
					if(nrk_errno_get() == 1)	// sanity check. This means signal was not created 
					{
						nrk_int_disable();
						nrk_led_set(RED_LED);
						while(1)
							nrk_kprintf(PSTR("NL: nl_tx_task: Bug detected in creating signals in port element array\r\n"));
					}
			   }					
				leave_cr(tl_sem, 34);	
				
			}// end if(isApplication == TRUE)
			
			else	// a network control message was transmitted. Nothing to signal
				;	// do nothing 
		
		} // end if(signal received = tx_done_signal)
		else if(ret & SIG(nrk_wakeup_signal))	
			 {
			 	//nrk_led_set(RED_LED);
			 	//nrk_int_disable();
			 	//while(1)			
			 	//{
			 		nrk_kprintf(PSTR("BMAC did not transmit the packet within specified time\r\n"));
			 	//}
			 }			
			else // unknown signal caught 
			{
				nrk_int_disable();
				nrk_led_set(RED_LED);
				while(1)
					nrk_kprintf(PSTR("NL: nl_tx_task(): Unknown signal caught\r\n"));
			}
		
		nrk_led_clr(BLUE_LED);		
		// update the end time 
		nrk_time_get(&end);
	
   } // end while(1) 
   
	return;
}
Exemplo n.º 27
0
Arquivo: main.c Projeto: Zubeen/ESE519
void Task1()
{
	int8_t rssi, slot,length; //all parameters recieved along with an rx

	printf( "Task1 PID=%d\r\n",nrk_get_pid());
	printf( "Node ID=%d\r\n",NODE_ID);

	nrk_led_set(RED_LED); 

	rtl_init (RTL_COORDINATOR);
	rtl_set_channel(MY_CHANNEL);

	rtl_set_schedule( RTL_RX, NODE_2_RX_SLOT, 1 );
	rtl_set_schedule( RTL_RX, NODE_3_RX_SLOT, 1 );
	rtl_set_schedule( RTL_TX, MY_TX_SLOT, 1 );
	//rtl_set_tx_power(MAX_POWER);
	rtl_rx_pkt_set_buffer(rx_buf, RF_MAX_PAYLOAD_SIZE); //to limit payload size
	rtl_start();
	
	while(!rtl_ready())  nrk_wait_until_next_period();  

	
	while(1)
	{
		
		if( rtl_tx_pkt_check(MY_TX_SLOT)!=0 )
		{
			//printf("Pending TX");
		}
		else
		{
                	nrk_time_get(&currentTime);
                	if(currentTime.secs-exchangeTime.secs>EXCHANGE_INTERVAL)
                	{
                		//TODO:Data to be transmitted
                		int8_t length;
				//sprintf( &tx_buf[PKT_DATA_START],"",);
				length = sprintf(&tx_buf[PKT_DATA_START], "%-+5d%-+5d",myX,myY); //TODO: Data
				printf ("(%s) is the result of our sprintf, which is %d characters long",tx_buf,length);
				length=length+PKT_DATA_START+1;
				printf("Sending: ");
/*				for(int i=PKT_DATA_START; i<length; i++ )*/
/*				{*/
/*					printf("%c",tx_buf[i] );*/
/*				}*/
/*				printf("\n\r");*/
				addToTXBuffer(tx_buf,length);
				nrk_time_get(&exchangeTime);
                	}
			fetchTxBuffer(); //Actual Transmit
               		nrk_led_toggle(BLUE_LED);
		}
		if( rtl_rx_pkt_check()!=0 )
		{
			int8_t senderNode;
			nrk_led_set(ORANGE_LED);
                   	uint8_t *local_rx_buf;
                   	local_rx_buf=rtl_rx_pkt_get(&length, &rssi, &slot);
                   	printf( "Got Packet on slot %d %d: ",slot,length );
                   	senderNode=slot/2;
                   	if(senderNode==0)
                   	{
                   		int li = atoi (&local_rx_buf[NODE_ID]);
				printf ("\nXrecd=%d",li);
				myX=li;
				li = atoi (&local_rx_buf[NODE_ID+5]);
				printf ("\nYrecd=%d",li);
				myY=li;
			}
                   	else
                   	{
                   		int li = atoi (&local_rx_buf[NODE_ID]);
				printf ("\nXrecd=%d",li);
				X[senderNode]=li;
				li = atoi (&local_rx_buf[NODE_ID+5]);
				printf ("\nYrecd=%d",li);
				Y[senderNode]=li;
                   	}
                   	
		}
		rtl_wait_until_rx_or_tx();
	}
}
Exemplo n.º 28
0
void pingMode()
{

  // Broadcast for ping
  val=bmac_addr_decode_set_my_mac(((uint16_t)my_subnet_mac<<8)|my_mac);
  val=bmac_addr_decode_dest_mac((uint16_t)0xffff);  // broadcast by default
  bmac_addr_decode_enable();
  
  uint8_t i;
  
  // Build a TX packet by hand...
  p2p_pkt.pkt_type = PING_PKT;
    // set as p2p packet (no US_MASK or DS_MASK)
  p2p_pkt.ctrl_flags = MOBILE_MASK ; // | DEBUG_FLAG ;
  p2p_pkt.ack_retry= 0x00;
  p2p_pkt.ttl = 1;
  p2p_pkt.src_subnet_mac[0] = 0;
  p2p_pkt.src_subnet_mac[1] = 0;
  p2p_pkt.src_subnet_mac[2] = 0;
  p2p_pkt.src_mac = my_mac;
  p2p_pkt.last_hop_mac = my_mac;
  p2p_pkt.dst_subnet_mac[0] = BROADCAST;
  p2p_pkt.dst_subnet_mac[1] = BROADCAST;
  p2p_pkt.dst_subnet_mac[2] = BROADCAST;
  p2p_pkt.dst_mac = BROADCAST;
  p2p_pkt.buf=tx_buf;
  p2p_pkt.buf_len = P2P_PAYLOAD_START;
  p2p_pkt.seq_num = cnt;
  p2p_pkt.priority = 0;
  cnt++;
//    p2p_pkt.payload[0]=my_mac;
//    p2p_pkt.payload_len=1;
//    ping_p2p_generate(&p2p_pkt);

  nrk_led_set (BLUE_LED);

  check_period.secs = 0;
  check_period.nano_secs = 100 * NANOS_PER_MS;
  val = bmac_set_rx_check_rate (check_period);

    // Pack data structure values in buffer before transmit
  pack_peer_2_peer_packet(&p2p_pkt);
    // For blocking transmits, use the following function call.
  val = bmac_tx_pkt (p2p_pkt.buf, p2p_pkt.buf_len);

  check_period.secs = 0;
  check_period.nano_secs = FAST_CHECK_RATE * NANOS_PER_MS;
  val = bmac_set_rx_check_rate (check_period);
#ifdef TXT_DEBUG
  nrk_kprintf (PSTR ("\r\nPING Packet Sent. Waiting for Replies...\r\n\n"));
#endif
  nrk_led_clr (BLUE_LED);
  nrk_led_clr(GREEN_LED);

    // Wait for packets or timeout
  nrk_time_get (&start);
    
  while (1) {

    timeout.secs = PING_WAIT_SECS;
    timeout.nano_secs = 0;

      // Wait until an RX packet is received
      //val = bmac_wait_until_rx_pkt ();
    nrk_set_next_wakeup (timeout);
    my_sigs = nrk_event_wait (SIG (rx_signal) | SIG (nrk_wakeup_signal));


    if (my_sigs == 0)
      nrk_kprintf (PSTR ("Error calling nrk_event_wait()\r\n"));
    if (my_sigs & SIG (rx_signal)) {	
        // Get the RX packet 
      local_rx_buf = bmac_rx_pkt_get (&len, &rssi);
	// Check the packet type from raw buffer before unpacking
      if ((local_rx_buf[CTRL_FLAGS] & (DS_MASK | US_MASK)) == 0) {
	// Set the buffer
        p2p_pkt.buf=local_rx_buf;
        p2p_pkt.buf_len=len;
        p2p_pkt.rssi=rssi;
        unpack_peer_2_peer_packet(&p2p_pkt);
        if (p2p_pkt.dst_mac == my_mac || p2p_pkt.dst_mac == BROADCAST) {
          nrk_led_set(GREEN_LED);
          // Packet arrived and is good to go
          printf( "Mac: %x%x%x",p2p_pkt.src_subnet_mac[0], p2p_pkt.src_subnet_mac[1], p2p_pkt.src_subnet_mac[2]);
          printf( "%x ",p2p_pkt.src_mac);
          printf( "| RSSI: %d ",p2p_pkt.rssi);
          printf( "| Type: %d \r\n",p2p_pkt.pkt_type);
        }
      }
      // Release the RX buffer so future packets can arrive
      bmac_rx_pkt_release ();
    }
    nrk_time_get (&current);
    if (start.secs + PING_WAIT_SECS < current.secs)
      break;
  }
  nrk_kprintf (PSTR ("\r\nDone Waiting for Response...\r\n"));
  nrk_led_clr(GREEN_LED);
}
Exemplo n.º 29
0
static void periodic_task()
{
    nrk_sig_mask_t wait_mask, func_wait_mask;
    nrk_time_t next_event, func_next_event;
    periodic_func_t **funcp;
    periodic_func_t *func;
    nrk_time_t now, sleep_time;
    int8_t rc;

    funcp = &functions[0];
    while (*funcp) {
        func = *funcp;
        LOG("init: "); LOGF(func->name); LOGNL();
        if (func->init)
            func->init();
        funcp++;
    }

    rc = nrk_signal_register(func_signal);
    if (rc == NRK_ERROR)
        ABORT("reg sig: func\r\n");

    while (1) {

        LOG("awake\r\n");

        TIME_CLEAR(next_event);

        wait_mask = SIG(func_signal);

        funcp = &functions[0];
        while (*funcp) {
            func = *funcp;

            TIME_CLEAR(func_next_event);
            func_wait_mask = 0;

            if (func->enabled ||
                func->enabled != func->last_enabled) {

                LOG("proc: "); LOGF(func->name); LOGNL();
                ASSERT(func->proc);

                func->proc(func->enabled,
                           &func_next_event, &func_wait_mask);
            }
            func->last_enabled = func->enabled;

            wait_mask |= func_wait_mask;
            if (IS_VALID_TIME(func_next_event) &&
                (!IS_VALID_TIME(next_event) ||
                 time_cmp(&func_next_event, &next_event) < 0)) {
                next_event = func_next_event;
            }

            funcp++;
        }

        if (IS_VALID_TIME(next_event)) {
            nrk_time_get(&now);
            rc = nrk_time_sub(&sleep_time, next_event, now);
            if (rc != NRK_OK) {
                LOG("next event in the past\r\n");
                continue;
            }
            LOG("sleeping for: ");
            LOGP("%lu ms\r\n", TIME_TO_MS(sleep_time));
            nrk_set_next_wakeup(sleep_time);
            wait_mask |= SIG(nrk_wakeup_signal);
        }
        LOG("waiting\r\n");
        nrk_event_wait( wait_mask );
    }

    ABORT("periodic task exited\r\n");
}
Exemplo n.º 30
0
void tdma_nw_task ()
{
  int8_t v, i;
  uint16_t slot, tmp,sync;
  nrk_sig_mask_t event;

  do {
    nrk_wait_until_next_period ();
  } while (!tdma_started ());
  _tdma_slot_time.nano_secs = TDMA_DEFAULT_SLOT_MS * NANOS_PER_MS;
  _tdma_slot_time.secs = 0;

//register the signal after bmac_init has been called
  v = nrk_signal_register (tdma_enable_signal);
  if (v == NRK_ERROR)
    nrk_kprintf (PSTR ("Failed to register signal\r\n"));
  slot = 0;
//rf_set_rx (&tdma_rfRxInfo, tdma_chan);



  while (1) {
    if (tdma_mode == TDMA_HOST) {
	    sync_status=1; // HOST is always synced
      // This is the downstream transmit slot
      if (slot == 0) {

        //rf_rx_off();
        // If there is no pending packet, lets make an empty one
        if (tx_data_ready == 0) {
          tdma_rfTxInfo.pPayload = tdma_tx_buf;
          // Setup the header data
          tdma_rfTxInfo.pPayload[TDMA_DST_LOW] = 0xff;  // dst
          tdma_rfTxInfo.pPayload[TDMA_DST_HIGH] = 0xff;
          tdma_rfTxInfo.pPayload[TDMA_SRC_LOW] = 0x00;  // src
          tdma_rfTxInfo.pPayload[TDMA_SRC_HIGH] = 0x00;
          tdma_rfTxInfo.pPayload[TDMA_SEQ_NUM_LOW] = 0x00;      // seq num
          tdma_rfTxInfo.pPayload[TDMA_SEQ_NUM_HIGH] = 0x00;
          tdma_rfTxInfo.length = TDMA_PCF_HEADER;
        }
        tdma_rfTxInfo.pPayload[TDMA_CYCLE_SIZE_LOW] = tdma_slots_per_cycle & 0xff;      // cycle size 
        tdma_rfTxInfo.pPayload[TDMA_CYCLE_SIZE_HIGH] =
          tdma_slots_per_cycle >> 8;
        tdma_rfTxInfo.pPayload[TDMA_SLOT_LOW] = 0;      // slot
        tdma_rfTxInfo.pPayload[TDMA_SLOT_HIGH] = 0;
        tdma_rfTxInfo.pPayload[TDMA_SLOT_SIZE] = tdma_slot_len_ms;
        nrk_time_get (&_tdma_next_wakeup);
        tdma_rfTxInfo.destAddr = 0xffff;
        tdma_rfTxInfo.ackRequest = 0;
        tdma_rfTxInfo.cca = 0;
        _tdma_tx ();
        rf_rx_on ();
      }
      else {
        // Upstream data slot
        v = _tdma_rx ();
        if (v == 1)
          tdma_last_tx_slot = slot;
      }
      slot++;
      if (slot >= tdma_slots_per_cycle + 1)
        slot = 0;
      nrk_time_add (&_tdma_next_wakeup, _tdma_next_wakeup, _tdma_slot_time);
      nrk_time_compact_nanos (&_tdma_next_wakeup);
      nrk_wait_until (_tdma_next_wakeup);

    }