|
上一节说到ZDApp_NetworkInit函数触发了ZDO_NETWORK_INIT任务,这个任务是由ZDApp_event_loop来处理的:
UINT16 ZDApp_event_loop( byte task_id, UINT16 events )
{
…………
if ( events & ZDO_NETWORK_INIT )
{
// Initialize apps and start the network
devState = DEV_INIT;
ZDO_StartDevice( (uint8)ZDO_Config_Node_Descriptor.LogicalType, devStartMode,
DEFAULT_BEACON_ORDER, DEFAULT_SUPERFRAME_ORDER );
// Return unprocessed events
return (events ^ ZDO_NETWORK_INIT);
}
…………
}
可以看到,这个函数的主要作用是调用了ZDO_StartDevice函数,参数ZDO_Config_Node_Descriptor.LogicalType在之前已经被设置为NODETYPE_COORDINATOR,表明这个设备的类型为协调器。
void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder )
{
ZStatus_t ret;
ret = ZUnsupportedMode;
#if defined(ZDO_COORDINATOR)
if ( logicalType == NODETYPE_COORDINATOR )
{
if ( startMode == MODE_HARD ) //MODE_HARD
{
devState = DEV_COORD_STARTING; //Started as Zigbee Coordinator
//建网
ret = NLME_NetworkFormationRequest( zgConfigPANID, zgDefaultChannelList,
zgDefaultStartingScanDuration, beaconOrder,
superframeOrder, false );
}
else if ( startMode == MODE_RESUME ) //MODE_RESUME
{
// Just start the coordinator
devState = DEV_COORD_STARTING;
ret = NLME_StartRouterRequest( beaconOrder, beaconOrder, false );
}
else //错误,未知启动模式
{
#if defined( LCD_SUPPORTED )
//HalLcdWriteScreen( "StartDevice ERR", "MODE unknown" );
ClearScreen();
Print8(HAL_LCD_LINE_1,10,"StartDevice ERR",1);
Print8(HAL_LCD_LINE_2,10,"MODE unknown",1);
#endif
}
}
#endif // !ZDO_COORDINATOR
//#if !defined ( ZDO_COORDINATOR ) || defined( SOFT_START )
if ( logicalType == NODETYPE_ROUTER || logicalType == NODETYPE_DEVICE )
{
if ( (startMode == MODE_JOIN) || (startMode == MODE_REJOIN) )
{
devState = DEV_NWK_DISC; //Discovering PAN's to join
#if defined( MANAGED_SCAN )
ZDOManagedScan_Next();
ret = NLME_NetworkDiscoveryRequest( managedScanChannelMask, BEACON_ORDER_15_MSEC );
#else
ret = NLME_NetworkDiscoveryRequest( zgDefaultChannelList, zgDefaultStartingScanDuration );
#endif
}
else if ( startMode == MODE_RESUME ) //MODE_RESUME 恢复
{
if ( logicalType == NODETYPE_ROUTER )
{
ZMacScanCnf_t scanCnf;
devState = DEV_NWK_ORPHAN;
/* if router and nvram is available, fake successful orphan scan */
scanCnf.hdr.Status = ZSUCCESS;
scanCnf.ScanType = ZMAC_ORPHAN_SCAN;
scanCnf.UnscannedChannels = 0;
scanCnf.ResultListSize = 0;
nwk_ScanJoiningOrphan(&scanCnf);
ret = ZSuccess;
}
else
{
devState = DEV_NWK_ORPHAN; //孤儿
ret = NLME_OrphanJoinRequest( zgDefaultChannelList,
zgDefaultStartingScanDuration );
}
}
else
{
#if defined( LCD_SUPPORTED )
// HalLcdWriteScreen( "StartDevice ERR", "MODE unknown" );
Print8(HAL_LCD_LINE_1,10,"StartDevice ERR",1);
Print8(HAL_LCD_LINE_2,10,"MODE unknown",1);
#endif
}
}
//#endif //!ZDO COORDINATOR || SOFT_START
if ( ret != ZSuccess )
osal_start_timerEx(ZDAppTaskID, ZDO_NETWORK_INIT, NWK_RETRY_DELAY );
}
ZDO_StartDevice函数的内容非常多,也特别的重要,第一次看的话有点吃力,但是其中最为重要的部分是调用了NLME_NetworkFormationRequest函数,发出网络创建请求。NLME_NetworkFormationRequest函数的详细部分是放在库文件中的,这里我们没有办法列出它的具体代码。
在ZStack中大量使用了回调函数来处理各种任务请求,网络创建请求的回调函数为:
void ZDO_NetworkFormationConfirmCB( ZStatus_t Status )
{
#if defined(ZDO_COORDINATOR)
nwkStatus = (byte)Status;
if ( Status == ZSUCCESS )
{
// LED on shows Coordinator started
HalLedSet ( HAL_LED_3, HAL_LED_MODE_ON );
// LED off forgets HOLD_AUTO_START
HalLedSet (HAL_LED_4, HAL_LED_MODE_OFF);
#if defined ( ZBIT )
SIM_SetColor(0xd0ffd0);
#endif
if ( devState == DEV_HOLD )
{
// Began with HOLD_AUTO_START
devState = DEV_COORD_STARTING;
}
}
#if defined(BLINK_LEDS)
else
HalLedSet ( HAL_LED_3, HAL_LED_MODE_FLASH ); // Flash LED to show failure
#endif
osal_set_event( ZDAppTaskID, ZDO_NETWORK_START );
#endif //ZDO_COORDINATOR
}
如果Status返回ZSUCCESS,建立网络成功,LED3被点亮,LED4将被熄灭来作为网络状态指示。至此,ZStack协调器网络组建的过程已经完成。
本文为与非网月光码头原创,未经允许谢绝转载。
更多内容请见:【深度分析Zigbee】Zigbee技术知多少?资深大牛对对碰
----------------------------
主讲嘉宾简 介:网名:月光码头。毕业于中国科学院电子学研究所,主要从事zigbee物联网方向的应用研究,尤其擅长TI RF芯片、和Silicon Lab MCU芯片的使用。现就职于上海理滋芯片设计公司,任研发部门经理,主要从事智能家居产品的设计开发,拥有5年多的zigbee软硬件开发经验。
------------------
推荐技术讲座:
听东北人讲天线:每周一个实例,个个经典!(CST仿真实践全包括)
【ADS学习小组】课程汇总(火烽主讲)
【HFSS学习小组】课程汇总(木木主讲)
|
|