Beispiel #1
0
int8_t nrk_sem_post(nrk_sem_t *rsrc)
{
	int8_t id=nrk_get_resource_index(rsrc);	
	int8_t task_ID;
	if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;}
	if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; }

	if(nrk_sem_list[id].value<nrk_sem_list[id].count)
	{
		// Signal RSRC Event		
		nrk_int_disable();

		nrk_sem_list[id].value++;
		sc = system_ceiling();
		nrk_cur_task_TCB->elevated_prio_flag=0;

		for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++){
			if(nrk_task_TCB[task_ID].event_suspend==RSRC_EVENT_SUSPENDED)
				if((nrk_task_TCB[task_ID].active_signal_mask == id))
				{
					nrk_task_TCB[task_ID].task_state=SUSPENDED;
					nrk_task_TCB[task_ID].next_wakeup=0;
					nrk_task_TCB[task_ID].event_suspend=0;
					nrk_task_TCB[task_ID].active_signal_mask=0;
				}   

		}
		nrk_int_enable();
	}
		
return NRK_OK;
}
Beispiel #2
0
int8_t nrk_reserve_consume (uint8_t reserve_id)
{

  if (reserve_id >= NRK_MAX_RESERVES) {
    _nrk_errno_set (1);
    return NRK_ERROR;
  }
  if (_nrk_reserve[reserve_id].active == -1) {
    _nrk_errno_set (2);
    return NRK_ERROR;
  }

  _nrk_reserve_update (reserve_id);

  if ((_nrk_reserve[reserve_id].set_access <=
       _nrk_reserve[reserve_id].cur_access)) {
    // You violated your resource (like MJ after a little boy)
    nrk_int_enable ();
    if (_nrk_reserve[reserve_id].error != NULL)
      _nrk_reserve[reserve_id].error ();
    return NRK_ERROR;
  }
  else {
    // Reserve is fine. Take some of it.
    _nrk_reserve[reserve_id].cur_access++;
  }


  return NRK_OK;
}
Beispiel #3
0
int8_t nrk_sem_pend(nrk_sem_t *rsrc )
{
	int8_t id;
	id=nrk_get_resource_index(rsrc);  
	if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;}
	if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; }
	
	nrk_int_disable();
	if(nrk_sem_list[id].value==0)
	{
		nrk_cur_task_TCB->event_suspend|=RSRC_EVENT_SUSPENDED;
		nrk_cur_task_TCB->active_signal_mask=id;
		// Wait on suspend event
		nrk_int_enable();
		nrk_wait_until_ticks(0);
	}

	nrk_sem_list[id].value--;	
		sc = system_ceiling();
	nrk_cur_task_TCB->task_prio_ceil=nrk_sem_list[id].resource_ceiling;
	nrk_cur_task_TCB->elevated_prio_flag=1;
	nrk_int_enable();

	return NRK_OK;
}
Beispiel #4
0
int8_t nrk_sem_query(nrk_sem_t *rsrc )
{
	int8_t id;
	id=nrk_get_resource_index(rsrc);
	if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;}
	if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; }

	return(nrk_sem_list[id].value);
}
Beispiel #5
0
int8_t nrk_event_signal(int8_t sig_id)
{

	uint8_t task_ID;
	uint8_t event_occured=0;
	uint32_t sig_mask;

	sig_mask=SIG(sig_id);
	// Check if signal was created
	// Signal was not created
	if((sig_mask & _nrk_signal_list)==0 ) { _nrk_errno_set(1); return NRK_ERROR;}

	//needs to be atomic otherwise run the risk of multiple tasks being scheduled late and not in order of priority.
	nrk_int_disable();
	for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++){


	//	if (nrk_task_TCB[task_ID].task_state == EVENT_SUSPENDED)
	//	{
	//	printf( "task %d is event suspended\r\n",task_ID );
			if(nrk_task_TCB[task_ID].event_suspend==SIG_EVENT_SUSPENDED)
				if((nrk_task_TCB[task_ID].active_signal_mask & sig_mask))
				{
					nrk_task_TCB[task_ID].task_state=SUSPENDED;
					nrk_task_TCB[task_ID].next_wakeup=0;
					nrk_task_TCB[task_ID].event_suspend=0;
					// Add the event trigger here so it is returned
					// from nrk_event_wait()
					nrk_task_TCB[task_ID].active_signal_mask=sig_mask;
					event_occured=1;
				}

			if(nrk_task_TCB[task_ID].event_suspend==RSRC_EVENT_SUSPENDED)
				if((nrk_task_TCB[task_ID].active_signal_mask == sig_mask))
				{
					nrk_task_TCB[task_ID].task_state=SUSPENDED;
					nrk_task_TCB[task_ID].next_wakeup=0;
					nrk_task_TCB[task_ID].event_suspend=0;
					// Add the event trigger here so it is returned
					// from nrk_event_wait()
					nrk_task_TCB[task_ID].active_signal_mask=0;
					event_occured=1;
				}

	//	}
	}
	nrk_int_enable();
	if(event_occured)
	{
		return NRK_OK;
	}
	// No task was waiting on the signal
	_nrk_errno_set(2);
	return NRK_ERROR;
}
Beispiel #6
0
int8_t  nrk_sem_delete(nrk_sem_t *rsrc)
{
int8_t id=nrk_get_resource_index(rsrc);
	int8_t task_ID;
	if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;}
	if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; }

	nrk_sem_list[id].count=-1;
	nrk_sem_list[id].value=-1;
	nrk_sem_list[id].resource_ceiling=-1;
	_nrk_resource_cnt--;
