-
ZigBee
协议栈初始化网络启动流程
p>
ZigBee
的基本流程:由协调器的组网(创建
< br>PAN ID
),终端设备和路由设备发现网络
以及加入
网络。
基本流程:
main()->
osal_init_system()->osalInitTasks()->ZDApp_Init()<
/p>
,进协议栈初始
化函数
ZDApp_In
it()
。
1.1
进入程序入口
main()
。
ZMain.c
中
C++ Code
int main( void )
{
//
Turn off interrupts
osal_int_disable( INTS_ALL );
// Initialization for
board related stuff such as LEDs
HAL_BOARD_INIT();
// Make sure supply voltage is high enough to run
zmain_vdd_check();
//
Initialize board I/O
InitBoard( OB_COLD );
// Initialze HAL drivers
HalDriverInit();
// Initialize NV System
osal_nv_init( NULL );
// Initialize the MAC
ZMacInit();
// Determine the extended address
zmain_ext_addr();
// Initialize basic NV items
zgInit();
#ifndef NONWK
// Since
the AF isn't a task, call it's initialization
routine
afInit();
#endif
// Initialize the
operating system
osal_init_system();
// Allow interrupts
osal_int_enable( INTS_ALL );
// Final board
initialization
InitBoard( OB_READY );
// Display information about this device
zmain_dev_info();
/* Display
the device info on the LCD */
#ifdef LCD_SUPPORTED
zmain_lcd_init();
#endif
#ifdef WDT_IN_PM1
/* If
WDT is used, this is a good place to enable it. */
WatchDogEnable( WDTIMX
);
#endif
osal_start_system(); //
No Return from here
return 0; // Shouldn't get here.
} // main()
1.2
给任务添加
ID
sapi.c
中
C++ Code
void osalInitTasks(
void ) //
为各自进程添加
ID
用于任务的查找
{
uint8 taskID = 0;
tasksEvents
= (uint16 *)osal_mem_alloc( sizeof( uint16 ) *
tasksCnt);
osal_memset(
tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
macTaskInit( taskID++ );
nwk_init( taskID++ );
Hal_Init( taskID++
);//
硬件抽象层初始化
#if defined( MT_TASK )
MT_TaskInit( taskID++ );
#endif
APS_Init(
taskID++ );
ZDApp_Init(
taskID++ );//
判断如果协调器节点建立网络、如果终端节点加入
网络
SAPI_Init( taskID );
}
1.3
初始化
ZigBee
协议栈网络
ZDApp.c
C++ Code
void ZDApp_Init(
uint8 task_id )
{
// Save the task ID
ZDAppTaskID = task_id;
// Initialize the ZDO global device short address
storage
de = Addr16Bit;
ddr =
INVALID_NODE_ADDR;
(void)NLME_GetExtAddr(); // Load the saveExtAddr
pointer.
//
Check for manual
//
检测到有手工设置
HAL_KEY_SW_1
则
会设置
devState = DEV_HOLD,
从
而避开网络初始化
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 );
#if
defined( ZDO_USERDESC_RESPONSE )
ZDApp_InitUserDesc();
#endif // ZDO_USERDESC_RESPONSE
// Start the device?
if ( devState !=
DEV_HOLD )
{
ZDOInitDevice(
0 );
}
else
{
// Blink LED to indicate HOLD_START
HalLedBlink ( HAL_LED_4, 0, 50, 500 );
}
ZDApp_RegisterCBs();
} /*
ZDApp_Init() */
如果设置
devState
为
DEV_HOLD
,则不会执行
p>
ZDOInitDevice
;反之,系统会调用此
函数是设备组网或者入网。看下这个函数完成的功能是什么样子的。
ZDOIn
itDevice
是
设备在网络中启动。
它会读取
NV
中的
ZCD_NV_S
TARTUP_OPTION
选项决定是否恢
复网络状态。如果
应用层强制进行新的
join
操作,它应该在调用这个函数之前
设置
ZCD_NV_STARTUP_OPTION
中的
ZCD_STARTOPT_DEFAULT_NETWORK_STATE
< br>位。可以调用
zgWrieStartupOptions()
< br>函数完成这些设置。
1.4
初始化设备(启动网络和设置网络类型)
ZDApp.c
C++ Code
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 );
}
ZDConfig_InitDescriptors();
// - fix this temporary solution
_lityInfo = ZDO_Config_Node_lityFlags;
devState = DEV_INIT; //
Remove the Hold state
//
函数读取
NV
项目
ZCD_NV_LEAVE_CTRL
的值
,ZDA
pp_LeaveCtrl
指向
这个值
// Initialize leave
control logic
ZDApp_LeaveCtrlInit();
// Check leave control reset settings//
设备的断开会造成
DEV_HOLD
状态
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
{
//
通过读取
ZCD_NV_STARTUP_OPTION
选项
决定是否进行网络恢复
// 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 the
security for type of device
ZDApp_SecInit( networkStateNV );
//
触发启动网络
// Trigger the network start
ZDApp_NetworkInit( extendedDelay );
// set broadcast
address mask to support broadcast filtering
用于处理合法
的广播地址
NLME_SetBroadcastFilter( ZDO_Config_Node_lityFlags
);
return ( networkStateNV );
}
p>
这个函数注意功能:
初始化设备配置,
ZD
AppDetermineDeviceType()
设置网络类型
(协
调、路由、终端),
ZDApp_NetworkIn
it( extendedDelay
)
初始化网络并开启或加入网
络。
1.5
定时开启网络
ZDApp.c
进入
ZDApp_N
etworkInit()
函数,
等待一段时间在执行
ZDO_NETWORK_INIT
,
跳入事<
/p>
件处理
ZDApp
层
ZDAPP_EVENT_LOOP()
函数开启网络。
C++ Code
void
ZDApp_NetworkInit( uint16 delay )
{
if ( delay )
{
// Wait awhile before starting the device
osal_start_timerEx( ZDAppTaskID, ZDO_NETWORK_INIT,
delay );
//
发送
ZDO_NETWORK_INIT
(网
络初始化)消息到
ZDApp
层,转
到
ZDApp
层,
ZDApp_eve
nt_loop()
函数。
}
else
{
osal_set_event( ZDAppTaskID, ZDO_NETWORK_INIT );
}
}
1.6
启动设备
ZDApp.c
ZDApp_event_loop()
p>
函数是回调函数,循环处理主事件。设备逻辑类型,启动模式,
信标
时间,超帧长度
C++ Code
-
-
-
-
-
-
-
-
-
上一篇:戴尔台式机BIOS详解
下一篇:DBXAFS240反馈抑制器设置步骤