Upma Xmac 测试 04 XmacSenderP.nc
/opt/tinyos-2.1.2/wustl/upma/lib/macs/xmac/XmacSenderP.nc源码如下:
async command error_t Send.send(message_t * msg, uint8_t len) { //printf("XmacSenderP Send.send\r\n"); if(call SendState.getState() == S_STOPPED) //要发送数据,radio必须是开的 return EOFF; // Make sure that the radio isn't off // Try to move to the preamble state if(call SendState.requestState(S_PREAMBLE) == SUCCESS) //请求发送前导 { //printf("SUCCESS\r\n"); call FixedSleepLplListener.cancelTimeout(); //取消超时操作,其实是关闭一个定时器,该定时器 //触发后 如果当前radio开着,并处于空闲状态,会关闭radio atomic { msg_ = msg; //保存要发发送的信息 len_ = len; } post doStart(); //开始发送前导分组 return SUCCESS; // Save the parameters and start the radio } return FAIL; }
FixedSleepLplListener.cancelTimeout()由/opt/tinyos-2.1.2/wustl/upma1/lib/macs/bmac/FixedSleepLplListenerP.nc实现,源码如下:
async command void FixedSleepLplListener.cancelTimeout() { call TimeoutAlarm.stop(); } async event void TimeoutAlarm.fired() { #ifndef FORCE_RADIO_ON if(call SendState.isIdle()) call RadioPowerControl.stop(); #endif }
post doStart()的源码如下:
task void doStart() { call SenderControl.start(); //打开radio }
SenderControl.start();由/opt/tinyos-2.1.2/wustl/upma/system/PreambleSenderP.nc实现,源码如下:
command error_t SplitControl.start() { if(call RadioState.getState() == S_ON) { signal SplitControl.startDone(SUCCESS); //printf("PreambleSenderP SplitControl.start\r\n"); return SUCCESS; } // If the radio's already on, do nothing //printf("PreambleSenderP SplitControl.start!!!\r\n"); if(call PreambleState.requestState(S_STARTING) != SUCCESS) return FAIL; // Try to move to the starting state startRadio(); //开启radio return SUCCESS; // Actually start the radio }
经测试,除了第一次发送前导之外,后面每次发送前导之前 radio都是关闭的,
startRadio(); 的源码如下:
void startRadio() { if(call RadioPowerControl.start() != SUCCESS) post startRadioLater(); }
RadioPowerControl.start()由/opt/tinyos-2.1.2/wustl/upma/chips/cc2420/CC2420CsmaP.nc实现,源码如下:
async command error_t RadioPowerControl.start() { //printf("RadioPowerControl.start1()\r\n"); if(call SplitControlState.requestState(S_STARTING) == SUCCESS) { //设置radio状态为正在开启 // printf("RadioPowerControl.start2()\r\n"); #ifdef CC2420_ACCOUNTING //并未定义 //printf("CC2420_ACCOUNTING=%d\r\n",CC2420_ACCOUNTING); call Alarm.start(1024UL); vRegStartedAt = call Counter.get(); #endif //printf("CC2420_ACCOUNTING=%d\r\n",CC2420_ACCOUNTING); call CC2420Power.startVReg(); //从字面意思来看,是稳压操作 //printf("SUCCESS\r\n"); return SUCCESS; //不出情况,一般度返回SUCCESS,代表开启成功 } else if(call SplitControlState.isState(S_STARTED)) { return EALREADY; } else if(call SplitControlState.isState(S_STARTING)) { return SUCCESS; } return EBUSY; }
总结:
XmacSenderP.nc的 async command error_t Send.send(message_t * msg, uint8_t len)完成的工作主要是打开radio,外后面的发送前导分组做准备。