📄 vmac.c
字号:
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 + -