网路设备的启动过程
无论是协调器还是路由器或是终端设备,其启动过程至网络初始步骤均是一样的,只是不同设备的配置文件在编译时有所区别:
协调器:F8wCoord.cfg
路由器:F8wRouter.cfg
终端设备:F8wEndev.cfg
启动过程:
1、int main( void )中的 osal_init_system();
2、 osal_init_system();中的 osalInitTasks();
3、osalInitTasks();中的 ZDApp_Init( taskID++ );和SerialApp_Init( taskID );
4、
/*********************************************************************
* @fn ZDApp_Init
*
* @brief ZDApp Initialization function.
*
* @param task_id - ZDApp Task ID
*
* @return None
*/
void ZDApp_Init( uint8 task_id )
{
// Save the task ID
ZDAppTaskID = task_id;
// Initialize the ZDO global device short address storage
ZDAppNwkAddr.addrMode = Addr16Bit;//地址模式为16bit短地址
ZDAppNwkAddr.addr.shortAddr = INVALID_NODE_ADDR; // 短地址INVALID_NODE_ADDR = 0xFFFE
(void)NLME_GetExtAddr(); // Load the saveExtAddr pointer. //API函数,用于得到64bit IEEE地址
// Check for manual "Hold Auto Start"
ZDAppCheckForHoldKey();
// Initialize ZDO items and setup the device - type of device to create.
ZDO_Init();
// Register the endpoint description with the AF
// This task doesn't have a Simple description, but we still need
// to register the endpoint.
afRegister( (endPointDesc_t *)&ZDApp_epDesc );//为设备注册端点0描述符
#if defined( ZDO_USERDESC_RESPONSE )
ZDApp_InitUserDesc();
#endif // ZDO_USERDESC_RESPONSE
// Start the device?
if ( devState != DEV_HOLD )// 无HOLD_AUTO_START此项预编译,所以devState = DEV_INIT
{
ZDOInitDevice( 0 );
}
else
{
ZDOInitDevice( ZDO_INIT_HOLD_NWK_START );
// Blink LED to indicate HOLD_START
HalLedBlink ( HAL_LED_4, 0, 50, 500 );
}
// Initialize the ZDO callback function pointers zdoCBFunc[]
ZDApp_InitZdoCBFunc();
ZDApp_RegisterCBs();
} /* ZDApp_Init() */
/*********************************************************************
* @fn ZDOInitDevice
*
* @brief Start the device in the network. This function will read
* ZCD_NV_STARTUP_OPTION (NV item) to determine whether or not to
* restore the network state of the device.
*
* @param startDelay - timeDelay to start device (in milliseconds).
* There is a jitter added to this delay:
* ((NWK_START_DELAY + startDelay)
* + (osal_rand() & EXTENDED_JOINING_RANDOM_MASK))
* When startDelay is set to ZDO_INIT_HOLD_NWK_START
* this function will hold the network init. Application
* can start the device.
*
* NOTE: If the application would like to force a "new" join, the
* application should set the ZCD_STARTOPT_DEFAULT_NETWORK_STATE
* bit in the ZCD_NV_STARTUP_OPTION NV item before calling
* this function. "new" join means to not restore the network
* state of the device. Use zgWriteStartupOptions() to set these
* options.
*
* @return
* ZDO_INITDEV_RESTORED_NETWORK_STATE - The device's network state was
* restored.
* ZDO_INITDEV_NEW_NETWORK_STATE - The network state was initialized.
* This could mean that ZCD_NV_STARTUP_OPTION said to not restore, or
* it could mean that there was no network state to restore.
* ZDO_INITDEV_LEAVE_NOT_STARTED - Before the reset, a network leave was issued
* with the rejoin option set to TRUE. So, the device was not
* started in the network (one time only). The next time this
* function is called it will start.
*/
uint8 ZDOInitDevice( uint16 startDelay )
{
uint8 networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;//0x01,初始化该设备新的网络状态
uint16 extendedDelay = 0;
if ( devState == DEV_HOLD )
{
// Initialize the RAM items table, in case an NV item has been updated.
zgInitItems( FALSE );
}
ZDConfig_InitDescriptors();
//devtag.071807.todo - fix this temporary solution
_NIB.CapabilityFlags = ZDO_Config_Node_Descriptor.CapabilityFlags;
#if defined ( NV_RESTORE )
// Get Keypad directly to see if a reset nv is needed.
// Hold down the SW_BYPASS_NV key (defined in OnBoard.h)
// while booting to skip past NV Restore.
if ( HalKeyRead() == SW_BYPASS_NV )
networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;
else
{
// Determine if NV should be restored
networkStateNV = ZDApp_ReadNetworkRestoreState();
}
if ( networkStateNV == ZDO_INITDEV_RESTORED_NETWORK_STATE )
{
networkStateNV = ZDApp_RestoreNetworkState();
}
else
{
// Wipe out the network state in NV
NLME_InitNV();
NLME_SetDefaultNV();
// clear NWK key values
ZDSecMgrClearNVKeyValues();
}
#endif
if ( networkStateNV == ZDO_INITDEV_NEW_NETWORK_STATE )
{
ZDAppDetermineDeviceType();//确定该设备的类型
// Only delay if joining network - not restoring network state
extendedDelay = (uint16)((NWK_START_DELAY + startDelay)
+ (osal_rand() & EXTENDED_JOINING_RANDOM_MASK));
}
// Initialize the security for type of device
ZDApp_SecInit( networkStateNV );
if( ZDO_INIT_HOLD_NWK_START != startDelay )
{
devState = DEV_INIT; // Remove the Hold state
// Initialize leave control logic
ZDApp_LeaveCtrlInit();
// Check leave control reset settings
ZDApp_LeaveCtrlStartup( &devState, &startDelay );
// Leave may make the hold state come back
if ( devState == DEV_HOLD )
{
// Set the NV startup option to force a "new" join.
zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );
// Notify the applications
osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );
return ( ZDO_INITDEV_LEAVE_NOT_STARTED ); // Don't join - (one time).
}
// Trigger the network start
ZDApp_NetworkInit( extendedDelay );//开始形成网络
}
// set broadcast address mask to support broadcast filtering
NLME_SetBroadcastFilter( ZDO_Config_Node_Descriptor.CapabilityFlags );
return ( networkStateNV );
}
/*********************************************************************
* @fn ZDApp_NetworkInit()
*
* @brief Used to start the network joining process
*
* @param delay - mSec delay to wait before starting
*
* @return none
*/
void ZDApp_NetworkInit( uint16 delay )
{
if ( delay )
{
// Wait awhile before starting the device
osal_start_timerEx( ZDAppTaskID, ZDO_NETWORK_INIT, delay );
}
else
{
osal_set_event( ZDAppTaskID, ZDO_NETWORK_INIT );
}
}
5、UINT16 ZDApp_event_loop( uint8 task_id, UINT16 events )中的
ZDO_StartDevice( (uint8)ZDO_Config_Node_Descriptor.LogicalType, devStartMode,
DEFAULT_BEACON_ORDER, DEFAULT_SUPERFRAME_ORDER );
协调器建网
void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder )
{
devState = DEV_NWK_DISC;
ret = NLME_NetworkDiscoveryRequest( zgDefaultChannelList, zgDefaultStartingScanDuration );
……
}
路由器入网
void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder )
{
devState = DEV_NWK_DISC;
ret = NLME_NetworkDiscoveryRequest( zgDefaultChannelList, zgDefaultStartingScanDuration );
……
}
终端设备入网
void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder )
{
devState = DEV_NWK_DISC;
ret = NLME_NetworkDiscoveryRequest( zgDefaultChannelList, zgDefaultStartingScanDuration );
……
}