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

📄 csmamacp.nc

📁 tinyos2.0版本驱动
💻 NC
📖 第 1 页 / 共 2 页
字号:
/* -*- mode:c++; indent-tabs-mode: nil -*- * Copyright (c) 2004-2006, Technische Universitaet Berlin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright notice, *   this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright *   notice, this list of conditions and the following disclaimer in the *   documentation and/or other materials provided with the distribution. * - Neither the name of the Technische Universitaet Berlin nor the names *   of its contributors may be used to endorse or promote products derived *   from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include "radiopacketfunctions.h"#include "flagfunctions.h"#include "PacketAck.h" /**  * An implementation of a Csma Mac.  *   * @author: Andreas Koepke (koepke@tkn.tu-berlin.de)  * @author: Kevin Klues (klues@tkn.tu-berlin.de)  * @author Philipp Huppertz (huppertz@tkn.tu-berlin.de)*/// #define MACM_DEBUG                 // debug...module CsmaMacP {    provides {        interface Init;        interface SplitControl;        interface MacSend;        interface MacReceive;        interface Packet;    }    uses {        interface StdControl as CcaStdControl;        interface PhySend as PacketSend;        interface PhyReceive as PacketReceive;        interface RadioTimeStamping;                interface Tda5250Control as RadioModes;          interface ResourceRequested as RadioResourceRequested;        interface UartPhyControl;        interface Packet as SubPacket;                interface ChannelMonitor;        interface ChannelMonitorControl;          interface ChannelMonitorData;        interface Resource as RssiAdcResource;        interface Random;        interface Timer<TMilli> as ReRxTimer;        interface Duplicate;        interface TimeDiff16;                interface Alarm<T32khz, uint16_t> as Timer;        async command am_addr_t amAddress();        interface LocalTime<T32khz> as LocalTime32kHz;        #ifdef MACM_DEBUG        interface GeneralIO as Led0;        interface GeneralIO as Led1;        interface GeneralIO as Led2;        interface GeneralIO as Led3;#endif    }}implementation{    enum {        BYTE_TIME=ENCODED_32KHZ_BYTE_TIME,           // phy encoded        PREAMBLE_BYTE_TIME=TDA5250_32KHZ_BYTE_TIME,  // no coding        PHY_HEADER_TIME=6*PREAMBLE_BYTE_TIME,        // 6 Phy Preamble        TIME_CORRECTION=TDA5250_32KHZ_BYTE_TIME+2,   // difference between txSFD and rxSFD                SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(tda5250_header_t)*BYTE_TIME,        SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc         MAXTIMERVALUE=0xFFFF,        // helps to compute backoff        DATA_DETECT_TIME=17,        RX_SETUP_TIME=102,    // time to set up receiver        TX_SETUP_TIME=58,     // time to set up transmitter        ADDED_DELAY = 30,        RX_ACK_TIMEOUT=RX_SETUP_TIME + PHY_HEADER_TIME + 2*ADDED_DELAY,        TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 33,        MAX_SHORT_RETRY=7,        MAX_LONG_RETRY=4,        BACKOFF_MASK=0xFFF,  // minimum time around one packet time        MIN_PREAMBLE_BYTES=2,        TOKEN_ACK_FLAG = 64,        TOKEN_ACK_MASK = 0x3f,        INVALID_SNR = 0xffff    };    /**************** Module Global Variables  *****************/        /* state vars & defs */    typedef enum {        CCA,             // clear channel assessment        CCA_ACK,        SW_RX,           // switch to receive        RX,              // rx mode done, listening & waiting for packet        SW_RX_ACK,        RX_ACK,        RX_ACK_P,        RX_P,        SW_TX,        TX,        SW_TX_ACK,        TX_ACK,        INIT    } macState_t;    /* flags */    typedef enum {        RSSI_STABLE = 1,        RESUME_BACKOFF = 2,        CANCEL_SEND = 4,        CCA_PENDING = 8    } flags_t;    /* Packet vars */    message_t* txBufPtr;    message_t ackMsg;    uint8_t txLen;    uint8_t shortRetryCounter;    uint8_t longRetryCounter;    unsigned checkCounter;        macState_t macState;    uint8_t flags;    uint8_t seqNo;        uint16_t restLaufzeit;    uint16_t rssiValue = 0;    uint32_t rxTime = 0;        /****** debug vars & defs & functions  ***********************/#ifdef MACM_DEBUG#define HISTORY_ENTRIES 100    typedef struct {        int index;        macState_t state;        int        place;    } history_t;        history_t history[HISTORY_ENTRIES];    unsigned histIndex;    void storeOldState(int p) {        atomic {            history[histIndex].index = histIndex;            history[histIndex].state = macState;            history[histIndex].place = p;            histIndex++;            if(histIndex >= HISTORY_ENTRIES) histIndex = 0;        }    }#else    void storeOldState(int p) {};#endif    void signalFailure(uint8_t place) {#ifdef MACM_DEBUG        unsigned long i;        atomic {            for(;;) {                call Led0.set();                call Led1.clr();                call Led2.clr();                call Led3.clr();                                for(i = 0; i < 1000000; i++) {                    ;                }                (place & 1) ? call Led0.set() : call Led0.clr();                (place & 2) ? call Led1.set() : call Led1.clr();                (place & 4) ? call Led2.set() : call Led2.clr();                (place & 8) ? call Led3.set() : call Led3.clr();                for(i = 0; i < 1000000; i++) {                    ;                }                (macState & 1) ? call Led0.set() : call Led0.clr();                (macState & 2) ? call Led1.set() : call Led1.clr();                (macState & 4) ? call Led2.set() : call Led2.clr();                (macState & 8) ? call Led3.set() : call Led3.clr();                for(i = 0; i < 1000000; i++) {                    ;                }            }        }#endif    }    void signalMacState() {#ifdef MACM_DEBUG/*         (macState & 1) ? call Led0.set() : call Led0.clr();         (macState & 2) ? call Led1.set() : call Led1.clr();         (macState & 4) ? call Led2.set() : call Led2.clr();         (macState & 8) ? call Led3.set() : call Led3.clr();*/#endif    }        /****** Secure switching of radio modes ***/        task void SetRxModeTask();    task void SetTxModeTask();    task void ReleaseAdcTask() {        macState_t ms;        atomic ms = macState;        if(isFlagSet(&flags, CCA_PENDING)) {          post ReleaseAdcTask();         }        else {        	if((ms > CCA)  && (ms != INIT) && call RssiAdcResource.isOwner()) {          	  call RssiAdcResource.release();        	}	        }    }        void setRxMode();    void setTxMode();    void requestAdc() {        if(macState != INIT) {          call RssiAdcResource.immediateRequest();        }        else {            call RssiAdcResource.request();        }    }        void setRxMode() {        rssiValue = INVALID_SNR;        if(call RadioModes.RxMode() == FAIL) {            post SetRxModeTask();        }        if(macState == INIT) {          requestAdc();        } else {          post ReleaseAdcTask();        }    }        task void SetRxModeTask() {        atomic {            if((macState == SW_RX) ||               (macState == SW_RX_ACK) ||               (macState == INIT)) setRxMode();        }    }    void setTxMode() {        clearFlag(&flags, RSSI_STABLE);        if(call RadioModes.TxMode() == FAIL) {            post SetTxModeTask();        }        post ReleaseAdcTask();    }        task void SetTxModeTask() {        atomic {            if((macState == SW_TX) ||               (macState == SW_TX_ACK)) setTxMode();        }    }    /**************** Helper functions ********/    task void postponeReRx() {        call ReRxTimer.startOneShot(5000);    }        uint16_t backoff(uint8_t counter) {        uint16_t mask = BACKOFF_MASK >> (MAX_LONG_RETRY - counter);        return (call Random.rand16() & mask);    }    void interruptBackoffTimer() {        if(call Timer.isRunning()) {            restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow());            call Timer.stop();            if(restLaufzeit > BACKOFF_MASK) {                restLaufzeit = call Random.rand16() & 0xFF;            }            setFlag(&flags, RESUME_BACKOFF);        }    }    void storeStrength(message_t *m) {        if(rssiValue != INVALID_SNR) {            (getMetadata(m))->strength = rssiValue;        }        else {            if(call RssiAdcResource.isOwner()) {                (getMetadata(m))->strength = call ChannelMonitorData.readSnr();            }            else {                (getMetadata(m))->strength = 1;            }        }    }    void signalSendDone(error_t error) {        message_t *m;        error_t e = error;        atomic {            m = txBufPtr;            txBufPtr = 0;            txLen  = 0;            longRetryCounter = 0;            shortRetryCounter = 0;            if(isFlagSet(&flags, CANCEL_SEND)) {                e = ECANCEL;            }            storeStrength(m);            clearFlag(&flags, CANCEL_SEND);        }        signal MacSend.sendDone(m, e);    }    void updateLongRetryCounters() {        longRetryCounter++;        shortRetryCounter = 1;        if(longRetryCounter > MAX_LONG_RETRY) {            storeOldState(13);            getMetadata(txBufPtr)->ack = WAS_NOT_ACKED;            signalSendDone(FAIL);        }    }    void updateRetryCounters() {        shortRetryCounter++;        if(shortRetryCounter > MAX_SHORT_RETRY) {            longRetryCounter++;            shortRetryCounter = 1;            if(longRetryCounter > MAX_LONG_RETRY) {                getMetadata(txBufPtr)->ack = WAS_NOT_ACKED;                signalSendDone(FAIL);            }        }    }        void computeBackoff() {        if(!isFlagSet(&flags, RESUME_BACKOFF)) {            setFlag(&flags, RESUME_BACKOFF);            restLaufzeit = backoff(longRetryCounter);            updateRetryCounters();            storeOldState(92);        }    }    bool isNewMsg(message_t* msg) {        return call Duplicate.isNew(getHeader(msg)->src, getHeader(msg)->dest,                                    (getHeader(msg)->token) & TOKEN_ACK_MASK);    }        void rememberMsg(message_t* msg) {        call Duplicate.remember(getHeader(msg)->src, getHeader(msg)->dest,                                (getHeader(msg)->token) & TOKEN_ACK_MASK);    }        void checkSend() {        if((txBufPtr != NULL) && (macState == RX) && (!call Timer.isRunning())) {            macState = CCA;            signalMacState();            checkCounter = 0;            requestAdc();            call Timer.start(DATA_DETECT_TIME);            storeOldState(170);        }        else {            storeOldState(171);            post ReleaseAdcTask();        }    }        bool needsAckRx(message_t* msg) {        bool rVal = FALSE;        uint8_t token;        if(getHeader(msg)->dest < AM_BROADCAST_ADDR) {            token = getHeader(msg)->token;            if(isFlagSet(&token, ACK_REQUESTED)) rVal = TRUE;        }        return rVal;    }    bool needsAckTx(message_t* msg) {        bool rVal = FALSE;        if(getHeader(msg)->dest < AM_BROADCAST_ADDR) {            if((getMetadata(msg)->ack == ACK_REQUESTED) || (getMetadata(msg)->ack != NO_ACK_REQUESTED)) {                rVal = TRUE;            }        }        return rVal;    }    void prepareAck(message_t* msg) {        uint8_t rToken = getHeader(msg)->token & TOKEN_ACK_MASK;        setFlag(&rToken, TOKEN_ACK_FLAG);        getHeader(&ackMsg)->token = rToken;        getHeader(&ackMsg)->src = call amAddress();        getHeader(&ackMsg)->dest = getHeader(msg)->src;        getHeader(&ackMsg)->type = getHeader(msg)->type;    }    bool msgIsForMe(message_t* msg) {        if(getHeader(msg)->dest == AM_BROADCAST_ADDR) return TRUE;        if(getHeader(msg)->dest == call amAddress()) return TRUE;        return FALSE;    }    bool ackIsForMe(message_t* msg) {        uint8_t localToken = seqNo;        setFlag(&localToken, TOKEN_ACK_FLAG);        if((getHeader(msg)->dest == call amAddress()) && (localToken == getHeader(msg)->token)) return TRUE;        return FALSE;    }        bool isControl(message_t* m) {        uint8_t token = getHeader(m)->token;        return isFlagSet(&token, TOKEN_ACK_FLAG);    }        /**************** Init ************************/        command error_t Init.init(){        atomic {            txBufPtr = NULL;            macState = INIT;            signalMacState();            shortRetryCounter = 0;            longRetryCounter = 0;            flags = 0;#ifdef MACM_DEBUG            histIndex = 0;#endif        }        return SUCCESS;    }    /****************  SplitControl  *****************/    task void StartDoneTask() {        atomic {            macState = RX;            signalMacState();            call UartPhyControl.setNumPreambles(MIN_PREAMBLE_BYTES);        }        post ReleaseAdcTask();        signal SplitControl.startDone(SUCCESS);    }    command error_t SplitControl.start() {        call CcaStdControl.start();        atomic {            macState = INIT;            signalMacState();            setRxMode();            storeOldState(1);        }        return SUCCESS;    }    task void StopDone() {

⌨️ 快捷键说明

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