⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmac.c

📁 SOS操作系统用于无线传感器网络节点的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
          sleeptime = MacBackoff_congestionBackoff(retry_count);
          //sleeptime=500;
	  ker_timer_restart(RADIO_PID, WAKEUP_TIMER_TID, sleeptime);	// setup backoff timer	

          //msg_send_senddone(msg, 0, RADIO_PID);		//release the memory for the msg
        }
/*
	if( Radio_Check_CCA() ) {
		radio_msg_send(msg);
		msg_send_senddone(msg, 1, RADIO_PID);
	}
	else {
		if( getMsgNumOfQueue() < MAX_MSGS_IN_QUEUE )		//queue is full?
			mq_enqueue(&vmac_pq, msg);
		else
			msg_send_senddone(msg, 0, RADIO_PID);		//release the memory for the msg
		sleeptime = MacBackoff_congestionBackoff(retry_count);
		ker_timer_restart(RADIO_PID, WAKEUP_TIMER_TID, sleeptime);	// setup backoff timer		
	}
        */
}

/*************************************************************************
 * get message number in the queue                                       *
 *************************************************************************/
static uint8_t getMsgNumOfQueue()
{
	uint8_t ret = 0;
	HAS_CRITICAL_SECTION;
	ENTER_CRITICAL_SECTION();
	ret = vmac_pq.msg_cnt;
	LEAVE_CRITICAL_SECTION();
	return ret;
}

/*************************************************************************
 * check whether the queue is empty                                      *
 *************************************************************************/
static int8_t isQueueEmpty()
{
	return ( getMsgNumOfQueue()==0 );
}

/*************************************************************************
 * implement backoff mechanism for Colliosn Avoidance                    *
 *************************************************************************/
void backoff_timeout()
{
        //printf("backoff\n");
	if( isQueueEmpty() )
		return;
        //printf("backoff not empty\n");
	Message *msg = NULL;
        msg = mq_dequeue(&vmac_pq);	// dequeue packet from mq
        if(msg) {
			if (radio_msg_send(msg))
                        {
                          msg_send_senddone(msg, 1, RADIO_PID);
			  resetRetries();				//set retry_count 0
                          return ;
                        }
			
		}	
        //send failed
      if( getRetries()  < (uint8_t)MAX_RETRIES ) {
        mq_enqueue(&vmac_pq,msg);//by zhou ya jin
	incRetries();				
      }
      else
      {
        //msg = mq_dequeue(&vmac_pq);			// dequeue packet from mq
        //msg has been dequeued

	if(msg) {
	  msg_send_senddone(msg, 0, RADIO_PID);	//to release the memory for this msg
	  resetRetries();		
        }
      }
      uint16_t sleeptime = MacBackoff_congestionBackoff(retry_count);
      //sleeptime = 500;
      ker_timer_restart(RADIO_PID, WAKEUP_TIMER_TID, sleeptime);	// setup new backoff timer

/*

	if( Radio_Check_CCA() ) {
		msg = mq_dequeue(&vmac_pq);	// dequeue packet from mq
		if(msg) {
			radio_msg_send(msg);
			msg_send_senddone(msg, 1, RADIO_PID);
			resetRetries();				//set retry_count 0
		}	
	} else {
		if( getRetries()  < (uint8_t)MAX_RETRIES ) {
			incRetries();				//increase retry_count
		} else {
			msg = mq_dequeue(&vmac_pq);			// dequeue packet from mq
			if(msg) {
				msg_send_senddone(msg, 0, RADIO_PID);	//to release the memory for this msg
				resetRetries();				//set retry_count 0
			}
		}		
	}
	uint16_t sleeptime = MacBackoff_congestionBackoff(retry_count);
	ker_timer_restart(RADIO_PID, WAKEUP_TIMER_TID, sleeptime);	// setup new backoff timer

      */
}
/*************************************************************************
 * Implement exponential backoff mechanism                               *
 *************************************************************************/
static int16_t MacBackoff_congestionBackoff(int8_t retries)
{
	int8_t i;
	int16_t masktime = 1;
	for(i=0; i<retries; i++)
		masktime *= 2;			//masktime = 2^retries
	masktime --;				//get the mask
	if( masktime > 1023 )
		masktime = MS1000;		//max backoff 1023
//	return ((ker_rand() & 0xF) + TIMER_MIN_INTERVAL);
	return ((ker_rand() & masktime) + TIMER_MIN_INTERVAL);
        //return ((ker_rand() & masktime) + MS100);
        //return 20;
}

