今天来看一下终端节点是如何加入网络,以及建立绑定操作并发送数据了。首先我们选择工作空间为SimpleSensorEB ,好,我们先按一下S2键,因为在
SAPI_Init中,我们利用RegisterForKeys( sapi_TaskID );注册了键盘消息,因此我们看一下在sapi如何对按键消息进行响应的。在UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events )中找到:
case KEY_CHANGE: #if ( SAPI_CB_FUNC )
zb_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys ); #endif
break;
好,接下来我们进入到zb_HandleKeys函数中看看源代码: 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 Sensor device is always an end-device 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();
} }
if ( keys & HAL_KEY_SW_2 )//成立 {
if ( myAppState == APP_INIT )//成立 {
logicalType = ZG_DEVICETYPE_ENDDEVICE;//修改本地设备类型为终端设备
zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);//将设备类型写入到flash中
zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
startOptions = ZCD_STARTOPT_AUTO_START;//修改启动选项
zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );//将启动选项写入到flash中 zb_SystemReset();//系统重启 } } }
好,系统重启后,程序从头开始执行,在进行SAPI_Init函数的最后时,出现 osal_set_event(task_id, ZB_ENTRY_EVENT);因此,进入到进入事件处理函数当中。我们在SAPI_ProcessEvent函数里找到如下代码:
if ( events & ZB_ENTRY_EVENT ) {
uint8 startOptions; #if ( SAPI_CB_FUNC )
zb_HandleOsalEvent( ZB_ENTRY_EVENT ); #endif
// LED off cancels HOLD_AUTO_START blink set in the stack HalLedSet (HAL_LED_4, HAL_LED_MODE_OFF);//首先关闭LED_4。 zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );//从flash中读出启动选项
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 ); }
继续到启动请求函数中去看一下源代码:
void zb_StartRequest() {
uint8 logicalType;
zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
//以下代码主要是确认设备类型是否正确,可以判断if中的条件为0,执行else中的语句
if ((logicalType > ZG_DEVICETYPE_ENDDEVICE) ||
#if !ZG_BUILD_ENDDEVICE_TYPE // Only RTR or Coord possible.
(logicalType == ZG_DEVICETYPE_ENDDEVICE) || #endif
#if !ZG_BUILD_RTR_TYPE // Only End Device possible. (logicalType == ZG_DEVICETYPE_ROUTER) || (logicalType == ZG_DEVICETYPE_COORDINATOR) || #elif ZG_BUILD_RTRONLY_TYPE // Only RTR possible. (logicalType == ZG_DEVICETYPE_COORDINATOR) || #elif !ZG_BUILD_JOINING_TYPE // Only Coord possible. (logicalType == ZG_DEVICETYPE_ROUTER) || #endif
(0)) {
logicalType = ZB_INVALID_PARAMETER;
SAPI_SendCback(SAPICB_START_CNF, logicalType, 0); } else {
logicalType = ZB_SUCCESS;//设置本地设备类型为ZB_SUCCESS ZDOInitDevice(zgStartDelay);//执行ZDO初始化设备函数。 }
return; }
下面我们接着去初始化设备函数当中看一下源代码,可以找到:
uint8 ZDOInitDevice( uint16 startDelay ) {
uint8 networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE; //设置网络状态为初始化新的网络
uint16 extendedDelay = 0;
if ( devState == DEV_HOLD ) { // Initialize the RAM items table, in case an NV item has been updated. zgInitItems( FALSE ); //初始化RAM item列表 }
ZDConfig_InitDescriptors();
//devtag.071807.todo - fix this temporary solution
_NIB.CapabilityInfo = ZDO_Config_Node_Descriptor.CapabilityFlags;
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 \ 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). }
#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();