ZCD_NV_LOGICAL_TYPE, sizeof(zgDeviceLogicalType), &zgDeviceLogicalType }, {
ZCD_NV_POLL_RATE, sizeof(zgPollRate), &zgPollRate }
..............................., }
在这个文件中我们还可以看到下面的这句话, // Device Logical Type
uint8 zgDeviceLogicalType = DEVICE_LOGICAL_TYPE; 前面我们也有看到
#if defined ( SOFT_START )
#define DEVICE_LOGICAL_TYPE ZG_DEVICETYPE_SOFT #define ZG_DEVICETYPE_SOFT 0x03
我们也可以看到在这个文件中的编译选项有 NV_INIT,并且在uint8 zgInit( void )函数中,对这个结构体数组进行了初始化。也就是说最后NV中的ZCD_NV_LOGICAL_TYPE条目被初始化了ZG_DEVICETYPE_SOFT值,所以if ( logicalType != ZG_DEVICETYPE_ENDDEVICE )判断不成功,执行下面的两条语句。也就是设置设备的逻辑类型为协调器,并且写入到ZCD_NV_LOGICAL_TYPE的条目中。
logicalType = ZG_DEVICETYPE_COORDINATOR;
zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType); 下面的语句就是语句就是写入了自动启动项,并且最后重新启动了系统。我们看一下重新启动后的流程
在void SAPI_Init( byte task_id )函数中触发ZB_ENTRY_EVENT事件,进入UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events )函数,对ZB_ENTRY_EVENT事件进行处理。 if ( events & ZB_ENTRY_EVENT ) {
uint8 startOptions;
// Give indication to application of device startup zb_HandleOsalEvent( ZB_ENTRY_EVENT );
// LED off cancels HOLD_AUTO_START blink set in the stack HalLedSet (HAL_LED_4, HAL_LED_MODE_OFF);
zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
if ( startOptions & ZCD_STARTOPT_AUTO_START )//这时这个判断就是成立的 {
zb_StartRequest(); } else {
// blink leds and wait for external input to config and restart HalLedBlink(HAL_LED_2, 0, 50, 500); }
return (events ^ ZB_ENTRY_EVENT ); }
判断成立的话,就会进入zb_StartRequest()函数。下面重点看一下zb_StartRequest() void zb_StartRequest() {
uint8 logicalType;
// Start the device
// start delay = min(NWK_START_DELAY, zgStartDelay) + rand() - only for fresh start, not restore
if ( zgStartDelay < NWK_START_DELAY ) zgStartDelay = 0; else
zgStartDelay -= NWK_START_DELAY;
/*check that bad combinations of compile flag definitions and device type 这时这里的ZCD_NV_LOGICAL_TYPE条目为ZG_DEVICETYPE_COORDINATOR #define ZG_DEVICETYPE_COORDINATOR 0x00(协调器) #define ZG_DEVICETYPE_ROUTER 0x01(路由器) #define ZG_DEVICETYPE_ENDDEVICE 0x02(终端) #define ZG_DEVICETYPE_SOFT 0x03(可选择类型)*/ zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8),
&logicalType );
if ( ( logicalType > ZG_DEVICETYPE_ENDDEVICE ) || #if defined( RTR_NWK )
#if defined( ZDO_COORDINATOR ) // Only RTR or Coord possible
( logicalType == ZG_DEVICETYPE_ENDDEVICE ) || #else
// Only RTR possible
( logicalType != ZG_DEVICETYPE_ROUTER ) || #endif #else
#if defined( ZDO_COORDINATOR ) // Error
( 1 ) || #else
// only ED possible
( logicalType != ZG_DEVICETYPE_ENDDEVICE ) || #endif #endif ( 0 ) ) {
// error configuration
SAPI_SendCback( SAPICB_START_CNF, ZInvalidParameter, 0 ); } else {
ZDOInitDevice(zgStartDelay); }
return; }
经过一系列的错误检测,可以得出上面的if分支不成立,会执行else分支也就是ZDOInitDevice(zgStartDelay);函数。这个函数,在上面的文章中也有分析到,这个函数中就分了NV_RESTORE编译选项的定义与否,由于这里没有定义这个选项,所以会直接执行ZDAppDetermineDeviceType();。 uint8 ZDOInitDevice( uint16 startDelay ) {
uint8 networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE; uint16 extendedDelay = 0;
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 )
return ( ZDO_INITDEV_LEAVE_NOT_STARTED ); // Don't join - (one time).
#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(); } #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 device security
ZDApp_SecInit( networkStateNV );
// Trigger the network start
ZDApp_NetworkInit( extendedDelay );
return ( networkStateNV );
}
在ZDAppDetermineDeviceType();函数中,对设备进行了判断。 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 )