return NRK_OK;
}
Beispiel #7
0
int8_t slip_tx (uint8_t * buf, uint8_t size)
{
  uint8_t i;
  int8_t v;
  uint8_t checksum;

// Make sure size is less than 128 so it doesn't act as a control
// message
  if (size > 128) {
    _nrk_errno_set (3);
    return NRK_ERROR;
  }

  v = nrk_sem_pend (slip_tx_sem);
  if (v == NRK_ERROR) {
    nrk_kprintf (PSTR ("SLIP TX ERROR:  Access to semaphore failed\r\n"));
    _nrk_errno_set (1);
    return NRK_ERROR;
  }

// Send the start byte
  put_byte (START);
  put_byte (size);

  checksum = 0;

// Send payload and stuff bytes as needed
  for (i = 0; i < size; i++) {
    if (buf[i] == END || buf[i] == ESC)
      put_byte (ESC);
    put_byte (buf[i]);
    checksum += buf[i];
  }

// Make sure checksum is less than 128 so it doesn't act as a control
// message
  checksum &= 0x7F;
  // Send the end byte
  put_byte (checksum);
  put_byte (END);
  v = nrk_sem_post (slip_tx_sem);
  if (v == NRK_ERROR) {
    nrk_kprintf (PSTR ("SLIP TX ERROR:  Release of semaphore failed\r\n"));
    _nrk_errno_set (2);
    return NRK_ERROR;
  }
  return NRK_OK;
}
Beispiel #8
0
uint8_t nrk_reserve_get (uint8_t reserve_id)
{

  if (reserve_id >= NRK_MAX_RESERVES) {
    _nrk_errno_set (1);
    return 0;
  }
  if (_nrk_reserve[reserve_id].active == -1) {
    // Reserve isn't active 
    _nrk_errno_set (2);
    return 0;
  }

  _nrk_reserve_update (reserve_id);

  if (_nrk_reserve[reserve_id].cur_access >
      _nrk_reserve[reserve_id].set_access)
    return 0;
  return (_nrk_reserve[reserve_id].set_access -
          _nrk_reserve[reserve_id].cur_access);
}
Beispiel #9
0
int8_t nrk_sem_pend(nrk_sem_t *rsrc )
{
	int8_t id;
	id=nrk_get_resource_index(rsrc);
	if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;}
	if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; }

	/* if (_nrk_system_ceiling > nrk_sem_list[id].resource_ceiling) */
	/* { */
	/* 	nrk_wait_until_ticks(0); */
	/* } */
	//get access to the semaphore
	nrk_int_disable();
	nrk_sem_list[id].value--;
        if(_nrk_system_ceiling < rsrc->resource_ceiling)
	  _nrk_system_ceiling = rsrc->resource_ceiling;
	_nrk_ceiling_stack[++_nrk_ceiling_tos]= nrk_sem_list[id].resource_ceiling;
	nrk_int_enable();
	//nrk_wait_until_ticks(0);
	return NRK_OK;
}
Beispiel #10
0
int8_t nrk_sem_post(nrk_sem_t *rsrc)
{
	int8_t id=nrk_get_resource_index(rsrc);
	int8_t task_ID;
	if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;}
	if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; }

	if(nrk_sem_list[id].value<nrk_sem_list[id].count)
	{
		// Signal RSRC Event
		nrk_int_disable();

		nrk_sem_list[id].value++;
		//nrk_cur_task_TCB->elevated_prio_flag=0;

		//should not be blocking under srp
		/*
		for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++){
			if(nrk_task_TCB[task_ID].event_suspend==RSRC_EVENT_SUSPENDED)
				if((nrk_task_TCB[task_ID].active_signal_mask == id))
				{
					nrk_task_TCB[task_ID].task_state=SUSPENDED;
					nrk_task_TCB[task_ID].next_wakeup=0;
					nrk_task_TCB[task_ID].event_suspend=0;
					nrk_task_TCB[task_ID].active_signal_mask=0;
				}

				}*/
		if(_nrk_system_ceiling == _nrk_ceiling_stack[_nrk_ceiling_tos--])
		  _nrk_system_ceiling= _nrk_ceiling_stack[_nrk_ceiling_tos];
		nrk_int_enable();
		nrk_wait_until_ticks(0);
	}

