Zigbee網(wǎng)絡(luò)處理器應(yīng)用簡介

本文首先介紹Zigbee的若干基本概念,然后針對TI Zigbee解決方案中的Zigbee網(wǎng)絡(luò)處理器(ZNP)應(yīng)用形式,介紹如何創(chuàng)建一個(gè)Zigbee網(wǎng)絡(luò),并與已有的節(jié)點(diǎn)進(jìn)行通信。

基本概念

Zigbee

Zigbee是一種短距離、低速率、低功耗的無線傳感器網(wǎng)絡(luò)技術(shù),包含了從底層網(wǎng)絡(luò)到上層應(yīng)用的完整定義,標(biāo)準(zhǔn)由Zigbee聯(lián)盟制定,最新規(guī)格為Zigbee 3.0。
多個(gè)IC廠商提供包含Zigbee技術(shù)的產(chǎn)品,本文只討論TI的解決方案。

信道

Zigbee可以在Sub-1GHz、2.4GHz等多個(gè)頻率范圍工作,一般選擇在2.4GHz頻率范圍,這個(gè)范圍中又劃分出16個(gè)具體的頻點(diǎn)(信道),對應(yīng)編號(hào)從11(0x0B)到26(0x1A)。當(dāng)同一個(gè)或相鄰近的物理空間中有多個(gè)Zigbee網(wǎng)絡(luò)時(shí),需要錯(cuò)開信道。

設(shè)備類型

Zigbee網(wǎng)絡(luò)中的設(shè)備分為三種類型:協(xié)調(diào)器(Coordinator)、路由(Router)和終端節(jié)點(diǎn)(End Device)。其中,協(xié)調(diào)器負(fù)責(zé)建立網(wǎng)絡(luò),并為新加入的節(jié)點(diǎn)分配地址(當(dāng)網(wǎng)絡(luò)建立、節(jié)點(diǎn)入網(wǎng)后,即使去掉協(xié)調(diào)器,網(wǎng)絡(luò)也能正常工作);路由負(fù)責(zé)將收到數(shù)據(jù)轉(zhuǎn)發(fā)給其他節(jié)點(diǎn),以拓展網(wǎng)絡(luò)的覆蓋范圍;終端節(jié)點(diǎn)只能接收和發(fā)送自身的數(shù)據(jù),不能轉(zhuǎn)發(fā)。
需要說明的是:(1)路由本身也具有終端節(jié)點(diǎn)的功能,可以收發(fā)自身的數(shù)據(jù);(2)終端節(jié)點(diǎn)可以不依賴路由,直接通過協(xié)調(diào)器入網(wǎng)。所以,一個(gè)完整的Zigbee網(wǎng)絡(luò),可以沒有終端節(jié)點(diǎn),只有協(xié)調(diào)器和路由;也可以沒有路由,只有協(xié)調(diào)器和終端節(jié)點(diǎn)。

網(wǎng)絡(luò)地址

Zigbee設(shè)備在出廠時(shí)都有一個(gè)唯一的8字節(jié)MAC地址,但在加入網(wǎng)絡(luò)時(shí),會(huì)被協(xié)調(diào)器分配一個(gè)兩字節(jié)的網(wǎng)絡(luò)地址,后續(xù)以這個(gè)網(wǎng)絡(luò)地址通信。協(xié)調(diào)器的網(wǎng)絡(luò)地址是0x0000。0xFFFF是廣播地址,如果將通信的目的地址設(shè)為0xFFFF,那么所有節(jié)點(diǎn)都會(huì)收到。

PANID

PANID是Zigbee網(wǎng)絡(luò)的標(biāo)識(shí),即使同一信道里有多個(gè)Zigbee網(wǎng)絡(luò),只要它們的PANID不同,也可以共存并獨(dú)立工作。

Z-Stack

Z-Stack是TI的Zigbee協(xié)議棧,包含文檔、源代碼和預(yù)編譯的庫,可以從TI網(wǎng)站上下載。Z-Stack使用IAR編譯和調(diào)試,生成的hex文件通過燒寫器燒寫進(jìn)Zigbee芯片當(dāng)中。

ZNP

ZNP,即Zigbee網(wǎng)絡(luò)處理器,是TI的Zigbee解決方案的一種應(yīng)用形式。在這種形式下,Zigbee芯片只負(fù)責(zé)處理底層網(wǎng)絡(luò)的功能,而將上層應(yīng)用交給主機(jī)處理,ZNP與主機(jī)之間通過USB或UART連接。Zigbee芯片實(shí)現(xiàn)ZNP功能所需的固件及其源碼,以及接口API的說明都包含在Z-Stack中。所謂接口API,指主機(jī)通過USB或UART與ZNP通信的幀格式,以及命令和參數(shù)的定義。在主機(jī)側(cè),TI提供了對接口API的包裝,即znp-host-framework,C語言實(shí)現(xiàn),開源,代碼托管在TI的Git網(wǎng)站上,另外在GitHub上還有適用于Node.js的版本。

安全

Zigbee網(wǎng)絡(luò)支持安全加密機(jī)制,通信數(shù)據(jù)采集AES加密。密鑰的分發(fā)有兩種方法:一種是預(yù)先配置在所有需要加入網(wǎng)絡(luò)的節(jié)點(diǎn)上;另一種是只配置在協(xié)調(diào)器上,節(jié)點(diǎn)入網(wǎng)時(shí)分發(fā)到節(jié)點(diǎn)。

配置ZNP

TI有多款芯片可以用作ZNP,我們選擇CC2538,通過其自帶的USB接口連接主機(jī),硬件dongle可以從淘寶采購。對應(yīng)的工程文件在Z-Stack的Projects\zstack\ZNP\CC2538目錄當(dāng)中。
Z-Stack中默認(rèn)開啟了安全加密,可以通過修改代碼禁用:

Projects/zstack/Tools/CC2538DB/f8wConfig.cfg

21(修改宏定義): DSECURE=0

Components/stack/bdb/bdb_touchlink.h

50(注釋掉此行): //#error SECURE must be globally defined to TRUE.

如果按照TI提供的參考設(shè)計(jì),配置了CC2592作為PA,還需要使能它:

Components/hal/target/CC2538ZNP/hal_board_cfg.h

84(增加一行): #define HAL_PA_LNA_CC2592

使用ZNP創(chuàng)建網(wǎng)絡(luò)

將CC2538 USB dongle連接到主機(jī),就可以從主機(jī)上發(fā)命令控制它了。CC2538的USB接口是一個(gè)CDC設(shè)備,在Windows上無需安裝驅(qū)動(dòng),會(huì)被識(shí)別成一個(gè)串口;在Linux系統(tǒng)上,需要確保內(nèi)核包含USB CDC設(shè)備驅(qū)動(dòng),會(huì)被識(shí)別成/dev/ttyACMx(x是序號(hào),從0開始)。

Z-Tool

Z-Tool是Z-Stack附帶的一個(gè)測試工具,可以用它給ZNP發(fā)送指令。在安裝Z-Stack以后,在安裝目錄下找到Tools\Z-Tool\Z-Tool.exe,雙擊打開,它會(huì)自動(dòng)搜索并連接ZNP。

Z-Tool

如上圖所示,界面左上角是Z-Tool支持的各種命令,分為System、AF等多個(gè)類別。下面介紹使用這些命令控制ZNP創(chuàng)建網(wǎng)絡(luò)的步驟。

  1. 配置啟動(dòng)選項(xiàng),在下次復(fù)位前清除網(wǎng)絡(luò)狀態(tài)和所有配置

    命令:SimpleAPI/ZB_WRITE_CONFIGURATION
    參數(shù):ConfigId: 3(ZCD_NV_STARTUP_OPTION),Len: 1,Value: [3]

  2. 復(fù)位

    命令:SimpleAPI/ZB_SYSTEM_RESET

  3. 配置設(shè)備類型

    命令:SimpleAPI/ZB_WRITE_CONFIGURATION
    參數(shù):ConfigId: 135(ZCD_NV_LOGICAL_TYPE),Len: 1,Value: [0](協(xié)調(diào)器)

  4. 設(shè)置PANID

    命令:Util/UTIL_SET_PANID
    參數(shù):PanId: 6

  5. 設(shè)置信道(復(fù)位后生效)

    命令:Util/UTIL_SET_CHANNELS
    參數(shù):Channels: 0x00020000(即17信道,計(jì)算方法:1<<17 = 0x00020000)

  6. 設(shè)置信道(立即生效)

    命令:AppConfig/APP_CNF_BDB_SET_CHANNEL
    參數(shù):isPrimary: TRUE, Channels: 0x00020000(計(jì)算方法同上一條命令)

  7. 注冊應(yīng)用程序(對于創(chuàng)建網(wǎng)絡(luò)來說,這一步不是必需的,但后面收發(fā)數(shù)據(jù)需要)

    命令:AF/AF_REGISTER
    參數(shù):
    EndPoint: 11
    AppProfID: 3845
    AppDeviceId: 256
    AppDevVer: 0
    LatencyReq: 0
    AppNumInClusters: 1
    AppInClusterList: [1]
    AppNumOutClusters: 1
    AppOutClusterList: [1]

  8. 啟動(dòng)網(wǎng)絡(luò)

    命令:ZDO/ZDO_STARTUP_FROM_APP

  9. 配置啟動(dòng)選項(xiàng),在下次復(fù)位后保持網(wǎng)絡(luò)狀態(tài)和配置

    命令:ZB_WRITE_CONFIGURATION
    參數(shù):ConfigId: 3(ZCD_NV_STARTUP_OPTION),Len: 1, Value: 0

