zstack的数据传输方式————组播、单播浅析

        最近在学习zigbee协议栈,对于zigbee的数据传输方式和流程不是很清楚,因此就狠花了几天功夫去研究zigbee组网流程!首先,下面的分析是基于TI公司zstack自带的例子程序——SampleApp。对SampleApp的应用层程序:SampleApp.c文件进行观察,发现不管选中SampleApp例子程序的哪种设备(coordinator router 还是enddevice),SampleApp.c文件的内容基本上都相同,即每个设备都可以发送和接受两种信息:周期信息(为何coordinator、router、ednDevice都会周期发送信息,我们随后会给出解释,这里先留个悬念)和闪烁信息。由于zstack组网过程不是讲述的重点,因此就不过多的介绍SampleApp例程的组网流程,如果用到的话再讲。

         这里直接进入SampleApp_Init()函数,该函数是SampleApp例程的应用层初始化的入口。语句:

if ( readCoordinatorJumper() )
    zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;
  else
    zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;

的意思是:通过判断传感器节点的跳线来判断该节点是coordinator还是router。

继续往下走看到下面的语句:


这个是节点发送周期信息的配置,其中第一行的addrMode = (afAddrMode_t)AddrBroadcast表示设备发送信息的方式是广播。而第三行的shortAddr=0xFFFF表示设备会将信息广播到网络上的所有设备。至于为何是shortAddr为0xFFFF表示广播到网络上的所有设备,这不解释了!

zstack的数据传输方式————组播、单播浅析_第1张图片



程序继续往下走,可以看到下列的语句:

zstack的数据传输方式————组播、单播浅析_第2张图片

这些语句是发送闪烁信息的配置。


程序继续往下走,可以看到下列语句:


同志们,这里可以看到,所有的设备都默认在组1里面。


在zigbee协议栈中,最最重要的就是任务事件的处理,zstack只要有需要处理的信息,首当其冲需要想到的就是事件处理函数,这里也一样,在初始化函数SampleApp_Init()执行后,接下来要执行的就是函数:uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ),这个函数的参数events就对应了相关的事件。这里我们学习的是数据传输过程,所以第一步是先要形成一个WSN的网络,而组网肯定会产生事件,而且这里产生的还是系统事件,具体的事件为ZDO_STATE_CHANGE。所以对应着SampleApp_ProcessEvent( uint8 task_id, uint16 events )函数的if ( events & SYS_EVENT_MSG )分支,该分支有个switch选择,对应的case ZDO_STATE_CHANGE,在选项分支里面,我们可以看到,不管设备是coordinator还是router还是endDevice,都会周期性(这里使用的是定时)的发送信息,这就解释了开始提出悬疑:为何每种设备都会周期性的发送信息。具体代码如下。

zstack的数据传输方式————组播、单播浅析_第3张图片


在case ZDO_STATE_CHANGE中,我们看到了SAMPLEAPP_SEND_PERIODIC_MSG_EVT,这也是事件,这个事件会导致下面的if语句运行:

zstack的数据传输方式————组播、单播浅析_第4张图片

进入该if语句的SampleApp_SendPeriodicMessage()函数,我们右键点击该函数,选择go to definition,下图是SampleApp_SendPeriodicMessage()函数的主体:

zstack的数据传输方式————组播、单播浅析_第5张图片

可以发现SampleApp_SendPeriodicMessage()调用通信原语,换句话说,我们不能也不需要进入AF_DataRequest()的内部,只需要了解AF_DataRequest()函数每个参数的意义即可,AF_DataRequest()第一个参数表示设备需要发送信息到哪个目标地址,为了找到第一个参数的具体值,我们需要搜索工程中的所有第一个参数的引用。具体方法是:依次点击IAR的菜单栏的“edit” 下拉菜单的 "find and replaces" 的选项“"find in files",把SampleApp_Periodic_DstAddr复制出现的文本框,如下图示:

zstack的数据传输方式————组播、单播浅析_第6张图片

在搜索到的信息中,我们可以找到下列信息:

SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast,该语句表明AF_DataRequest()是将信息发送到网络上的所有设备!即周期性的信息发送方式是广播方式。

到这里我们就介绍了TI公司自带的例程SampleApp的广播信息发送过程!


而SampleApp实际上还有种数据传输方式为组播,那组播的过程又是怎么实现的呢?请继续往下看!

在该例程中,组播的具体实现是对按键事件的响应。在SampleApp.c文件中,找到函数:void SampleApp_HandleKeys( uint8 shift, uint8 keys ),该函数是组播方式,

我们可以发现下列if语句:if ( keys & HAL_KEY_SW_1 ),该if语句的意思是如果按下按键SW_1,则调用函数: SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION ),按照之前的方法,进入SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION )函数的内部。该函数的内部同样也调用了一个原语:AF_DataRequest,具体内容如下:

zstack的数据传输方式————组播、单播浅析_第7张图片


同样,该原语的第一个参数表示信息发送的目标地址,即信息发送的方式是广播还是组播还是点播,按照之前搜索原语参数的所有引用的过程,可以同样得到SampleApp_Flash_DstAddr的所有引用,搜索到的SampleApp_Flash_DstAddr所有引用如下:



我们点击第二个引用,得到:下列语句:从这里就可以得到,如果有按键按下了,则该节点会发送组播的信息!



以上观点纯属个人看法 ,欢迎各位留言!











你可能感兴趣的:(zigbee及无线传感网,zigbee,zstack,组播,广播,无线传感网)