`
wangleide414
  • 浏览: 606752 次
  • 性别: 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){}//中断处理后执行这个函数
各种状态之间互相切换,其他应用层函数,我给注释了一下,难免会出现错误

分享到:
评论

相关推荐

    基于ARM的无线报警技术在电气试验中的应用.pdf

    【基于ARM的无线报警技术在电气试验中的应用】 在电气试验中,安全是至关重要的,因为电气设备的绝缘水平和电气性能的检测直接关系到电力系统的稳定运行和人员安全。近年来,由于工作人员的疏忽导致的事故频发,...

    CC 2530 zigbee 流水灯实验

    CC2530是一款广泛应用的微控制器,特别适用于无线传感器网络和Zigbee通信。Zigbee是一种低功耗、低成本的无线通信技术,常用于物联网(IoT)设备。流水灯实验是嵌入式系统开发中的一个基础练习,它有助于理解控制LED灯...

    Zigbee +PC上位机 无线控制二维云台开发C# Winform上位机的编程

    今日尝试开发一款简单好学的PC上位机无线控制二维云台的小试验品: 主要开发环境与工具介绍: 单片机 STM32F103C8T6 使用标准库函数编程 Visual Studio 2022软件C# Winform 开发 上位机控制软件 DL_20 无线...

    ZStack试验介绍

    ### ZStack试验介绍 #### ZigBee 2007/PRO无线传感器网络技术概览 ZigBee 2007/PRO无线传感器网络是基于最新的IEEE 802.15.4技术标准和ZigBee 2007/PRO网络协议而设计的一种低功耗无线数据传感器网络。它主要应用...

    cc2530开发试验

    《CC2530开发试验:探索无线微控制器的魅力》 CC2530是一款由Texas Instruments(TI)公司推出的高效能、低功耗的无线微控制器,特别适用于Zigbee、6LoWPAN等无线网络协议。这款芯片集成了ARM7TDMI-S内核,拥有强大...

    单片机的一些试验项目

    Zigbee模块基于IEEE802.15.4标准和ZIGBEE2007/PRO协议,采用CC2530芯片,该芯片具备低功耗特性,适用于多种无线通信应用。其特点包括: 1. 宽电源电压范围,支持2V到3.6V。 2. 内置8051微控制器,提供高性能和代码...

    TI SmartRF Flash Programmer

    TI SmartRF Flash Programmer是一款由德州仪器(Texas Instruments,简称TI)开发的专业软件工具,主要用于对Zigbee无线通信模块...通过不断的试验和优化,开发者可以构建出高效稳定、符合预期的Zigbee无线网络系统。

    ZStack-CC2530-2.3.0-1.4.0.rar

    SensorDemo是一个非常实用的例子,它演示了如何利用CC2530芯片构建无线传感器网络并进行组网试验。在这个例子中,我们将深入探讨ZStack协议栈和CC2530硬件平台的关键特性以及它们在SensorDemo中的应用。 首先,CC...

    PyPI 官网下载 | zigpy-homeassistant-0.9.0a3.tar.gz

    Zigbee是一种低功耗、低数据速率的无线网络协议,广泛应用于智能家居、物联网(IoT)设备和工业自动化等领域。Home Assistant是一个流行的开源智能家居控制系统,它允许用户通过自定义规则和自动化来管理各种智能设备...

    Ti的CC2430下载工具V1.8.1

    在无线通信领域,Zigbee技术以其低功耗、低成本、易组网的特点被广泛应用。而CC2430作为Zigbee芯片的重要代表,是TI(Texas Instruments)推出的一款集成了微控制器与2.4GHz射频收发器的单片系统(SoC)。为了对CC...

Global site tag (gtag.js) - Google Analytics