📄 acbasem.nc
字号:
/* Anycast/Marzullo Base Implmentation. *//* Modified by Kin Sun Ho (ksho@cse) *//* Last Modified: 06 September 2005 *//* Modified from TOSBase *//* * @author Phil Buonadonna * @author Gilman Tolle *//* leds red: sending broadcast packets green: sending to UART yellow: receving data packets*/includes Sasha;#ifndef TOSBASE_BLINK_ON_DROP#define TOSBASE_BLINK_ON_DROP#endifmodule ACBaseM { provides interface StdControl; uses { interface StdControl as UARTControl; interface BareSendMsg as UARTSend; interface ReceiveMsg as UARTReceive; interface TokenReceiveMsg as UARTTokenReceive; interface StdControl as RadioControl; interface BareSendMsg as RadioSend; interface ReceiveMsg as RadioReceive; interface Leds; interface Timer as JTimer; interface Timer as MTimer; interface Timer as RTimer; interface Marzullolib; interface StdControl as MarzulloControl; }}implementation{ enum { UART_QUEUE_LEN = 12, RADIO_QUEUE_LEN = 12, }; TOS_Msg marzullo_result; TOS_Msg uartQueueBufs[UART_QUEUE_LEN]; TOS_MsgPtr uartQueue[UART_QUEUE_LEN]; uint8_t uartIn, uartOut; bool uartBusy, uartFull; TOS_Msg radioQueueBufs[RADIO_QUEUE_LEN]; TOS_MsgPtr radioQueue[RADIO_QUEUE_LEN]; uint8_t radioIn, radioOut; bool radioBusy, radioFull; uint8_t sequences; uint8_t state; uint8_t repeat; uint16_t record[MAX_MOTES]; // resizeable array of Mote Info struct Cluster_Msg *result; uint8_t fault_mote; uint8_t nrecord; task void UARTSendTask(); task void RadioSendTask(); void failBlink(); void dropBlink(); command result_t StdControl.init() { result_t ok1, ok2, ok3; uint8_t i; atomic { sequences = 0; state = TRAINING; repeat = REPEAT_MSG; } for (i = 0; i < UART_QUEUE_LEN; i++) { uartQueue[i] = &uartQueueBufs[i]; } uartIn = uartOut = 0; uartBusy = FALSE; uartFull = FALSE; for (i = 0; i < RADIO_QUEUE_LEN; i++) { radioQueue[i] = &radioQueueBufs[i]; } radioIn = radioOut = 0; radioBusy = FALSE; radioFull = FALSE; ok1 = call UARTControl.init(); ok2 = call RadioControl.init(); ok3 = call Leds.init(); dbg(DBG_BOOT, "TOSBase initialized\n"); return rcombine3(ok1, ok2, ok3); } command result_t StdControl.start() { call JTimer.start(TIMER_REPEAT,DISCOVERY); call UARTControl.start(); call RadioControl.start(); return SUCCESS; } command result_t StdControl.stop() { call UARTControl.stop(); call RadioControl.stop(); call JTimer.stop(); call MTimer.stop(); return SUCCESS; } /*Broadcast Join packet*/ task void BroadcastJoin() { struct Anycast *m; dbg(DBG_USR1, "Monitoring Node broadcasting Join packet.\n"); atomic { m= (Anycast *) (radioQueue[radioOut])->data; m->type = JOIN; // setting general data m->src = TOS_LOCAL_ADDRESS; m->parent = TOS_LOCAL_ADDRESS; m->seqNum = sequences++; m->hop = 0; if(state == TRAINING || state == VERIFY) { m->request = state; if(state == VERIFY) { m->min = result->min1; // setting general data m->max = result->max1; m->min1 = result->min2; m->max1 = result->max2; m->min2 = result->min3; m->max2 = result->max3; m->min3 = result->min4; m->max3 = result->max4; m->nintervals = result->src; } repeat--; if(repeat == 0) { // end of repeat if(state == TRAINING) state = MARZULLO; // state: TRAINING -> MARZULLO if(state == VERIFY) state = WAIT; // state: VERIFY -> WAIT call MTimer.start(TIMER_ONE_SHOT,TEN_MIN); // 10 min timeout } } else m->request = 0; radioQueue[radioOut]->group = TOS_AM_GROUP; radioQueue[radioOut]->addr = TOS_BCAST_ADDR; radioQueue[radioOut]->length = TOSH_DATA_LENGTH; if (!radioBusy) { call RadioSend.send(radioQueue[radioOut]); radioBusy = TRUE; } }//end atomic }//end Broadcast Join // what to do when a mote cluster packet arrive result_t doData(TOS_MsgPtr rmsg) { struct Cluster_Msg *datat; result_t r; datat = (struct Cluster_Msg *)rmsg->data; // stop timer call MTimer.stop(); // store mote data r = call Marzullolib.add_mote(datat); // start timer again call MTimer.start(TIMER_ONE_SHOT,TIMEOUT); return r; } // when a verify packet arrives result_t doOnce(TOS_MsgPtr rmsg) { struct Cluster_Msg *datat; int16_t mote_id; int16_t fault; int8_t i; datat = (struct Cluster_Msg *)rmsg->data; // stop timer call MTimer.stop(); // record mote data mote_id = datat->src; // mote_id fault = datat->train; // number of faults for(i=0; i<nrecord; i++) { // check if we have hear this mote before if(mote_id == record[i]) break; } if(i != nrecord) return FAIL; // drop if not new pkt if(nrecord == MAX_MOTES) return FAIL; // drop if the MAX_MOTES limit has arrived record[nrecord] = mote_id; // record the mote_id in the buffer nrecord++; // increase the count if(fault >= MAX_FAULTS) fault_mote++; // the mote is a fault mote if its fault > theshold datat->type = FAULT; // setting other values for debug datat->win3 = fault_mote; // setting other values for debug /* [KS] Make sure the ADC are not over writed */ /* The format of the packet is the following datat->win1 = c_min; // ADC minimum reading datat->win2 = c_max; // ADC maximum reading // below is the latest 10 reading from the ADC datat->win3 = nrecord;//number of faulty modes counted so far datat->win4 = c_buffer[1]; datat->min1 = c_buffer[2]; datat->min2 = c_buffer[3]; datat->min3 = c_buffer[4]; datat->min4 = c_buffer[5]; datat->max1 = c_buffer[6]; datat->max2 = c_buffer[7]; datat->max3 = c_buffer[8]; datat->max4 = c_buffer[9]; */ /* datat->win1 = fault_mote; datat->win2 = THRESHOLD; datat->win3 = nrecord; datat->win4 = result->src; */ call MTimer.start(TIMER_ONE_SHOT,TIMEOUT); return SUCCESS; } // receive a pkt from radio event TOS_MsgPtr RadioReceive.receive(TOS_MsgPtr Msg) { result_t print; uint8_t t= Msg->data[0];//type of the packet TOS_MsgPtr pBuf = Msg; print = FAIL; dbg(DBG_USR1, "TOSBase received radio packet.\n"); if(Msg->addr != TOS_LOCAL_ADDRESS) return Msg; if(Msg->length != TOSH_DATA_LENGTH) return Msg; if ((!Msg->crc) || (Msg->group != TOS_AM_GROUP)) return Msg; /*What Kind of message is it*/ switch (t){ case(DATA): if(state == MARZULLO) { print = doData(Msg); // on recving clusters from the mote } if(state == WAIT) { print = doOnce(Msg); // on recving fault pkt from the mote call MTimer.stop(); call MTimer.start(TIMER_ONE_SHOT,TIMEOUT); } if(print == SUCCESS) { call Leds.greenToggle(); atomic { if (!uartFull) { pBuf = uartQueue[uartIn]; uartQueue[uartIn] = Msg; if( ++uartIn >= UART_QUEUE_LEN ) uartIn = 0; if (uartIn == uartOut) { uartFull = TRUE; } if (!uartBusy) { if (post UARTSendTask()) { uartBusy = TRUE; } } } else { dropBlink(); } } } break; default: break; } return pBuf; } task void UARTSendTask() { bool noWork = FALSE; dbg (DBG_USR1, "TOSBase forwarding Radio packet to UART\n"); atomic { if (uartIn == uartOut && uartFull == FALSE) { uartBusy = FALSE; noWork = TRUE; } } if (noWork) { return; } if(uartQueue[uartOut]->length != TOSH_DATA_LENGTH) return; if (call UARTSend.send(uartQueue[uartOut]) == SUCCESS) { //call Leds.greenToggle(); } else { failBlink(); post UARTSendTask(); } } event result_t UARTSend.sendDone(TOS_MsgPtr msg, result_t success) { if (!success) { failBlink(); } else { atomic { if (msg == uartQueue[uartOut]) { if( ++uartOut >= UART_QUEUE_LEN ) uartOut = 0; if (uartFull) { uartFull = FALSE; } } } } post UARTSendTask(); return SUCCESS; } event TOS_MsgPtr UARTReceive.receive(TOS_MsgPtr Msg) { return Msg; } event TOS_MsgPtr UARTTokenReceive.receive(TOS_MsgPtr Msg, uint8_t Token) { TOS_MsgPtr pBuf = Msg; bool reflectToken = FALSE; dbg(DBG_USR1, "TOSBase received UART token packet.\n"); atomic { if (!radioFull) { reflectToken = TRUE; pBuf = radioQueue[radioIn]; radioQueue[radioIn] = Msg; if( ++radioIn >= RADIO_QUEUE_LEN ) radioIn = 0; if (radioIn == radioOut) radioFull = TRUE; if (!radioBusy) { if (post RadioSendTask()) { radioBusy = TRUE; } } } else { dropBlink(); } } if (reflectToken) { call UARTTokenReceive.ReflectToken(Token); } return pBuf; } task void RadioSendTask() { bool noWork = FALSE; dbg (DBG_USR1, "TOSBase forwarding UART packet to Radio\n"); atomic { if (radioIn == radioOut && radioFull == FALSE) { radioBusy = FALSE; noWork = TRUE; } } if (noWork) return; radioQueue[radioOut]->group = TOS_AM_GROUP; if (call RadioSend.send(radioQueue[radioOut]) == SUCCESS) { call Leds.redToggle(); } else { failBlink(); post RadioSendTask(); } } event result_t RadioSend.sendDone(TOS_MsgPtr msg, result_t success) { if (!success) { failBlink(); } else { atomic { if (msg == radioQueue[radioOut]) { if( ++radioOut >= RADIO_QUEUE_LEN ) radioOut = 0; if (radioFull) radioFull = FALSE; } } } post RadioSendTask(); return SUCCESS; }/* Time to rebrodcast Join Message */ event result_t JTimer.fired() { post BroadcastJoin(); return SUCCESS; } task void send_uart() { call UARTSend.send(&marzullo_result); } /* send final Marzullo result to UART */ event result_t RTimer.fired() { result = (struct Cluster_Msg *)marzullo_result.data; result->type = INTERVAL; // set the pkt as INTERVAL atomic { result = call Marzullolib.getfinal(result); // request result from Marzullolib post send_uart(); // send to UART port } // clear variables call Marzullolib.reset(); state = VERIFY; repeat = REPEAT_MSG; fault_mote = 0; nrecord = 0; return SUCCESS; } // Marzullo Timeout or Verify Timeout event result_t MTimer.fired() { uint8_t Nfinals; // Verify Timeout if(state == WAIT) { // call retraining of > 1/2 of mote faulty /*result->src(number of nodes replied) fault_mote (number of nodes replied with faulty message)*/ if(nrecord > 0 && result->src - fault_mote < fault_mote) { atomic { state = TRAINING; repeat = REPEAT_MSG; } return SUCCESS; } atomic { nrecord = 0; fault_mote = 0; state = VERIFY; repeat = REPEAT_MSG; } return SUCCESS; } // else if state == MARZULLO // its time to doMarzullo marzullo_result.group = TOS_AM_GROUP; marzullo_result.addr = TOS_UART_ADDR; marzullo_result.length = TOSH_DATA_LENGTH; // do marzullo Nfinals = call Marzullolib.doMarzullo(); // if no Marzullo was done... if(Nfinals < 1) { atomic { state = TRAINING; repeat = REPEAT_MSG; } } else { atomic { radioQueue[radioOut]->group = TOS_AM_GROUP; radioQueue[radioOut]->addr = TOS_BCAST_ADDR; radioQueue[radioOut]->length = TOSH_DATA_LENGTH; // send result uart call RTimer.start(TIMER_ONE_SHOT,1000); } } return SUCCESS; } void dropBlink() {#ifdef TOSBASE_BLINK_ON_DROP call Leds.yellowToggle();#endif } void failBlink() {#ifdef TOSBASE_BLINK_ON_FAIL call Leds.yellowToggle();#endif }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -