图1 协调器的编译选项的配置
还是在ZDApp.c文件中,有下面的代码: #if defined( HOLD_AUTO_START ) devStates_t devState = DEV_HOLD; #else
devStates_t devState = DEV_INIT; #endif
#if defined( ZDO_COORDINATOR ) && !defined( SOFT_START )
//定义了ZDO_COORDINATOR,没有定义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 \
// to parent. Set to make the device do an Orphan scan.
#endif
在协调器中定义了编译选项非自动启动模式HOLD_AUTO_START和软启动模式SOFT_START,这里可以得知各个选项的值:devStates_t devState = DEV_HOLD; devStartModes_t devStartMode = MODE_JOIN;在Zglobals.h文件中可以看到。 #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
// Values for ZCD_NV_LOGICAL_TYPE (zgDeviceLogicalType) #define ZG_DEVICETYPE_COORDINATOR 0x00 #define ZG_DEVICETYPE_ROUTER 0x01 #define ZG_DEVICETYPE_ENDDEVICE 0x02 #define ZG_DEVICETYPE_SOFT 0x03
在AF.h文件中,
// Node Logical Types
#define NODETYPE_COORDINATOR 0x00 #define NODETYPE_ROUTER 0x01 #define NODETYPE_DEVICE 0x02 在ZDConfig.c文件中。
NodeDescriptorFormat_t ZDO_Config_Node_Descriptor = {
#if defined( ZDO_COORDINATOR ) && !defined( SOFT_START ) NODETYPE_COORDINATOR, #elif defined (RTR_NWK) NODETYPE_ROUTER, #else
NODETYPE_DEVICE, // Logical Type #endif
........ }
这些变量都会在下面的分析中展示其作用。我们可以看到这个协调器中各个变量的赋值是个什么情况,也就是加粗的部分。我们知道还要从ZDApp_Init()函数分析
void ZDApp_Init( byte task_id ) {
uint8 capabilities;
// Save the task ID ZDAppTaskID = task_id;
// Initialize the ZDO global device short address storage ZDAppNwkAddr.addrMode = Addr16Bit;
ZDAppNwkAddr.addr.shortAddr = INVALID_NODE_ADDR;
(void)NLME_GetExtAddr(); // Load the saveExtAddr pointer. 加载IEEE地址
// Check for manual \
//打开电源时,检测到有手工设置SW_1则会设置devState = DEV_HOLD,从而不进行网络初始化
ZDAppCheckForHoldKey();
// Initialize ZDO items and setup the device - type of device to create.
ZDO_Init(); //初始化ZDO条目,并设置设备的启动方式是协调器,还是别的
// 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 );
#if defined( ZDO_USERDESC_RESPONSE ) ZDApp_InitUserDesc();
#endif // ZDO_USERDESC_RESPONSE
// set broadcast address mask to support broadcast filtering NLME_GetRequest(nwkCapabilityInfo, 0, &capabilities); NLME_SetBroadcastFilter( capabilities );
// Start the device? 是否启动设备?如果devState不是DEV_HOLD时,则启动设备,在上面的代码分析中,也可以看到,如果定义了HOLD_AUTO_START宏,则devState等于DEV_HOLD,不会启动设备。如果按下了SW_1键devState也等于DEV_HOLD,也不会启动网络。也就是说有两种方式可以设置非自动启动模式,一种是通过按键,一种通过宏定义 if ( devState != DEV_HOLD ) {
ZDOInitDevice( 0 ); //在本例程中没有定义HOLD_AUTO_START所以这个会成功执行 } else {
//如果定义了HOLD_AUTO_START,则等待延时或外部事件启动网络,并且LED4灯,也就是蓝色的灯闪烁
// Blink LED to indicate HOLD_START HalLedBlink ( HAL_LED_4, 0, 50, 500 ); }
ZDApp_RegisterCBs(); } /* ZDO_Init() */
我们首先看一下ZDO_Init( void )函数
void ZDO_Init( void ) {
// Initialize ZD items
#if defined ( REFLECTOR ) ZDO_EDBind = NULL; #endif
// Setup the device - type of device to create. ZDODeviceSetup(); }
static void ZDODeviceSetup( void ) {
#if defined( ZDO_COORDINATOR ) NLME_CoordinatorInit(); //这个函数执行 #endif
#if defined ( REFLECTOR )//源绑定操作 #if defined ( ZDO_COORDINATOR )
APS_ReflectorInit( APS_REFLECTOR_PUBLIC );//这个函数执行 #else
APS_ReflectorInit( APS_REFLECTOR_PRIVATE ); #endif #endif
#if !defined( ZDO_COORDINATOR ) || defined( SOFT_START ) NLME_DeviceJoiningInit(); #endif }
从上面的分析可知,由于编译了HOLD_AUTO_START选项后,devState == DEV_HOLD,所以不会进入ZDOInitDevice( 0 ); 函数,而是闪烁LED4,指示初始化设备。这时就应该到应用程序来处理的,决定来初始化为协调器,还是路由器了。
void SAPI_Init( byte task_id ) {
.............................................. if ( HalKeyRead () == HAL_KEY_SW_5) {