`
wangleide414
  • 浏览: 590433 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

无线龙zigbee2004精简版试验总结

 
阅读更多

花了很长时间看代码,中间有限状态机部分还没有看懂,目前只知道,有限状态机的功能是完成网络中设备各种状态之间的切换/*
V0.1 Initial Release   10/July/2006
*2006/08/16 WXL 2.0
*/

 

/*
This is a two node test, requires a Coordinator
and an RFD. The coordinator and node simply
ping-pong a packet back and forth, and print
out the RSSI byte. The RFD waits before
bouncing it back, while the coordinator responds
immediately.

Expects coordinator, and one RFD.
The topology to test should be:

Coordinator -> RFD1


Start the coordinator first, then
RFD1. If a RFD1 fails to join the network, try
again. The RFD1 will prompt the user to hit
a key to start the ping-pong.

You can connect multiple RFDs if desired.

You can also ping-pong through a router; see
the note in usrJoinVerifyCallback(). The topology
for a router would be:

coord -> router -> RFD1
-> RFD2
-> ..RFDn


This requires Virtual Boards to be running,
since a switch press is needed to start the pinging.//需要开关按下才能启动发送和接收数据的函数


*/

#include "wx_lrwpan.h"

#ifndef LRWPAN_COORDINATOR//如果未定义代表协调器这个宏变量
#define PING_DELAY   2 //wait before bouncing back可以延迟2秒
#else
#define PING_DELAY   0 //coordinator does not wait如果是协调器,不能延迟
#endif

#define RX_PING_TIMEOUT     5    //seconds超时时间是5秒
//this is assumed to be the long address of our coordinator, in little endian order
//used to test LONG ADDRESSING back to coordinator

UINT16 ping_cnt;//ping测试的计数器
UINT32 my_timer;//定时器
UINT32 last_tx_start;//上次完成传送的时间


LADDR_UNION dstADDR;//目标地址变量
/*
四种状态切换:开始接收、等待接收、发送、等待发送
*/
typedef enum _PP_STATE_ENUM {
PP_STATE_START_RX,
PP_STATE_WAIT_FOR_RX,
PP_STATE_SEND,
PP_STATE_WAIT_FOR_TX
}PP_STATE_ENUM;

PP_STATE_ENUM ppState;//定义状态变量
BYTE rxFlag;              //set from within usrRxPacketCallback 接收标志
BYTE payload[2];               //收发数据
UINT16 numTimeouts;           //延时
BOOL first_packet;            //第一个数据包

void PingPong(void);

void PingPong (void ) {
apsFSM();//应用层无线数据收发处理 , 有限状态机,用于网络各种状态之间的切换                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
switch (ppState) {

    case PP_STATE_START_RX://如果正在接收
     if (!first_packet) {//如果不是第一个数据包
      my_timer= halGetMACTimer();//构造一个定时器
      ppState = PP_STATE_WAIT_FOR_RX;//把等待接受的状态赋给记录状态的变量ppState
     }else if (rxFlag) {//如果是第一个数据包
      //on first packet, do not start timer, just wait for a packet.
      ppState = PP_STATE_WAIT_FOR_RX;//等待接受状态赋给ppState
      first_packet = FALSE;//表示这之后的包已经不是第一个包了
     }
     break;
    case PP_STATE_WAIT_FOR_RX://如果状态是等待接收
     //rxFlag is set from within usrRxPacketCallback rxFlag在这个函数里被设定
     if (rxFlag || halMACTimerNowDelta(my_timer) > MSECS_TO_MACTICKS( RX_PING_TIMEOUT *1000 )) {//如果正在接收或者还未超时
      if (!rxFlag) numTimeouts++;     //got tired of waiting for a response, send again如果还未接收超时时间增加1
      rxFlag = 0; //clear flag设定成不再接收
      if (EVB_LED1_STATE()) EVB_LED1_OFF(); else EVB_LED1_ON();//灯状态取反
      //start timer
      my_timer= halGetMACTimer();//重新构造一个定时器
      ppState = PP_STATE_SEND;//设定成发送状态
     }
     break;
    case PP_STATE_SEND://如果是正在发送状态
     if ((halMACTimerNowDelta(my_timer))> MSECS_TO_MACTICKS(PING_DELAY*1000)){//如果还未超时
      MemDump();//取出存储器中的数值,通过串口进行显示

      //increment ping counter
      ping_cnt++; //this was value received by this node//ping计数器加1
      //received packet, ping it back
      //format the packet形成包
      payload[0] = (BYTE) ping_cnt;
      payload[1] = (BYTE) (ping_cnt>>8);
      ppState = PP_STATE_WAIT_FOR_TX;//设定成等待发送状态
      last_tx_start = halGetMACTimer();//重新构造定时器

      aplSendMSG (APS_DSTMODE_SHORT,//发送一条消息
       &dstADDR,//目标地址
       2, //dst EP目标端点号
       0, //cluster is ignored for direct message
       1, //src EP//源端点号
       &payload[0],//数据包
       2, //msg length//消息长度
       apsGenTSN(),//产生事物队列号
       FALSE); //No APS ack requested//不需要确认
      ppState = PP_STATE_WAIT_FOR_TX;//设定为等待传送状态
     }
     break;
    case PP_STATE_WAIT_FOR_TX://如果是在等待传送状态
     if (apsBusy()) break; //status not ready yet if busy.//等待加入网络
     if (aplGetStatus() == LRWPAN_STATUS_SUCCESS) {//如果加入网络成功
      ppState = PP_STATE_START_RX;//设定为接收状态
      //compute the latency of this TX send operation计算发送操作的延时
      //aplGetLastTxTime gets the time that the LAST tx operation finished.//函数获取上一次传送操作完成的时间
      //this will be the latency of the TX stack operation only if no mac retries were required
      last_tx_start = aplMacTicksToUs(aplGetLastTxTime() - last_tx_start);//转MAC滴答为微秒
      conPrintROMString("TX Stack latency(us): ");//串口在仿真终端上打印一段字符串
      conPrintUINT32(last_tx_start);//串口打印出上次的延迟
      conPCRLF();//串口输出一个换行符
     }else {
      conPrintROMString("Ping Send failed! Restarting timer to try again\n");
      my_timer= halGetMACTimer();//重新构造一个定时器
      ppState = PP_STATE_SEND;//状态设为发送
     }
     break;
}
}

 

void main (void){
//this initialization set our SADDR to 0xFFFF,
//PANID to the default PANID
//HalInit, evbInit will have to be called by the user
numTimeouts = 0;
my_timer = 0;
first_packet = TRUE;//开始发送第一个数据包
halInit();//硬件初始化
evbInit();   //CC2430芯片初始化

aplInit(); //init the stack 协议栈初始化
conPrintConfig();//串口初始化配置
ENABLE_GLOBAL_INTERRUPT(); //enable interrupts开启所有中断使能端

EVB_LED1_OFF();        //LED灯初始化
EVB_LED2_OFF();//初始化两个等都关掉

ping_cnt = 0;//ping计数器都初始化为0
rxFlag = 0;//初始化收标志
//debug_level = 10;

#ifdef LRWPAN_COORDINATOR       //是协调者
aplFormNetwork();       //初始化一个新网络
while(apsBusy()) {apsFSM();} //wait for finish等待加入网络
conPrintROMString("Network formed, waiting for RX\n");
EVB_LED2_ON();//LED灯亮
ppState = PP_STATE_START_RX;//状态设定为收
#else                            //是路由或终端
do {
   aplJoinNetwork();//加入已存在的一个网络
   while(apsBusy()) {apsFSM();} //wait for finish 等待完成加入网络
   if (aplGetStatus() == LRWPAN_STATUS_SUCCESS) {   //成功加入网络
    EVB_LED2_ON();//LED灯亮
                        //数据输出显示
    conPrintROMString("Network Join succeeded!\n");
    conPrintROMString("My ShortAddress is: ");
    conPrintUINT16(aplGetMyShortAddress());//串口输出显示网络地址
    conPCRLF();//串口输出换行
    conPrintROMString("Parent LADDR: ")
    conPrintLADDR(aplGetParentLongAddress());//串口输出物理地址
    conPrintROMString(", Parent SADDR: ");
    conPrintUINT16(aplGetParentShortAddress());//串口输出网络地址
    conPCRLF();//串口输出一个换行符
    break;
   }else {//加入网络失败
    conPrintROMString("Network Join FAILED! Waiting, then trying again\n");
    my_timer= halGetMACTimer();
    //wait for 2 seconds等待2秒钟
    while ((halMACTimerNowDelta(my_timer))< MSECS_TO_MACTICKS(2*1000));
   }
} while(1);

#endif

#ifdef LRWPAN_RFD   //RFD(终端)节点
//now send packets
dstADDR.saddr = 0; //RFD sends to the coordinator   RFD发送数据的目的地址为网络协调器
ppState = PP_STATE_SEND;//设定为发送状态
#endif

#if (defined(LRWPAN_RFD) || defined(LRWPAN_COORDINATOR))   //网络协调器
//WARNING - this is only for latency testing, max MAC retries is normally
//set to aMaxFrameRetries (value=3) as defined in mac.h. Setting this to 0 means
//that there will be no automatic retransmissions of frames if we do not get a MAC ACK back.
//only do this in your normal code if you want to disable automatic retries
aplSetMacMaxFrameRetries(0);//设定重转次数为0,表示不重传
while (1) {
   PingPong();//调用自定义函数,不停的发送接收,进行状态转换
}
#endif


#ifdef LRWPAN_ROUTER //路由节点
//router does nothing, just routes
DEBUG_PRINTNEIGHBORS(DBG_INFO);//打印出邻居信息
conPrintROMString("Router, doing its thing.!\n");
while(1) {apsFSM();}   //应用层处理函数
#endif


}

//########## Callbacks ##########

//callback for anytime the Zero Endpoint RX handles a command
//user can use the APS functions to access the arguments
//and take additional action is desired.
//the callback occurs after the ZEP has already taken
//its action.//回调函数在终端设备的所有操作完成后执行
LRWPAN_STATUS_ENUM usrZepRxCallback(void){//zigbee终端设备回调函数

#ifdef LRWPAN_COORDINATOR//如果是协调器
if (aplGetRxCluster() == ZEP_END_DEVICE_ANNOUNCE) {//获取消息簇号等于ZEP_END_DEVICE_ANNOUNCE
   //a new end device has announced itself, print out the
   //the neightbor table and address map
   dbgPrintNeighborTable();//打印出邻居表
}
#endif
return LRWPAN_STATUS_SUCCESS;
}

//callback from APS when packet is received
//user must do something with data as it is freed
//within the stack upon return.在接收到数据包后执行的回调函数,用户必须执行操作在栈空间收回之前对数据进行处理

LRWPAN_STATUS_ENUM usrRxPacketCallback(void) {//回调函数在屏幕上输出一些数据信息

BYTE len, *ptr;

//just print out this data

conPrintROMString("User Data Packet Received: \n");
conPrintROMString("SrcSADDR: ");
conPrintUINT16(aplGetRxSrcSADDR());
conPrintROMString(", DstEp: ");
conPrintUINT8(aplGetRxDstEp());
conPrintROMString(", Cluster: ");
conPrintUINT8(aplGetRxCluster());
conPrintROMString(", MsgLen: ");
len = aplGetRxMsgLen();
conPrintUINT8(len);
conPrintROMString(",RSSI: ");
conPrintUINT8(aplGetRxRSSI());
conPCRLF();
conPrintROMString("PingCnt: ");//打印出一些字符
ptr = aplGetRxMsgData();
ping_cnt = *ptr;
ptr++;
ping_cnt += ((UINT16)*ptr)<<8;
conPrintUINT16(ping_cnt);
conPrintROMString(", RxTimeouts: ");
conPrintUINT16(numTimeouts);
rxFlag = 1;//signal that we got a packet
//use this source address as the next destination address
dstADDR.saddr = aplGetRxSrcSADDR();
conPCRLF();
return LRWPAN_STATUS_SUCCESS;
}

#ifdef LRWPAN_FFD
//Callback to user level to see if OK for this node
//to join - implement Access Control Lists here based
//upon IEEE address if desired这个回调函数是在节点加入网络前执行的,用户可以在该函数里设定访问控制列表,对与网络地址进行校验
BOOL usrJoinVerifyCallback(LADDR *ptr, BYTE capinfo){\

#if 0      //set this to '1' if you want to test through a router
//only accept routers.
//only let routers join us if we are coord
#ifdef LRWPAN_COORDINATOR//如果是协调器
if (LRWPAN_GET_CAPINFO_DEVTYPE(capinfo)) {//如果是路由器
//this is a router, let it join
conPrintROMString("Accepting router\n");//串口打印表示路由器加入网络
return TRUE;
}else {
conPrintROMString("Rejecting non-router\n");//串口打印表示拒绝非路由设备加入网络
return FALSE;
}
#else
return TRUE;
#endif

#else

return TRUE;

#endif

}

BOOL usrJoinNotifyCallback(LADDR *ptr){//这个函数是加入网路后执行的回调函数,可以对该节点的信息进行通告

//allow anybody to join

conPrintROMString("Node joined: ");
conPrintLADDR(ptr);
conPCRLF();
DEBUG_PRINTNEIGHBORS(DBG_INFO);
        EVB_LED2_OFF();
        halWaitMs(200);
        EVB_LED2_ON();
        halWaitMs(200);
        EVB_LED2_OFF();
        halWaitMs(200);
        EVB_LED2_ON();//红灯闪烁两次,表示加入网络成功
return TRUE;
}
#endif

//called when the slow timer interrupt occurs
#ifdef LRWPAN_ENABLE_SLOW_TIMER
void usrSlowTimerInt(void ) {}//中断发生,中断处理前执行这个函数
#endif


//general interrupt callback , when this is called depends on the HAL layer.
void usrIntCallback(void){}//中断处理后执行这个函数
各种状态之间互相切换,其他应用层函数,我给注释了一下,难免会出现错误

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics