csmamacp.nc

来自「tinyos-2.0源代码!转载而已!要的尽管拿!」· NC 代码 · 共 661 行 · 第 1/2 页

NC
661
字号
/* -*- 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" /**  * 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)*/module CsmaMacP {    provides {        interface Init;        interface SplitControl;        interface MacSend;        interface MacReceive;    }    uses {        interface StdControl as CcaStdControl;        interface PhySend as PacketSend;        interface PhyReceive as PacketReceive;                interface Tda5250Control as RadioModes;          interface UartPhyControl;              interface ChannelMonitor;        interface ChannelMonitorControl;          interface ChannelMonitorData;        interface Random;                interface Alarm<T32khz, uint16_t> as Timer;        interface GeneralIO as Led0;        interface GeneralIO as Led1;        interface GeneralIO as Led2;        interface GeneralIO as Led3;    }}implementation{#define CSMA_ACK 100#define BYTE_TIME 17// #define MACM_DEBUG                    // debug...#define MAX_LONG_RETRY 3              // Missing acks, or short retry limit hits -> increase long retry #define MAX_SHORT_RETRY 5             // busy channel -> increase short retry#define DIFS 165                      // 5ms to get an ACK started#define ACK_TIMEOUT 20*BYTE_TIME#define MIN_BACKOFF_MASK 0x7F         // roughly 4ms for Rx/Tx turnaround defines this value#define CHECK_RX_LIVENESS_INTERVALL 165    /**************** Module Global Variables  *****************/        /* state vars & defs */    typedef enum {        SW_CCA,          // switch to CCA        CCA,             // clear channel assessment             SW_RX,           // switch to receive        RX,              // rx mode done, listening & waiting for packet        SW_RX_ACK,        RX_ACK,        RX_P,        SW_TX,        TX,        SW_TX_ACK,        TX_ACK,        INIT    } macState_t;    /* flags */    typedef enum {        RSSI_STABLE = 1,        BUSY_DETECTED_VIA_RSSI = 2,        CHECK_RX_LIVENESS = 4,        DIFS_TIMER_FIRED = 8    } flags_t;    /* Packet vars */    message_t* txBufPtr;    message_t ackMsg;    uint8_t txLen;    int16_t rssiValue;    uint8_t shortRetryCounter;    uint8_t longRetryCounter;    macState_t macState;    uint8_t flags;    uint16_t slotMask;        /****** debug vars & defs & functions  ***********************/#ifdef MACM_DEBUG#define HISTORY_ENTRIES 40    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();        void setRxMode();    void setTxMode();    void setRxMode() {        if(call RadioModes.RxMode() == FAIL) {            post SetRxModeTask();        }    }        task void SetRxModeTask() {        atomic {            if((macState == SW_RX) ||               (macState == SW_RX_ACK) ||               (macState == SW_CCA) ||               (macState == INIT)) setRxMode();        }    }    void setTxMode() {        clearFlag(&flags, RSSI_STABLE);        clearFlag(&flags, BUSY_DETECTED_VIA_RSSI);        if(call RadioModes.TxMode() == FAIL) {            post SetTxModeTask();        }    }        task void SetTxModeTask() {        atomic {            if((macState == SW_TX) ||               (macState == SW_TX_ACK)) setTxMode();        }    }    /**************** Helper functions ********/    uint16_t backoff() {        uint16_t mask = slotMask;        unsigned i;        for(i = 0; i < longRetryCounter; i++) {            mask = (mask << 1) + 1;        }        return (call Random.rand16() & mask);    }        void signalSendDone(error_t error) {        message_t *m;        atomic {            m = txBufPtr;            txBufPtr = 0;            txLen  = 0;            longRetryCounter = 0;            shortRetryCounter = 0;        }        signal MacSend.sendDone(m, error);    }    void updateRetryCounters() {        shortRetryCounter++;        if(shortRetryCounter > MAX_SHORT_RETRY) {            longRetryCounter++;            shortRetryCounter = 1;            if(longRetryCounter > MAX_LONG_RETRY) {                signalSendDone(FAIL);            }        }    }        void checkSend() {        if((txBufPtr != NULL) && (macState == RX) && (!call Timer.isRunning())) {            clearFlag(&flags, CHECK_RX_LIVENESS);            clearFlag(&flags, DIFS_TIMER_FIRED);            /*           if(!call UartPhyControl.isBusy()) { */                if(isFlagSet(&flags, RSSI_STABLE)) {                    macState = CCA;                    signalMacState();                    call Timer.start(DIFS);                    call ChannelMonitor.start();                    storeOldState(130);                } else {                    macState = SW_CCA;                    signalMacState();                    storeOldState(131);                } /*           }            else {                storeOldState(132);                updateRetryCounters();                setFlag(&flags, CHECK_RX_LIVENESS);                call Timer.start(backoff());            }                */      }    }        bool needsAck(message_t* msg) {        return FALSE;  // (getHeader(msg)->addr != AM_BROADCAST_ADDR);    }        /**************** Init ************************/        command error_t Init.init(){        atomic {            txBufPtr = NULL;            macState = INIT;            signalMacState();            shortRetryCounter = 0;            longRetryCounter = 0;            flags = 0;            slotMask = MIN_BACKOFF_MASK;#ifdef MACM_DEBUG            histIndex = 0;#endif        }        return SUCCESS;    }    /****************  SplitControl  *****************/    task void StartDoneTask() {        signal SplitControl.startDone(SUCCESS);    }    command error_t SplitControl.start() {        call CcaStdControl.start();        atomic {            macState = INIT;            signalMacState();            setRxMode();            storeOldState(1);        }        return SUCCESS;    }    task void StopDone() {        atomic {

⌨️ 快捷键说明

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