8.4ZigBee网络多信道调度如果需要扩大ZigBee网络规模,只要网络PANID不同,在一个信道上建立多个PAN网络的方式是可行的,但是,IEEE802.15.4标准MAC层信道接入技术采用的是CSMA/CA机制,过多的节点势必会造成严重的信道退避冲突。IEEE802.15.4标准使用的2.4GHz频段具有16个信道。因此,利用ZigBee多信道特性可以建立多个PAN网络。根据多个网络的负载程度,设置物理信道以选择性加入网络,实现网络负载相对平衡;当由于某种原因与网络长时间断开连接后,节点能够自动地切换信道加入另一个可用网络,以增强网络灵活性和可靠性。本节实验主要讲述节点利用协议栈网络层自动切换信道和在应用层设置信道两种方式。实验目的与器材1)实验目的深入理解Z-Stack节点入网过程以及信道概念。学会在Z-Stack中进行信道设置以及切换。理解并学会使用非易失性存储器(NV)相关操作。Z-Stack中使用标准C语言函数库。2)实验器材5个CC2530开发套件(2个协调器模块,1个终端模块,2个用于PacketSniffer抓包)实验原理与步骤1.实验原理1)网络发现和节点信道自动切换协调器上电后,进行一系列的初始化设备,初始化网络事件等过程后,请求建立形成一个新的网络。当网络建立成功后,就可以等待其他终端设备和路由器节点加入。终端设备在经过一系列的初始化过程后,首先要请求网络层执行网络扫描发现已经存在的网络。然后,终端设备根据网络发现返回的网络号、信道号等信息,请求加入网络。如果加入网络失败,节点初始化网络继续上述过程。终端设备加入网络后,如果与网络断开后,节点会初始化网络等待再次加入先前的网络。此时,如果在另一个信道上存在一个网络,终端设备可以选择加入这个网络,从而实现信道自动切换,保证节点不离开ZigBee网络。网络启动与节点加入流程函数基本上都在Z-StackZDApp.c文件中。读者可以在这个文件的关键函数处加入断点,追踪程序流程。下面主要介绍终端设备的入网过程和无法自动调频原因。(1)设备初始化终端设备上电后,在ZDApp_Init中调用初始化设备函数:ZDOInitDevice(0);ZDOInitDevice函数主要完成初始化任务ID,网络地址,网络服务,初始化NV,安全等参数。ZDOInitDevice函数最后触发初始化网络操作:ZDApp_NetworkInit(extendedDelay);此函数用于启动网络加入过程,extendedDelay代表在网络启动前需等待的时间。函数中启动网络初始事件ZDO_NETWORK_INIT。osal_start_timerEx(ZDAppTaskID,ZDO_NETWORK_INIT,delay);ZDO层任务事件处理函数ZDApp_event_loop对网络初始化事件进行处理,设置设备初始状态为DEV_INIT。并启动该设备if(events&ZDO_NETWORK_INIT){devState=DEV_INIT;ZDO_StartDevice((uint8)ZDO_Config_Node_Descriptor.LogicalType,devStartMode,DEFAULT_BEACON_ORDER,DEFAULT_SUPERFRAME_ORDER);return(events^ZDO_NETWORK_INIT);}(2)网络发现如果是协调器,程序将会调用NLME_NetworkFormationRequest函数请求建立网络。如果是终端设备,程序会启动网络发现过程:在ZDO_StartDevice中,执行if((startMode==MODE_JOIN)||(startMode==MODE_REJOIN)){devState=DEV_NWK_DISC;#ifdefined(MANAGED_SCAN)ZDOManagedScan_Next();ret=NLME_NetworkDiscoveryRequest(managedScanChannelMask,BEACON_ORDER_15_MSEC);#elseret=NLME_NetworkDiscoveryRequest(zgDefaultChannelList,zgDefaultStartingScanDuration);#endif}NLME_NetworkDiscoveryRequest()正是网络发现过程中最为关键的函数,但是由于TI并没有给出该函数的具体实现,所以对理解网络发现的具体实现过程存在一定的困难。TI提供了ZDO_NetworkDiscoveryConfirmCB()回调函数。该函数返回网络发现的结果,包括网络ID,网络频段等网络重要信息。在ZDO_NetworkDiscoveryConfirmCB()中最后触发函数:ZDApp_SendMsg(ZDAppTaskID,ZDO_NWK_DISC_CNF,sizeof(ZDO_NetworkDiscoveryCfm_t),(byte*)&msg);该函数向ZDAppTaskID任务投递一个ZDO_NWK_DISC_CNF事件。(3)加入网络在ZDApp_ProcessOSALMsg()函数中响应ZDO_NWK_DISC_CNF事件:caseZDO_NWK_DISC_CNF:……if(ZG_BUILD_JOINING_TYPE&&ZG_DEVICE_JOINING_TYPE)if(devStartMode==MODE_JOIN){devState=DEV_NWK_JOINING;ZDApp_NodeProfileSync((ZDO_NetworkDiscoveryCfm_t*)msgPtr);if(NLME_JoinRequest(…..)!=ZSuccess){ZDApp_NetworkInit((uint16)(NWK_START_DELAY+((uint16)(osal_rand()&EXTENDED_JOINING_RANDOM_MASK))));}}其中网络的加入通过NLME_JoinRequest()函数实现,其参数logicalChannel就是加入网络所在的频段。如果成功加入网络,节点将会分配到网络地址和端点等信息,设为成功加入网络状态。如果该函数执行失败,则调用初始化网络函数ZDApp_NetworkInit()重新寻找网络。在ZDApp_NetworkInit()函数中又会触发ZDO_NETWORK_INIT事件,进入下一轮的网络加入过程。(4)终端节点断开网络后,无法自动切换信道的原因终端节点与网络断开后,就会重新孤立扫描程序,由于先前没有加入过网络,通过孤立扫描程序加入网络失败。终端节点重启网络发现过程,具体过程已在上文中详细阐述。当再次执行到网络发现ZDO_NWK_DISC_CNF事件,而后在ZDApp_ProcessOSALMsg()函数中响应该事件。如果此时网络没有恢复,节点不再执行网络加入过程,而是执行continueJoining代码段,即执行以下程序:caseZDO_NWK_DISC_CNF:…….if((((ZDO_NetworkDiscoveryCfm_t*)msgPtr)-hdr.status==ZDO_SUCCESS)&&(zdoDiscCounterNUM_DISC_ATTEMPTS))………//如果指示网络发现不成功或者成功次数不符合规定elseif(continueJoining){#ifdefined(MANAGED_SCAN)ZDApp_NetworkInit(MANAGEDSCAN_DELAY_BETWEEN_SCANS);#elsezdoDiscCounter++;ZDApp_NetworkInit((uint16)(BEACON_REQUEST_DELAY+((uint16)(osal_rand()&BEACON_REQ_DELAY_MASK))));#endif}MANAGED_SCAN是编译选项,允许信道扫描延迟。从以上程序可以看到,当节点与父节点断开连接后,子节点会不断的重复执行ZDApp_NetworkInit初始化网络,试图加入先前的网络,直到与先前网络重新建立连接。这就是终端节点无法加入到其他网络,实现自动切换信道的原因。在continueJoining函数段添加增加节点请求入网NLME_JoinRequest函数,即可实现信道跳转,加入到其他网络。2)使用NV区设置信道利用mac_low_level.h文件中macRadioSetChannel(uint8channel),ZmacSetReq(ZMACChannel)能够实现信道设置。但是,这种在MAC层设置信道的方式可能会影响到上层一些其他函数执行,产生一些严重后果。本节介绍利用非易失存储器(NonVolatile,NV)设置信道,启动节点实现应用层设置信道。非易失存储器,像硬盘,U盘(闪存)等存储介质,掉电后其信息不丢失。而易失性存储器,像内存,断电后存储信息就会丢失。易失性存储器有什么缺点呢?举个例子说,你的IAR软件在处于编辑时状态时,会将Z-Stack工程从硬盘装入到内存中。如果突然停电了,你想起刚敲打的几行代码还没有保存到硬盘上,这时的你会有怎样的反应呢?与此类似,Z-Stack把一些重要的系统参数存储到NV中。存入NV的系统参数通常包括网络NIB,组表,设备表,绑定表,ProfileID,网络密匙等信息。节点不必每次重启时都需重新配置如此多的参数,能够迅速恢复到掉电前的系统状态。OSAL主要有以下几个重要的NV函数:1.osal_nv_item_init()初始化nv条目。2.osal_nv_read()读取nv条目。3.osal_nv_write()写入nv条目。4.NLME_InitNV(void)NV区初始化。5.NLME_SetDefaultNV()设置默认的NV区条目。6.NLME_RestoreFromNV()从NV区中恢复条目。使用这几个函数时,读者须加入NV_INIT和NV_RESTORE这两个编译选项。使用NV区设置信道,读者可以把欲写入的信道值使用osal_nv_write()函数写入NV区中,然后使用SimpleAPI中的zb_SystemReset()重启系统。重启之后,节点就可能在设定信道上工作。这里说“可能”的意思是节点设置的PANID和信道号,可能不存在于现存网络中的PANID和信道集合。换句话说,节点不能加入到现存网络。所以,PANID和信道设置要与现存网络PANID和信道号一致。2.程序流程本实验是在TISensorDemo官方例程基础上修改的。SensorDemo工程主要分为传感器节点(Sensor)和数据收集(Collect)节点两种类型。Sensor节点为终端节点,采集温度、光照等信息。Collect节点一般为路由器或协调器节点,主要用于数据汇集等。1)默认信道设置在f8wConfig.cfg配置文件中进行信道设置:/*DefaultchannelisChannel11-0x0B*///Channelsaredefinedinthefollowing://0:868MHz0x00000001//1-10:915MHz0x000007FE//11-26:2.4GHz0x07FFF800////-DMAX_CHANNELS_868MHZ0x00000001//-DMAX_CHANNELS_915MHZ0x000007FE//-DMAX_CHANNELS_24GHZ0x07FFF800//-DDEFAULT_CHANLIST=0x04000000//26-0x1A//-DDEFAULT_CHANLIST=0x02000000//25-0x19//-DDEFAULT_CHANLIST=0x01000000//24-0x18//-DDEFAULT_CHANLIST=0x00800000//23-0x17//-DDEFAULT_CHANLIST=0x