下面看一下终端结点的不同之处,下面这个图是终端结点的的编译选项,这里我们可以看到没有了编译选项SOFT_START。这里我们重点看一下不同之处。
#if defined( ZDO_COORDINATOR ) && !defined( SOFT_START )
// Set the default to coodinator
devStartModes_t devStartMode = MODE_HARD;
#else
devStartModes_t devStartMode = MODE_JOIN; // Assume joining
//devStartModes_t devStartMode = MODE_RESUME; // if already "directly joined"
// to parent. Set to make the device do an Orphan scan.
#endif
// Device Logical Type
uint8 zgDeviceLogicalType = DEVICE_LOGICAL_TYPE;
#if defined ( SOFT_START )
#define DEVICE_LOGICAL_TYPE ZG_DEVICETYPE_SOFT
#elif defined( ZDO_COORDINATOR )
#define DEVICE_LOGICAL_TYPE ZG_DEVICETYPE_COORDINATOR
#elif defined (RTR_NWK)
#define DEVICE_LOGICAL_TYPE ZG_DEVICETYPE_ROUTER
#else
#define DEVICE_LOGICAL_TYPE ZG_DEVICETYPE_ENDDEVICE
#endif
最后得出
zgDeviceLogicalType = DEVICE_LOGICAL_TYPE =ZG_DEVICETYPE_ENDDEVICE
这里主要的不同还是在应用程序中的按键部分,下面是按键的程序,这个是在SimpleSwitch.c中
void zb_HandleKeys( uint8 shift, uint8 keys )
{
uint8 startOptions;
uint8 logicalType;
// Shift is used to make each button/switch dual purpose.
if ( shift )
{
if ( keys & HAL_KEY_SW_1 )
{
}
if ( keys & HAL_KEY_SW_2 )
{
}
if ( keys & HAL_KEY_SW_3 )
{
}
if ( keys & HAL_KEY_SW_4 )
{
}
}
else
{
if ( keys & HAL_KEY_SW_1 )
{
if ( myAppState == APP_INIT )
{
// In the init state, keys are used to indicate the logical mode.
// The Switch device is always an end-device 在这里当按下S1按键时设置为终端设备
logicalType = ZG_DEVICETYPE_ENDDEVICE;
zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
// Do more configuration if necessary and then restart device with auto-start bit set
zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
startOptions = ZCD_STARTOPT_AUTO_START;
zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
zb_SystemReset();
}
else
{
// Initiate a binding with null destination
zb_BindDevice(TRUE, TOGGLE_LIGHT_CMD_ID, NULL);
}
}
if ( keys & HAL_KEY_SW_2 )
{
if ( myAppState == APP_INIT )
{
// In the init state, keys are used to indicate the logical mode.
// The Switch device is always an end-device按键SW2和SW1的作用是一样的,都是设置为终端设备,这里也和协调器和路由器稍微有点不同
logicalType = ZG_DEVICETYPE_ENDDEVICE;
zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
startOptions = ZCD_STARTOPT_AUTO_START;
zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
zb_SystemReset();
}
else
{
// Send the command to toggle light
zb_SendDataRequest( 0xFFFE, TOGGLE_LIGHT_CMD_ID, 0,
(uint8 *)NULL, myAppSeqNumber, 0, 0 );
}
}
if ( keys & HAL_KEY_SW_3 )
{
// Remove all existing bindings
zb_BindDevice(FALSE, TOGGLE_LIGHT_CMD_ID, NULL);
}
if ( keys & HAL_KEY_SW_4 )
{
}
}
}
从上面可以看出KEY1 KEY2都是作为终端设备的。而在函数中也并没有改变上面的变量的类型。下面的这个函数,在函数uint8 ZDOInitDevice( uint16 startDelay )调用的,上面在分析协调器的时,也有看到,这个函数在这里就直接返回,并没有起到什么作用。
void ZDAppDetermineDeviceType( void )
{
if ( zgDeviceLogicalType == ZG_DEVICETYPE_ENDDEVICE )
return;
#if defined ( SOFT_START )
if ( zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR )
{
devStartMode = MODE_HARD; // Start as a coordinator
ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_COORDINATOR;
}
else
{
if ( zgDeviceLogicalType == ZG_DEVICETYPE_ROUTER )
{
softStartAllowCoord = FALSE; // Don't allow coord to start
continueJoining = TRUE;
}
devStartMode = MODE_JOIN; // Assume joining
}
#endif // SOFT_START
}
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()函数中可以根据不同的选项来进行操作。
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 )
{
devState = DEV_COORD_STARTING; //调用网络的格式化函数形成网络
ret = NLME_NetworkFormationRequest( zgConfigPANID, zgDefaultChannelList,
zgDefaultStartingScanDuration, beaconOrder,
superframeOrder, false );
}
else if ( startMode == 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" );
#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;
#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 )
{
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" );
#endif
}
}
#endif //!ZDO COORDINATOR || SOFT_START
if ( ret != ZSuccess )
osal_start_timerEx(ZDAppTaskID, ZDO_NETWORK_INIT, NWK_RETRY_DELAY );
}
在终端的结点时,就会执行蓝色的代码。至此,在程序中设备类型就确定了。这样整个工程中的三个设备就可以确定,并按照设定的方式来加入网络,或者形成网络了。