个人分析如下:
1、ZDO_JoinIndicationCB函数的处理
(1)每次产生回调,会新增到单链表ZDApp_NewDeviceList中,然后开启定时器事件ZDO_NEW_DEVICE
(2)在ZDO_NEW_DEVICE事件中处理
(3)根据链表节点,重复开启ZDO_NEW_DEVICE
疑问:这里的每个节点的timeDelta参数的计算?
举例:第一个节点加入时间T1(开启timer),第二个节点加入时间T2 = T1 + 100MS,那么第二个节点的timeDelta = ZDAPP_NEW_DEVICE_TIME – 100 = 500
当第一个节点ZDAPP_NEW_DEVICE_TIME时间到达后,处理;第二个节点,此时加入设备链表不是已经经过了500ms,怎么还是开启timer = 500的定时器?
ZStatus_t ZDO_JoinIndicationCB(uint16 ShortAddress, uint8 *ExtendedAddress,uint8 CapabilityFlags, uint8 type) {// get the remaining time of the timertimeToFire = osal_get_timeoutEx( ZDAppTaskID, ZDO_NEW_DEVICE );pNewDevice->next = NULL;pNewDevice->shortAddr = ShortAddress; ////////////////////////////////////////////////////////////////////////////// //这里时间处理不明白?pNewDevice->timeDelta = ZDAPP_NEW_DEVICE_TIME - timeToFire; //////////////////////////////////////////////////////////////////////////////// Start the timer only if there is no pending timerif ( pNewDevice->timeDelta == ZDAPP_NEW_DEVICE_TIME ){osal_start_timerEx( ZDAppTaskID, ZDO_NEW_DEVICE, ZDAPP_NEW_DEVICE_TIME );}return ZSuccess; }// process the new device eventif ( ZDApp_NewDeviceList ){ZDAppNewDevice_t *pNewDevice;uint16 timeDelta;(void) ZDSecMgrNewDeviceEvent( ZDApp_NewDeviceList->shortAddr );pNewDevice = (ZDAppNewDevice_t *) ZDApp_NewDeviceList->next;osal_mem_free( ZDApp_NewDeviceList );ZDApp_NewDeviceList = pNewDevice;if ( pNewDevice ){timeDelta = pNewDevice->timeDelta;pNewDevice = pNewDevice->next;while ( pNewDevice ){ ////////////////////////////////////////////////////////////////// //这里时间处理不明白?pNewDevice->timeDelta -= timeDelta; //////////////////////////////////////////////////////////////////pNewDevice = pNewDevice->next;}osal_start_timerEx( ZDAppTaskID, ZDO_NEW_DEVICE, timeDelta );}}
Alvin Chen:
只有当没有ZDO_NEW_DEVICE没有no pending timer才会去开启ZDO_NEW_DEVICE任务。
// Start the timer only if there is no pending timerif ( pNewDevice->timeDelta == ZDAPP_NEW_DEVICE_TIME ){OsalPortTimers_startTimer( ZDAppTaskID, ZDO_NEW_DEVICE, ZDAPP_NEW_DEVICE_TIME );}
此外关于节点加入网络,为了防止发送冲突,建议是当一个节点入网成功后入网后续节点
xin dong:
回复 Alvin Chen:
这里第一个加网的设备产生的ZDO_JoinIndicationCB,此时ZDO_NEW_DEVICE,没有开启,则会打开ZDO_NEW_DEVICE任务,但是ZDAPP_NEW_DEVICE_TIME时间还没有到,此时又有新的节点加入,这里的timeDelta处理,没明白什么意思?
xin dong:
回复 Alvin Chen:
我想问的是为什么pNewDevice->timeDelta = ZDAPP_NEW_DEVICE_TIME – timeToFire??
如果第一个节点加入100ms后,第二个加入,此时第二个节点timeDelta= ZDAPP_NEW_DEVICE_TIME – 100 = 500
第一个节点加入开启的ZDO_NEW_DEVICE时间到达,再次开启第二个节点的ZDO_NEW_DEVICE事件
那么第二个节点的时间,不就不是ZDAPP_NEW_DEVICE_TIME ,而是2 *timeDelta= 1000了??
Alvin Chen:
回复 xin dong:
你没看明白吧,当你ZDAPP_NEW_DEVICE_TIME有剩余不会再次开启ZDO_NEW_DEVICE事件。
第二个节点会在while ( pNewDevice ){
pNewDevice->timeDelta -= timeDelta;
pNewDevice = pNewDevice->next;}
xin dong:
回复 Alvin Chen:
如果只有两个节点
第一个节点开启ZDO_NEW_DEVICE后,时间到达后,处理完成后
pNewDevice = (ZDAppNewDevice_t *) ZDApp_NewDeviceList->next;osal_mem_free( ZDApp_NewDeviceList );//第一个节点就会删除ZDApp_NewDeviceList = pNewDevice;//第二个节点成为链表头
if ( pNewDevice ){timeDelta = pNewDevice->timeDelta;pNewDevice = pNewDevice->next;//一共两个节点,所有这里为null,因此while ( pNewDevice )不成立
while ( pNewDevice ){pNewDevice->timeDelta -= timeDelta;pNewDevice = pNewDevice->next;}
osal_start_timerEx( ZDAppTaskID, ZDO_NEW_DEVICE, timeDelta );
//这里的时间不就是之前计算的timeDelta =ZDAPP_NEW_DEVICE_TIME – timeToFire}
xin dong:
回复 Alvin Chen:
个人理解错误。
Thanks Alvin!