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 + -
显示快捷键?