void mac2message(Message *msg)
{
  uint8_t offset;
  uint8_t *receive_data;
  offset=0;


  receive_data=rxData.payload;
  memcpy(&(msg->did),receive_data+offset,sizeof(msg->did));
  offset += sizeof(msg->did);
  memcpy(&(msg->sid),receive_data+offset,sizeof(msg->sid));
  offset += sizeof(msg->sid);
  memcpy(&(msg->daddr),receive_data+offset,sizeof(msg->daddr));
  offset += sizeof(msg->daddr);
  memcpy(&(msg->saddr),receive_data+offset,sizeof(msg->saddr));
  offset += sizeof(msg->saddr);
  memcpy(&(msg->type),receive_data+offset,sizeof(msg->type));
  offset += sizeof(msg->type);
  msg->len = rxData.payloadLength-MESSAGE_RADIO_PAYLOAD_HEADER_LEN;
  offset += sizeof( msg->len);
  memcpy(&(msg->flag),receive_data+offset,sizeof(msg->flag));
  offset += sizeof(msg->flag);

  /*
  if (msg->len <=SOS_MSG_PAYLOAD_LENGTH)
    memcpy(msg->payload,receive_data+offset,msg->len);
  else
  {
    msg->data=ker_malloc(msg->len,RADIO_PID);
    if (msg->data==NULL)
      return;
    else
      memcpy(msg->data,receive_data+offset,msg->len);
  }
*/

  /* change the above by wmchen. The last byte of the msg->data is RSSI. The length include that of RSSI*/
  if (msg->len+1 <=SOS_MSG_PAYLOAD_LENGTH)
    memcpy(msg->payload,receive_data+offset,msg->len+1);
  else
  {
    msg->data=ker_malloc(msg->len+1,RADIO_PID);
    if (msg->data==NULL)
      return;
    else
      memcpy(msg->data,receive_data+offset,msg->len+1);
  }
  msg->len=msg->len+1;
   /* end change*/

}
void _MacRecvCallBack(int16_t timestamp)
{
      Message *msg = msg_create();
      mac2message(msg);
//timestamp_incoming(msg, ker_systime32());
      /*NOTICE:
      if we do not put off SOS_MSG_RELIABLE of incoming msg,
      receiver will send sendone message to itself.
      */
      msg->flag &= ~(SOS_MSG_RELIABLE); //by zhou ya jin

      handle_incoming_msg(msg, SOS_MSG_RADIO_IO);
}
extern uint16_t node_address; //in sos_info.c
void mac_init()
{
  UINT32 frequency = 2405000;
  radioInit(frequency, node_address);

  sched_register_kernel_module(&vmac_module, sos_get_header_address(mod_header), NULL);
	
 // Timer needs to be done after reigsteration
  ker_permanent_timer_init(&wakeup_timer, RADIO_PID, WAKEUP_TIMER_TID, TIMER_ONE_SHOT);
	
  mq_init(&vmac_pq);	//! Initialize sending queue
  resetSeq();		//set seq_count 0
  resetRetries(); 	//set retries 0

  sppSetRxCallBackFunction(_MacRecvCallBack);
  //receiving data
  sppReceive(&rxData);

}

//-----------------------------------------------------------------------------
// See hal.h for a description of this function.
//-----------------------------------------------------------------------------
BOOL halRfConfig(UINT32 frequency)
{
   BOOL status;

   //Turning on crystal oscillator
   SET_MAIN_CLOCK_SOURCE(CRYSTAL);

   // Setting the frequency
   halRfSetRadioFrequency(frequency);

   // Checking that the entered frequency is valid
   if (frequency > 2047000)
   {
      //turning on power to analog part of radio and waiting for voltage regulator.
      RFPWR = 0x04;
      while((RFPWR & 0x10)){}
      // Turning off Address Decoding
      MDMCTRL0H &= ~ADR_DECODE;

      // Setting for AUTO CRC
      MDMCTRL0L |= AUTO_CRC;

      // Turning on AUTO_TX2RX
      FSMTC1 = ((FSMTC1 & (~AUTO_TX2RX_OFF & ~RX2RX_TIME_OFF))  | ACCEPT_ACKPKT);

      // Turning off abortRxOnSrxon.
      FSMTC1 &= ~0x20;

      status = TRUE;
   }
   else {
      status = FALSE;
   }

   return status;
}
//------------------------------------------------------------------------------------------------------
// See hal.h for a description of this function.
//------------------------------------------------------------------------------------------------------
BYTE halSetTimer34Period(BYTE timer, DWORD period){

        BYTE div = 0;

        if(TICKSPD > 5) { // Checking that the period is not too short.
        if( (period < 2*(TICKSPD-5)) && (period != 0) ){
               return 0;
           }
    }

        if(period == 0){  // If period is 0, max period length and max prescaler
                div = 7;  // division is used.
                period = 255;
        } else {
                period = ((period*32) >> TICKSPD);// Determining how many timer ticks the period consist of
                while(period > 255){              // If the period is too long, the prescaler division is
                        period = (period >> 1);   // increased.
                        div++;
                        if(div > 7){              // If the period is too long when using max prescaler division,
                                return 0;         // 0 is returned.
                        }
                }
        }

        if(timer == 4){
                // Timer 4 selected
                T4CTL |= (div << 5);              // Setting prescaler value
                T4CC0 = (BYTE) period;            // Setting timer value.
        } else if(timer == 3){
                // Timer 3 selected
                T3CTL |= (div << 5);              // Setting prescaler value
                T3CC0 = (BYTE) period;            // Setting timer value.
        } else {return 0;}

        return period;
}
//-----------------------------------------------------------------------------
// See hal.h for a description of this function.
//-----------------------------------------------------------------------------
void halRfSetRadioFrequency(UINT32 frequency)
{

   frequency /= 1000;
   frequency -= 2048;
   FSCTRLL = (BYTE) frequency;
   FSCTRLH = ((FSCTRLH & ~0x03) | (BYTE)((frequency >> 8) & 0x03));
   return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -