1. 程式人生 > >【深度分析Zigbee】Zstack協議棧初窺(六):協調器的組網過程詳解

【深度分析Zigbee】Zstack協議棧初窺(六):協調器的組網過程詳解

這一講我要詳細說一下協調器的組網過程。在Zstack中,網路組網是從ZDApp_Init函式開始的。具體的執行流程為:Main()->osal_init_system()->osalInitTasks()->ZDApp_In

it()。進入到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; //0xFFFE
  (void)NLME_GetExtAddr();  // Load the saveExtAddr pointer.

  // Check for manual"Hold Auto Start"
  //

檢測到有手工設定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

  // set broadcast address mask to support broadcast filtering
  NLME_GetRequest(nwkCapabilityInfo, 0, &capabilities);
  NLME_SetBroadcastFilter( capabilities );

  // 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首先檢測SW1是否被按下,如果SW1被按下,裝置將處於DEV_HOLD狀態,不會進入組網狀態,這裡我們要特別注意。如果SW1沒有被按下,那麼程式將呼叫ZDOInitDevice來開啟裝置。

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();

  //devtag.071807.todo - fix this temporary solution

  _NIB.CapabilityFlags = ZDO_Config_Node_Descriptor.CapabilityFlags;

#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();

    // clear NWK key values

    ZDSecMgrClearNVKeyValues();

  }

#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 );

  if( ZDO_INIT_HOLD_NWK_START != startDelay )

  {

    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 "new" join.

      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).

    }

    // Trigger the network start

    ZDApp_NetworkInit( extendedDelay );

  }

  // set broadcast address mask to support broadcast filtering

  NLME_SetBroadcastFilter( ZDO_Config_Node_Descriptor.CapabilityFlags );

  return ( networkStateNV );

}

在這個函式中有一段程式碼值得我們特別注意:

#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;

。。。

#endif

我們在以前的文章裡曾提到過,裝置在復位之後,之前的網路資訊就會丟失,那麼裝置將以全新的狀態組建或者加入到網路中,這在實際使用過程中非常不方便。很多的應用場景中都要求裝置能夠在復位後仍舊按照上次入網的狀態重新連線到網路中,Zstack也提供了實現該機制的方法。在工程的Options->C/C++ Complier->Preprocessor的Defined symbols中我們填入:NV_RESTORE。再回到剛才說到的程式碼中,程式會呼叫HalKeyRead(),來判斷SW5的狀態。如果SW5沒有被按下,程式會呼叫ZDApp_RestoreNetworkState,取出上一次儲存在flash中的網路狀態資訊,裝置將根據這些資訊重新連線到網路中;如果SW5被按下,那麼即便我們使用了NV_RESTORE,程式將呼叫NLME_InitNV()和NLME_SetDefaultNV(),清除之前儲存的網路資訊,然後以全新的狀態加入網路中。在完成以上操作之後,程式會呼叫ZDApp_NetworkInit函式,觸發ZDO_NETWORK_INIT事件。

void ZDApp_NetworkInit( uint16 delay )

{

  if ( delay )

  {

    // Wait awhile before starting the device

    osal_start_timerEx( ZDAppTaskID, ZDO_NETWORK_INIT, delay );

  }

  else

  {

    osal_set_event( ZDAppTaskID, ZDO_NETWORK_INIT );

  }

}

相關推薦

深度分析ZigbeeZstack協議協調組網過程

這一講我要詳細說一下協調器的組網過程。在Zstack中,網路組網是從ZDApp_Init函式開始的。具體的執行流程為:Main()->osal_init_system()->osalInitTasks()->ZDApp_In it()。進入到ZDApp_I

SSH之旅一步步學習Hibernate框架關於持久化

stc localhost 對象 schema hbm.xml java let pass [] 在不引用不論什麽框架下,我們會通過平庸的代碼不停的對數據庫進行操作,產生了非常多冗余的可是又有規律的底層代碼,這樣頻繁的操作數據庫和大量的底層代碼的反復

視訊Kubernetes1.12從零開始從程式碼編譯到自動部署

作者: 李佶澳   轉載請保留:原文地址   釋出時間:2018/11/10 16:14:00 說明 kubefromscratch-ansible和kubefromscratch介紹 使用前準備

linuxValgrind工具集Memcheck命令列引數

【linux】Valgrind工具集詳解(五):命令列詳解中不夠全,在此專門針對Memcheck工具中的命令列引數做一次詳細的解釋。 Memcheck命令列選項 –leak-check=<no|summary|yes|full> [default: summary]

Spring官網教程閱讀筆記訪問Twitter

此時,Twitter會詢問是否允許樣例應用讀取你的推文檢視你的關注人。這裡,螢幕上的顯示有些誤導,因為此時的應用只會讀取你的資訊已經你關注人的資訊。點選Authorize app獲取上述訪問許可權。 一旦獲取了許可權,Twitter重定向瀏覽器到應用。此時連線建立,該連線儲存在連線倉庫中。此時應該可以看見頁

深度學習基於caffe的表情識別在Intel AI DevCloud上訓練模型

一、註冊申請Intel AI DevCloud   2.填寫註冊資訊:   3.Submit提交,提交後會出現下面的介面:   4.說明已經申請成功了,大概等2個工作日左右,會收到一封郵件,郵件長這樣:   第一個紅框內的連結是使用教程,教你怎麼連線到dev

2008/1/31 OSIP協議使用入門續一協議邏輯分析

http://mbstudio.spaces.live.com/blog/cns!C898C3C40396DC11!2860.entry 2008/1/31OSIP協議棧使用入門(續一:純協議棧邏輯分析)  (CopyLeft by Meineson | www.mbstu

SVM入門線性分類的求解——問題的轉化,直觀角度

content cli 樣本 image ges 五個 是你 角度 spa SVM入門(六)線性分類器的求解——問題的轉化,直觀角度 讓我再一次比較完整的重復一下我們要解決的問題:我們有屬於兩個類別的樣本點(並不限定這些點在二維空間中)若幹,如圖, 圓形的樣本點定為正樣

Selenium-WebDriver自學Selenium-IDE測試創建

html 位置 當我 模塊 mage baidu 用例 問題 測試 =======================================================================================================

計算機網絡基礎數據鏈路層目錄

計算機網絡 劃分 靜態 控制 網橋 透明 回退 csma/cd 廣播 數據鏈路層知識結構 數據鏈路層組幀和透明傳輸 數據鏈路層差錯檢驗 奇偶校驗 循環冗余校驗(CRC) 海明碼 數據鏈路層可靠傳輸(ARQ協議) 停止-等待協議 回退N幀協議(GBN協議) 選擇重傳協

Win 10 應用開發UI Composition 劄記動畫

onclick 相對 行修改 log review asset 是你 express iteration 動畫在 XAML 中也有,而且基本上與 WPF 中的用法一樣。不過,在 UWP 中,動畫還有一種表現方式—— 通過 UI Composition

201803182018北京集訓測試賽

sum cnblogs 中間 com phi gpo 但是 分享圖片 problem 菜雞滾回石家莊了233 Problem B: 求和 題解&反思: 好久沒寫反演了真刺激 大力推公式就好咯 \[ \sum_{i=1}^{n}\sum_{j=1}^{i}\sum_

讀書筆記——《代碼大全》

variable 數據 borde 代碼 In 自然 dex ont 列表 The Power of Variable Names 摘錄與總結一些有用的東西。 語義前綴 語義前綴 含義 c 數量(count,如記錄、字符或者其他東西的個數)

golang-GUI開發qt之signal和slot

類型 取消 htm return 所在 turn hang nbsp type 想了很久,我決定還是先從signal和slot(信號槽)開始講起。 signal和slot大家一定不陌生,先看一段示例(選自文檔): 1 class Counter : public QOb

USACO 2004 DEC網絡破壞Tree CuttingDFS

pre nbsp \n printf 整數 back push_back sca 如果 題目描述 約翰意識到貝茜建設網絡花費了他巨額的經費,就把她解雇了.貝茜很憤怒,打算狠狠報 復.她打算破壞剛建成的約翰的網絡. 約翰的網絡是樹形的,連接著N(1≤N≤

Django Series - 05基於 "xlsxwriter + BytesIO"Python3生成 Excel 報表 ||| Python2 StringIO.StringIO()

Django Series(Django2.1.2 + Anaconda3) (一)安裝並配置 Django 環境 ||| 基於 Django 進行 Web 開發 (二)Django 基礎知識:語法、教程 (三)使用者管理模組:建立使用者、登入、退出 (四)資料的增刪改:使用者提交資

移動開發關於一對一視訊交友技術原始碼現代播放原理

在上一篇延遲優化中,我們分享了不少簡單實用的調優技巧。本篇是《一對一視訊直播技術詳解》系列之六:現代播放器原理。 近年來,多平臺適配需求的增長導致了流媒體自適應位元速率播放的興起,這迫使 Web 和移動開發者們必須重新思考視訊技術的相關邏輯。首先,巨頭們分分發布了 HLS、HDS 和 Smooth Stre

活動報名NEO 區塊鏈公開課1 NEO 區塊鏈開發入門

NEO 區塊鏈公開課是 NGD ( NEO Global Development )、NEL ( NewEconoLab )、InnoSpace 創新院共同發起的區塊鏈技術學習專場活動。旨在滿足廣大開發者對 NEO 區塊鏈技術的入門、進階以及技能提升需求。 精心設計的課程內容,資深技術講師

活動預告NEO區塊鏈公開課5NNS系統設計與實現

NEO區塊鏈公開課第5期: 主題:NEL精品課程之NNS系統設計與實現 時間:10月20日13:30—17:00   地點:上海市楊浦區政學路77號INNOSPACE 1樓IPOCLUB   報名連結:http://www.huodongxing.c

linuxValgrind工具集使用Valgrind gdbserver和GDB除錯程式

一、概述 在Valgrind下執行的程式不是由CPU直接執行的。相反,它執行在Valgrind提供的合成CPU上。這就是偵錯程式在Valgrind上執行時無法除錯程式的原因。 二、快速入門 在使用Memcheck工具時使用GDB除錯程式,啟動方式如下: 1、valgrind