Zigbee组网设备分为三类:
1.Coordinator(图中黑色的节点)。发起网络,并确定PAN ID的设备。一个网里有且只有一个。组网完成之后退化为Router。
2.Router(图中红色的节点)。管理若干子节点,须一直在线。
3.End-device(图中白色的节点)。可以休眠。
从图中可以看出,zigbee网络是一个网状结构,从图论的角度讲,End-device相当于叶子,而Router相当于枝干。Coordinator在组网的时候,相当于根节点,但是组网一旦完成,整个网络就没有中心了,数据交换是不必通过Coordinator的。从图中还可看出,数据从一个节点到另一个节点,中间会经过多次中继节点的数据交换,因此存在路由算法的问题。
简单来说,通常只有栈类型相同的设备之间才能组网。也分为三类:
1.Zigbee。
2.Zigbee PRO。
3.自定义。
设备地址分为64位的MAC地址和16位的逻辑地址两种,其中前者全球唯一,而后者全网唯一。其中后者的唯一性,由相关地址分配算法和地址冲突机制保证。
此外对应用而言,还有EndPoint需要指定,它相当于普通TCP/IP的端口号。afRegister函数用于指定EndPoint。
按目的地的不同分为三类:
1.Unicast。发给单独的设备。
2.Multicast。发给一组设备。知识点:Group Addressing
3.Broadcast。全网广播。
存在以下几种广播地址:
0xFFFF -这个一个对全网络中设备进行广播的广播地址
0xFFFD -如果在命令中将目标地址设为这个地址的话那么只对打开了接收的设备进行广播
0xFFFC -广播到协调器和路由器
0xFFFE -如果目的地址为这个地址的话,那么应用层将不指定目标设备,而是通过协议栈读取绑定表来获得相应目标设备的短地址。
此外的0x0000到0xFFF8都是有效的目的地址。其中协调器为0x0000。
按照目的地指派方式的不同可分为直接和间接两种。后者通过查找Binding Table的方式找到目的地的逻辑地址。知识点:Binding的含义,以及Binding Table的实现。
1.路由发现、选择和维护相关的规则。
2.路由表存储及维护
1.End-device由于移动导致的父节点的更换。
2.PAN ID冲突的解决,以及跨PAN通讯的实现。
3.无线信道的选择。知识点:侦测环境,确定最小噪声的信道。
ZigBee联盟除了定义ZigBee协议的物理层和链路层之外,还对应用层做了一些统一的规定。其中Profile ID用于区分设备的应用领域,比如是灯光,还是传感器。而Cluster ID用于细分同一个Profile下的操作,比如灯光是调亮,还是调暗。
Z-Stack是德州仪器公司推出的Zigbee协议栈。源代码不公开,仅有如何使用的接口文档。
Z-Stack的消息分为两大类:系统消息SYS_EVENT_MSG和自定义消息。其中前者又可分为三大类:
1.硬件消息。例如KEY_CHANGE
2.AF消息。主要是和数据的交换和路由相关的消息。例如AF_DATA_CONFIRM_CMD,AF_INCOMING_MSG_CMD。
3.ZDO消息。和具体设备的应用相关的消息。例如ZDO_STATE_CHANGE,ZDO_CB_MSG。
1.可以设定Coordinator组网所用的Channel和Pan ID,否则就是随机生成Channel和Pan ID。
2.在指定Channel或Pan ID的情况下,如果已经有网络使用了该Channel或Pan ID,则Coordinator会重新选择一个Channel或Pan ID。但是与之配套的Router和End Device无法侦测到这个改变,因此会加入已有的网络,而不是Coordinator新建的网络。
3.设备可开机自动入网,也可稍后手动入网。入网成功之后,可以保存入网信息。
绑定就是发送方指定接收方。而查找则是接收方注册可以被接受的发送方。
设计原则:
1.SYS_EVENT_MSG消息需要一次性全部处理完。
2.而其他消息最好一次只处理一条。
sentTransID可用于标识消息。每发一条消息,自动加1。
从芯片手册来看,CC2530采用的是NOR FLASH。其所用的存储方案实际上和我去年提出的一份专利类似:它的实现更通用一些,但是性能上比我的要差些。
1)主流程
main—主函数
->osal_init_system
-->osalInitTasks—初始化任务结构,每个任务会分配一个全局的任务ID,发送消息的时候会用到这个ID。
->osal_start_system—任务调度死循环
-->osal_run_system
--->tasksArr—任务处理回调
2)客户定制的事件处理
Coordinator_ProcessEvent—事件处理入口,可定义为一个任务
->KEY_CHANGE—按键处理
-->Coordinator_Net_PermitDeviceToJoinNet
--->ZDApp_NetworkInit—未建网 OR NLME_PermitJoiningRequest—已建网
->AF_INCOMING_MSG_CMD—接收到数据的消息
->AF_DATA_CONFIRM_CMD—返回发送数据的结果(结果包括是否成功发送等)
3)建网和入网
发起方:
ZDOInitDevice
->ZDApp_NetworkInit
-->ZDO_StartDevice
接收方:
ZDO_JoinIndicationCB
4) 退网
NLME_LeaveReq
5)自定义流程
如果ZStack的标准流程无法满足需要的话,就需要使用ZDO_RegisterForZdoCB函数注册相应的回调函数,来改变标准的流程。
source/Tools/CC2530DB/f8wConfig.cfg—可以配置PAN ID等。
长短地址转换:AddrMgrExtAddrLookup和AddrMgrNwkAddrLookup。
获得长地址:NLME_GetExtAddr。
Zstack的重启分为以下几种:
1)SystemReset
这种重启的机制是关闭中断,并死循环,然后WatchDog超时,从而导致的重启。是为“硬重启”。
2)SystemResetSoft
这种重启,将PC指针重置为0,也就是上电时代码启动的位置。是为“软重启”。
3)ZDO_DEVICE_RESET
除了函数调用式的重启之外,还有消息式的重启。消息处理最终调用SystemResetSoft实现重启。
两者的区别在于,二次组网的时候,由于设备的FLASH上保存有上次启动时的组网信息。因此就没有首次组网时的Beacon request握手过程。
程序使用ZDApp_ReadNetworkRestoreState函数判定是否有上次的组网信息。
HOLD_AUTO_START
为了方便对zigbee协议的调试,TI还提供了CC2531 USB Dongle。这个Dongle硬件配合TI的Packet Sniffer软件,可以对周围的zigbee网络通信进行监控和抓包分析。也就是说它监控的不是单个的Zigbee模块或设备,而是一个区域内的所有Zigbee信号。
使用时,首先需要设定监控的Zigbee Channel。然后即可开启抓包按钮。
以下使用Packet Sniffer对Zigbee组网过程中的数据包,做一个简单的分析。
1.EndDevice不断发送Beacon request数据包。
2.Coordinator把自己的MAC地址和PAN ID发送给EndDevice。此外信息还有节点深度、最大子节点数等内容。EndDevice会根据这个信息选择有富余能力的节点,并进行下一步。
3.EndDevice发送Association request到Coordinator,其中包含了EndDevice的MAC地址。
4.Coordinator返回一个应答包。
5.EndDevice发送Data request到Coordinator。
6.Coordinator返回一个应答包。
7.Coordinator将Short addr发送给EndDevice。
8.EndDevice返回一个应答包。
9.EndDevice发送一个应用层的广播数据包。该包的内容是该设备的长短地址,用于通知网络,它的长短地址之间的对应关系。这个数据包是应用层的,也就是使用AF_DataRequest发送的,而之前步骤的数据包都是链路层的。
应用层所收发的数据包,由3部分组成:
1.MAC层。这一层包括PAN ID,直接的源地址和目标地址。
2.NWK层。这一层包括间接的源地址和目标地址。
3.APS层。这一层包括源EndPoint、目标EndPoint、Cluster ID、Profile ID和普通数据。
下面以多跳情况下的数据交互为例,解释一下直接地址和间接地址的含义。
假设有三台设备A、B、C。其中的路由关系是A->B->C。现在从设备A向设备C发送一个数据包,其步骤如下:
1.Route Request和Route Reply,确定路由。
2.A向B发送一个数据包,该数据包的MAC层地址是A->B,NWK层的地址是A->C。
3.B根据NWK层的地址判定,这个包不是给自己的,而是给C的,于是转发一个数据包。该数据包的MAC层地址是B->C,NWK层的地址是A->C。
4.C根据NWK层的地址判定,这个包虽然是B发过来的,但是数据的源头是A。
1.条件准备
至少有3台设备才可以组成一个深度为2的ZigBee网络。
2.修改配置
默认配置下,Zigbee网络一个节点可以挂载的总设备为20个,其中路由节点为6个。因此如果不修改配置的话,需要很多的设备才能模拟多跳组网的情况。
修改的步骤如下:
1)
#define STACK_PROFILE_ID NETWORK_SPECIFIC
2)
nwk_globals.c文件中的Cskipchldrn数组和CskipRtrs数组。这些数组的值由MAX_CHILDREN和MAX_ROUTER构成。
MAX_CHILDREN决定了一个路由(Router)或者一个协调器节点可以处理的儿子节点的最大个数。
MAX_ROUTER决定了一个路由(Router)或者一个协调器(Coordinator)节点可以处理的具有路由功能的儿子节点的最大个数。这个参数是MAX_CHILDREN的一个子集,终端节点使用(MAX_CHILDREN – MAX_ROUTER)剩下的地址空间。
TI ZigBee FAQ 常见问题解答
http://www.deyisupport.com/question_answer/wireless_connectivity/zigbee/f/104/t/75525.aspx
NLME_PermitJoiningRequest只管本节点是否允许其他设备加入,管不了整个网络。所以多级组网或者设备很多的时候,不但协调器的Permit需要打开,下面Router的Permit也要打开,否则一旦设备和协调器之间无法直接通信,或者协调器直接挂载的设备数已经达到最大值,都会导致设备无法入网。同样,设备退网的时候,也需要将整个网络的Permit都关掉,不然的话,设备一退网,如果发入网请求的话,又会加回来,这就是有人说的设备退不了网的情况。
P2.1和P2.2是特殊的GPIO,由于它们和JTAG复用,因此在调试模式下无法当做GPIO输入来使用,但普通模式下,它们的工作是正常的。
ZigBee resides on IEEE 802.15.4 transceivers, which in the 2.4 GHz space communicate at 250 kilobits per second (kbps), but by the time retries, encryption/decryption, and the fully acknowledged mesh protocol is applied, the actual through- put is closer to 25 kbps.
这是TI官方技术支持的说法,转换成相应的串口波特率大概是38400。也就是说超过这个速度的串口速度对于Zigbee设备来说是处理不过来的。
您的打赏,是对我的鼓励