Node.js

以上步驟可以通過Node.js腳本實(shí)現(xiàn):

const znp = require('cc-znp')
znp.request('SAPI', 'writeConfiguration', {
            configid: 3,
            len: 1,
            value: [0x03]
        })
znp.request('SAPI', 'systemReset', {})
znp.request('SAPI', 'writeConfiguration', {
                configid: 0x87,
                len: 1,
                value: [0] //coordinator
            })
znp.request('UTIL', 'setPanid', {
                panid: 6
            })
znp.request('UTIL', 'setChannels', {
                channels: 0x00020000
            })
znp.sendCmd(1, 'RPC_SYS_DEBUG', 0x08, new Buffer([1, 0, 0, 2, 0]))
znp.request('AF', 'register', {
                endpoint: 0x0B, 
                appprofid: 0xF05, 
                appdeviceid: 0x100, 
                appdevver: 0, 
                latencyreq: 0, 
                appnuminclusters: 1, 
                appinclusterlist: [1], 
                appnumoutclusters: 1, 
                appoutclusterlist: [1] 
            })
znp.request('ZDO', 'startupFromApp', {
                startdelay: 0
            }
znp.request('SAPI', 'writeConfiguration', {
            configid: 3,
            len: 1,
            value: [0]
        })

發(fā)送數(shù)據(jù)(待發(fā)送的數(shù)據(jù)放在buffer變量中):

znp.request('AF', 'dataRequest', {
                dstaddr: 0xFFFF,
                destendpoint: 0x0B,
                srcendpoint: 0x0B,
                clusterid: 0x0001,
                transid: 1,
                options: 0,
                radius: 0x7,
                len: buffer.length,
                data: buffer
            })

接收數(shù)據(jù):

znp.on('AREQ', function (msg) {
    if(msg.ind === 'incomingMsg') {
        var srcaddr = msg.data.srcaddr;
        var data = msg.data.data;
    }
});

C語言

在Linux上,可以使用TI提供的znp-host-framework來操作ZNP。其中提供了一個(gè)cmdLine例程,可以在命令行中交互式地設(shè)置創(chuàng)建網(wǎng)絡(luò)的參數(shù),主要步驟與上文大體一致,缺少了AppConfig/APP_CNF_BDB_SET_CHANNEL這條命令(設(shè)置信道并立即生效),可以自行添加:

/*
 * mtAppCnf.c
 *
 * This module contains the API for the MT App Config Interface
 *
 */
#include <stdlib.h>
#include <string.h>
#include "mtAppCnf.h"
#include "mtParser.h"
#include "rpc.h"
#include "dbgPrint.h"

extern uint8_t srspRpcBuff[RPC_MAX_LEN];

uint8_t appCnfBdbSetChannel(mtBdbSetChannelFormat_t *req)
{
    uint8_t status;
    uint8_t cmInd = 0;
    uint32_t cmdLen = 5;
    uint8_t *cmd = malloc(cmdLen);

    if (cmd)
    {
        cmd[cmInd++] = req->isPrimary;
        memcpy((cmd + cmInd), req->channelMask, 4);
        cmInd += 4;

        status = rpcSendFrame((MT_RPC_CMD_SREQ | MT_RPC_SYS_APP_CNF),
        MT_APP_CNF_BDB_SET_CHANNEL, cmd, cmdLen);

        if (status == MT_RPC_SUCCESS)
        {
            rpcWaitMqClientMsg(50);
            status = srspRpcBuff[2];
        }

        free(cmd);
        return status;
    }
    else
    {
        dbg_print(PRINT_LEVEL_WARNING, "Memory for cmd was not allocated\n");
        return 1;
    }
}

TODO

  • 新節(jié)點(diǎn)入網(wǎng):需要在Zigbee協(xié)調(diào)器上控制是否允許新節(jié)點(diǎn)入網(wǎng)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容