return NRK_OK;
}
Beispiel #11
0
int8_t set_excess_policy(int8_t prio, int8_t pref)	// user API 
{
	if(prio <= 0 || prio > MAX_PRIORITY || is_excess_policy_valid(pref) == FALSE)
	{
		_nrk_errno_set(INVALID_ARGUMENT);
		return NRK_ERROR;
	}
	
	enter_cr(bm_sem, 39);	// enter CR 
		
	if(pref == DROP)	// set bit number 'prio' in excessPolicySettings to 1
		excessPolicySettings |= (uint32_t)1 << prio;
	else					// set bit number 'prio' in excessPolicySettings to 0
		excessPolicySettings &= ~( (uint32_t)1 << prio );
	
	leave_cr(bm_sem, 39);	// leave CR 
		
	return NRK_OK;
}
Beispiel #12
0
int8_t sendToGateway(uint8_t *ptr, int8_t len)	// user API 
{
	uint8_t gw_buf[SIZE_NODETOGATEWAYSERIAL_PACKET] = {0};
		
	if(len <= 0 || len > MAX_SERIAL_PAYLOAD || ptr == NULL || CONNECTED_TO_GATEWAY == FALSE)	// bad input 
	{
		_nrk_errno_set(INVALID_ARGUMENT);
		return NRK_ERROR;
	}
	
	// fill up the members of the transmit buffer 
	gw_buf[0] = SERIAL_APPLICATION;
	gw_buf[1] = len;
	memcpy(gw_buf + SIZE_NODETOGATEWAYSERIAL_PACKET_HEADER, ptr, len);
	
	sendToSerial(gw_buf, SIZE_NODETOGATEWAYSERIAL_PACKET);
	//printBuffer(gw_buf, SIZE_NODETOGATEWAYSERIAL_PACKET);
	
	return NRK_OK;
}
Beispiel #13
0
int8_t get_excess_policy(int8_t prio)	// user API 
{
	if(prio <= 0 || prio > MAX_PRIORITY)
	{
		_nrk_errno_set(INVALID_ARGUMENT);
		return NRK_ERROR;
	}	
	
	enter_cr(bm_sem, 40);
		
	// check the state of bit number 'prio' in excessPolicySettings 
	if( ((excessPolicySettings >> prio) & ((uint32_t)1)) == 0 ) // is bit 'prio' cleared
	{
		leave_cr(bm_sem, 40);	
		return OVERWRITE;
	}
	
	leave_cr(bm_sem, 40);
	return DROP;
}
Beispiel #14
0
/******************************* FUNCTION DEFINITIONS ***************************************/
inline int8_t add_neighbor(Neighbor n)
{
	int8_t i;					// loop index
	int8_t found = FALSE;	// flag to indicate whether neighbor was found in array
	
	/* first pass through array checks to see 
		1. if the neighbor had been recorded before
		2. decrements the lastReport (and possibly removes) of each neighbor
	*/
	
	enter_cr(nl_sem, 19);
	for(i = 0; i < MAX_NGBS; i++)	
	{
		// search to see if this neighbor has been recorded before		
		if(nl.ngbs[i].addr == n.addr)
		{
			found = TRUE;
			// update last reported
			nl.ngbs[i].lastReport = TIMEOUT_COUNTER;
			nl.ngbs[i].isNew = FALSE;
			nl.ngbs[i].rssi = n.rssi;
		}
		else if(nl.ngbs[i].addr != BCAST_ADDR)		// entry at this position is valid
      {
			nl.ngbs[i].lastReport--;					// decrement lastReport
			if(nl.ngbs[i].lastReport == 0)			// should I remove this neighbor?
			{
				nl.ngbs[i].addr = BCAST_ADDR;			// invalidate this entry
				nl.ngbs[i].rssi = 0;						// zero out the remaining two entries 
				nl.ngbs[i].isNew = FALSE;
				nl.count--;									// decrement number of ngbs recorded
			}
		}
	} // end for 

	if(found == TRUE)			// neighbor was already present in array; do nothing further
	{
		leave_cr(nl_sem, 19);	
		return NRK_OK;
	}
	
	// check to see if the addition of a new neighbor is possible 	
	if(nl.count == MAX_NGBS)		// cannot store more than MAX_NGBS neighbors
	{
		_nrk_errno_set(MAX_NEIGHBOR_LIMIT_REACHED);
		
		leave_cr(nl_sem, 19);		
		return NRK_ERROR;
	}
	
	/* second pass through array adds the new neighbor */
	for(i = 0; i < MAX_NGBS; i++)	
	{
		if(nl.ngbs[i].addr == BCAST_ADDR)		// this position in array holds an invalid entry
		{
			n.lastReport = TIMEOUT_COUNTER;		// set lastReport to timeout value
			n.isNew = TRUE;							// a new neighbor has reported 
			nl.ngbs[i] = n;							// place the new neighbor at this array index
			nl.count++;									// increment the number of neighbors recorded
			break;
		}
	}
	
	if(i == MAX_NGBS)									// sanity check for debugging
	{
		nrk_int_disable();
		nrk_led_set(RED_LED);
		while(1)
			nrk_kprintf(PSTR("add_neighbor(): Bug found in implementation of MAX_NGBS\r\n"));
	}
		
	leave_cr(nl_sem, 19);	
	return NRK_OK; 
}
Beispiel #15
0
int8_t set_routing_algorithm(int8_t pref, int8_t type, int8_t pdist)
{
	switch(pref)
	{
		case LINK_STATE:
			break;
			
		case FLOODING:
		{
			switch(type)
			{
				case TTL_BASED:
					break;
				
				case PROBABILISTIC:
				{
					switch(pdist)
					{
						case RANDOM:
						case GAUSSIAN:
							break;
							
						default:
						{
							_nrk_errno_set(INVALID_ARGUMENT);
							return NRK_ERROR;
						}
  					} // end switch(pdist)
					break;  					
  				} // end case PROBABILISTIC:
  				  				
  				default:	// invalid flooding type 
  				{
  					_nrk_errno_set(INVALID_ARGUMENT);
  					return NRK_ERROR;
  				}
  			} // end switch(type)
			break;
		} // end case FLOODING 
		
		default: // invalid routing algorithm preference
		{
			_nrk_errno_set(INVALID_ARGUMENT);
			return NRK_ERROR;
		}
	} // end switch(pref)
	
	enter_cr(nl_sem, 19);
	ROUTING_ALGORITHM = pref;
	if(pref == FLOODING)
	{
		FLOODING_TYPE = type;
		if(type == PROBABILISTIC)
		{
			P_DISTRIBUTION = pdist;
		}
	}
	leave_cr(nl_sem, 19);
	
	return NRK_OK;
}
Beispiel #16
0
//-------------------------------------------------------------------------------------------------------
//  void rf_init(RF_RX_INFO *pRRI, uint8_t channel, WORD panId, WORD myAddr)
//
//  DESCRIPTION:
//      Initializes CC2420 for radio communication via the basic RF library functions. Turns on the
//		voltage regulator, resets the CC2420, turns on the crystal oscillator, writes all necessary
//		registers and protocol addresses (for automatic address recognition). Note that the crystal
//		oscillator will remain on (forever).
//
//  ARGUMENTS:
//      RF_RX_INFO *pRRI
//          A pointer the RF_RX_INFO data structure to be used during the first packet reception.
//			The structure can be switched upon packet reception.
//      uint8_t channel
//          The RF channel to be used (11 = 2405 MHz to 26 = 2480 MHz)
//      WORD panId
//          The personal area network identification number
//      WORD myAddr
//          The 16-bit short address which is used by this node. Must together with the PAN ID form a
//			unique 32-bit identifier to avoid addressing conflicts. Normally, in a 802.15.4 network, the
//			short address will be given to associated nodes by the PAN coordinator.
//-------------------------------------------------------------------------------------------------------
void rf_init(RF_RX_INFO *pRRI, uint8_t channel, uint16_t panId, uint16_t myAddr)
{
    uint8_t n;

#ifdef RADIO_PRIORITY_CEILING
    int8_t v;
    radio_sem = nrk_sem_create(1,RADIO_PRIORITY_CEILING);
    if (radio_sem == NULL)
        nrk_kernel_error_add (NRK_SEMAPHORE_CREATE_ERROR, nrk_get_pid ());

    v = nrk_sem_pend (radio_sem);
    if (v == NRK_ERROR)
    {
        nrk_kprintf (PSTR ("CC2420 ERROR:  Access to semaphore failed\r\n"));
    }
#endif

    // Make sure that the voltage regulator is on, and that the reset pin is inactive
    SET_VREG_ACTIVE();
    halWait(1000);
    SET_RESET_ACTIVE();
    halWait(1);
    SET_RESET_INACTIVE();
    halWait(100);

    // Initialize the FIFOP external interrupt
    //FIFOP_INT_INIT();
    //ENABLE_FIFOP_INT();

    // Turn off all interrupts while we're accessing the CC2420 registers
    DISABLE_GLOBAL_INT();

    FASTSPI_STROBE(CC2420_SXOSCON);
    mdmctrl0=0x02E2;
    FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0);  // Std Preamble, CRC, no auto ack, no hw addr decoding
    //FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AF2);  // Turn on automatic packet acknowledgment
    // Turn on hw addre decoding
    FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0500); // Set the correlation threshold = 20
    FASTSPI_SETREG(CC2420_IOCFG0, 0x007F);   // Set the FIFOP threshold to maximum
    FASTSPI_SETREG(CC2420_SECCTRL0, 0x01C4); // Turn off "Security"
    FASTSPI_SETREG(CC2420_RXCTRL1, 0x1A56); // All default except
    // reference bias current to RX
    // bandpass filter is set to 3uA

    /*
        // FIXME: remove later for auto ack
        myAddr=MY_MAC;
        panId=0x02;
        FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AF2);  // Turn on automatic packet acknowledgment
    //    FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AE2);  // Turn on automatic packet acknowledgment
        nrk_spin_wait_us(500);
        nrk_spin_wait_us(500);
        FASTSPI_WRITE_RAM_LE(&myAddr, CC2420RAM_SHORTADDR, 2, n);
        nrk_spin_wait_us(500);
        FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n);
        nrk_spin_wait_us(500);

       printf( "myAddr=%d\r\n",myAddr );
    */

    nrk_spin_wait_us(500);
    FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n);
    nrk_spin_wait_us(500);

    ENABLE_GLOBAL_INT();

    // Set the RF channel
    halRfSetChannel(channel);

    // Turn interrupts back on
    ENABLE_GLOBAL_INT();

    // Set the protocol configuration
    rfSettings.pRxInfo = pRRI;
    rfSettings.panId = panId;
    rfSettings.myAddr = myAddr;
    rfSettings.txSeqNumber = 0;
    rfSettings.receiveOn = FALSE;

    // Wait for the crystal oscillator to become stable
    halRfWaitForCrystalOscillator();

    // Write the short address and the PAN ID to the CC2420 RAM (requires that the XOSC is on and stable)
    //	DISABLE_GLOBAL_INT();
//    FASTSPI_WRITE_RAM_LE(&myAddr, CC2420RAM_SHORTADDR, 2, n);
//    FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n);
    //	ENABLE_GLOBAL_INT();

#ifdef RADIO_PRIORITY_CEILING
    v = nrk_sem_post (radio_sem);
    if (v == NRK_ERROR)
    {
        nrk_kprintf (PSTR ("CC2420 ERROR:  Release of semaphore failed\r\n"));
        _nrk_errno_set (2);
    }
#endif

    auto_ack_enable=0;
    security_enable=0;
    last_pkt_encrypted=0;
} // rf_init()