当前位置:
文档之家› ZStack协议栈结构的初步解析
ZStack协议栈结构的初步解析
InitBoard( OB_READY ); // Display information about this device(显示设备信息,比如
CollectorEB 板的 IEEE 地址就是在这个函数里面显示出来的。)
zmain_dev_info(); /* Display the device info on the LCD */(显示 LCD 设备信息)
用 DEMo 来讲,上述的 SAPI_ProcessEvent()函数在 SAPI.c 中实
现如下:
UINT16 SAPI_ProcessEvent( byte task_id, UINT16 events ) {
osal_event_hdr_t *pMsg; afIncomingMSGPacket_t *pMSGpkt; afDataConfirm_t *pDataConfirm;
//更新时间
Leabharlann Baidu
Hal_ProcessPoll(); // This replaces MT_SerialPoll() and osal_check_timer().(轮询 UART 和 Timer 等设备消息)
do { if (tasksEvents[idx]) // Task is highest priority that is ready.
break; ... // Return unprocessed events
return (events ^ SYS_EVENT_MSG); }
if ( events & ZB_ALLOW_BIND_TIMER ) //ZB_ALLOW_BIND_TIMER
{ afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE); return (events ^ ZB_ALLOW_BIND_TIMER);
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 ); } // This must be the last event to be processed if ( events & ( ZB_USER_EVENTS ) ) { // User events are passed to the application #if ( SAPI_CB_FUNC ) zb_HandleOsalEvent( events ); #endif // Do not return here, return 0 later }
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 ) //Joystick Up key (Set as
void zb_HandleKeys( uint8 shift, uint8 keys ) {
static uint8 allowBind=FALSE; static uint8 allowJoin=TRUE; uint8 logicalType;
// Shift is used to make each button/switch dual purpose. if ( shift ) {
enough to run(电压检查) zmain_vdd_check(); // Initialize board I/O(初始化 I/O 接口) InitBoard( OB_COLD ); // Initialze HAL drivers(初始化 HAL 设备,在 hal_drivers.c 中实现) HalDriverInit(); // Initialize NV System(初始化 NV 系统,即非易失设备,如 Flash) osal_nv_init( NULL ); // Initialize the MAC(初始化 MAC) ZMacInit(); // Determine the extended address(确定设备的长地址) zmain_ext_addr(); // Initialize basic NV items(初始化 ZStack 的全局变量,如果在 NV 内
events = (tasksArr[idx])( idx, events );
//处
理当前要处理的事件,并返回事件 ID
HAL_ENTER_CRITICAL_SECTION(intState); tasksEvents[idx] |= events; // Add back unprocessed events
NWK, Hal, APS, ZDAPP 的事件处理函数。以 macEventLoop 为例,可
以在 mac_api.h 文件中找到这个函数的定义如下:
extern uint16 macEventLoop(uint8 taskId, uint16 events); 但是,没有跟踪到上述函数的实现在哪个文件中。但是对于温度监测应
to the current task.(更新事件状态)
HAL_EXIT_CRITICAL_SECTION(intState); } #if defined( POWER_SAVING ) else // Complete pass through all task events with no activity? {
osal_start_system(); // No Return from here(启动操作系统,实际上
进入一个死循环)
return 0; // Shouldn't get here. } // main() 说明:以上初始化有的跟硬件相关,有的跟操作系统(以 osal 开头)相关,
最后系统调用 osal_start_system 进入循环,然后在循环中处理消息,
下面是这个函数的主体(见 osal.c):
void osal_start_system( void ) { #if !defined ( ZBIT ) && !defined ( UBIT )
for(;;) // Forever Loop (死循环)
#endif { uint8 idx = 0;
osalTimeUpdate();
{ break;
} } while (++idx < tasksCnt); if (idx < tasksCnt) {
uint16 events; halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState);
//加锁防上访
问事件队列充突
events = tasksEvents[idx]; tasksEvents[idx] = 0; // Clear the Events for this task. HAL_EXIT_CRITICAL_SECTION(intState);
if ( events & SYS_EVENT_MSG )
//系统事件消息,只有
定义了 SAPI_CB_FUNC 的似乎才会被上层应用处理。
{ ...
case KEY_CHANGE: #if ( SAPI_CB_FUNC )
zb_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys ); #endif
} if ( events & ZB_BIND_TIMER ) //ZB_BIND_TIMER {
// Send bind confirm callback to application SAPI_BindConfirm( sapi_bindInProgress, ZB_TIMEOUT ); sapi_bindInProgress = 0xffff; return (events ^ ZB_BIND_TIMER); } if ( events & ZB_ENTRY_EVENT ) //ZB_ENTRY_EVENT { uint8 startOptions; // Give indication to application of device startup #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); zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions ); if ( startOptions & ZCD_STARTOPT_AUTO_START ) {
int main( void ) {
// Turn off interrupts(关中断) osal_int_disable( INTS_ALL ); // Initialization for board related stuff such as LEDs(初始化板上组
件,如 LED) HAL_BOARD_INIT(); // Make sure supply voltage is high
#ifdef LCD_SUPPORTED zmain_lcd_init();
#endif #ifdef WDT_IN_PM1
/* If WDT is used, this is a good place to enable it. */(开 WatchDog)
WatchDogEnable( WDTIMX ); #endif
// Discard unknown events return 0; }
上述代码中,只有黑色标注的才被上传到应用层 APL 进行处理,而这
些代码正好是用户需要实现的,分别在 DemoSensor.c 和
DemoCollector.c 中实现。以路由器的代码为例,显示如下,其作用主
要是对按键进行处理:
macEventLoop,
nwk_event_loop, Hal_ProcessEvent, #if defined( MT_TASK ) MT_ProcessEvent, #endif APS_event_loop, ZDApp_event_loop, SAPI_ProcessEvent }; 上面基本上是***EventLoop,可以推测是处理不同层的信息,如 mac,
#if OSAL_SAPI // The order in this table must be identical to the task initialization calls below inosalInitTask. const pTaskEventHandlerFn tasksArr[] = {
osal_pwrmgr_powerconserve(); // Put the processor/system
into sleep(没有事件处理,进入休眠状态)
} #endif
} }
需要特别解析的是上面红色标注的行,这个地方看起来象是一个函数指
针的形式,查看 taskArr 定义(见 SAPI.c)如下:
存中不存在,则写入缺省值) 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(最后初始化板)