ZStack

一些参考 :
http://wjf88223.blog.163.com/blog/static/351680012011731105424480/
http://blog.csdn.net/tanqiuwei/article/details/7640913

前言

这片文章总结一下学习ZStack自带例子的过程。这些例子位于ZStack的安装目录中,如:
D:\Texas Instruments\ZStack-CC2530-2.5.1a\Projects\zstack\Samples
此外,安装路径下有自带的帮助文档,位于:
D:\Texas Instruments\ZStack-CC2530-2.5.1a\Documents
这些文档对于学习ZStack很有帮助。

在这里总结一些预备知识。来源是自带文档《Z-Stack Developer’s Guide》

  • Device Type: 即设备类型,包括:
    • 协调器 Coordinator : 负责创建一个网络:选择一个Channel和一个网络ID(PAN ID-Personal Area Network),然后启动这个网络。默认的Channel是2.4 GHz,PAN ID可以在配置文件中指定。注意:协调器用来配置并启动一个网络,之后协调器角色转化为Router。
    • 路由器 Router
      • 帮助其他设备加入网络
      • multi-hop routing (多跳路由?)
      • 负责终端设备之间的“交流”
    • 终端设备 End Device:可以加入一个网络
  • Stack Profile :配置文件,在工程的workspace下可以选择当前的设备类型,当选择CoordinatorEB时,f8wCoord.cfg会被使用。
    • 配置文件位于工程的Tools目录下,
      • f8wconfig.cfg 共享的配置文件,可以配置channel,PAN ID(即网络ID)
      • f8wCoord.cfg 协调器的配置文件
      • f8wEnddev.cfg 终端设备的配置文件
      • f8wRouter.cfg 路由器的配置文件
  • Addressing : 寻址,地址类型包含如下两种
    • 64-bit IEEE address : 即MAC地址
    • 16-bit network address : 16比特的网络地址,也叫逻辑地址或短地址。当一个设备加入一个网络时,会给该设备分配一个地址,在该网络中,这个地址是唯一的,用来标识该设备,从而用于发送数据等操作。

地址分配策略:

  • Tree Addressing,树形地址结构。一个设备通过它的父节点获得一个唯一的网络地址。与地址相关的参数有:
    • MAX_DEPTH 定义了网络的深度depth,协调器的depth是0, 它的子节点的depth是1,以此类推。
    • MAX_CHILDREN 定义了一个router节点的子节点个数的最大值。
    • MAX_ROUTERS 定义了一个coordinator或router所拥有的router的最大个数,MAX_CHILDREN – MAX_ROUTERS则表示拥有的终端节点的个数。
  • Stochastic Addressing 随机地址分配,随机分配设备地址。会发生地址冲突(address confilict)。

Z-Stack中的地址:
发送数据使用函数AF_DataRequest(), 参考《Z-Stack API》,函数原型为:

afStatus_t AF_DataRequest( 
    afAddrType_t *dstAddr, // 目的地址
    endPointDesc_t *srcEP, // 源地址
    uint16 cID, // Cluster ID ,the message’s cluster ID is likea message ID and is unique with in 
the profile. 
    uint16 len, // 要发送的数据的长度
    uint8 *buf, // 指向发送数据的地址
    uint8 *transID, //transaction sequence number pointer. This number will be incremented by 
this function if the message is buffered to be sent.
    uint8 options, 
    uint8 radius // 跳数 : Maximum number of hops
    );

其中afAddrType_t用来表示一个设备的网络地址。

typedef enum
{
  afAddrNotPresent = AddrNotPresent, // ? indiret , binding table...
  afAddr16Bit      = Addr16Bit, // 用于单播
  afAddr64Bit      = Addr64Bit,
  afAddrGroup      = AddrGroup,  // 用于多播
  afAddrBroadcast  = AddrBroadcast // 用于广播
} afAddrMode_t;

typedef struct
{
  union
  {
    uint16      shortAddr; // 上面提到的16bit的网络地址
    ZLongAddr_t extAddr;
  } addr;
  afAddrMode_t addrMode; // 用单播、广播或多播
  uint8 endPoint;
  uint16 panId;  // used for the INTER_PAN feature
} afAddrType_t;

其中addrMode用来做什么呢? ZigBee中的网络包可以单播、多播、广播,addrMode用于不同的模式。

  • 单播
  • Indirect:当应用层不知道一个packege的最终地址,addrMode设置为AddrNotPresent,在发送设备协议栈中的“binding table”中查找目的地址。
  • 广播:想要广播时,addrMode设置为AddrBroadcast,可以将shortAddr设置为下面的值:
    • NWK_BROADCAST_SHORTADDR_DEVALL (0xFFFF) 发送给所有设备,包括在sleeping的设备
    • NWK_BROADCAST_SHORTADDR_DEVRXON (0xFFFD) 不发给sleeping的设备
    • NWK_BROADCAST_SHORTADDR_DEVZCZR (0xFFFC) 发送给所有router,包括coordinator
  • 多播:此模式下,addrMode设置为afAddrGroup,将shortAddr设置为group identifier。但是首先需要添加一个组。(see aps_AddGroup() in the Z-Stack API doc)
  • -

一些与地址相关的API

  • NLME_GetShortAddr() 返回设备的16bit网络地址
  • NLME_GetCoordShortAddr() 返回父节点的16bit网络地址

Todo:
Bind…
Routing…
binding table, routing table, neighbor table…

GenericApp

实验的主要过程:一个协调器,一个终端节点。
按键:

  • SW4(JoyStick向左)-device discovery
  • SW2(JoyStick向右)-device binding

有两种方法让两个设备进行沟通:

  • 终端节点上按下SW4
  • 两个设备“同时”按下SW2。(时间差在APS_DEFAULT_MAXBINDING_TIME范围内)

建立联系后,终端节点并会不断的发送信息Hello World给协调器,协调器收到后会将信息显示到LCD上。

  • device binding:
    设备向coordinator发送binding请求(通过函数ZDApp_SendEndDeviceBindReq()),然后coordinator会维护一个binding table,这个表用来记录有联系的设备。

  • device discovery:
    call ZDP_MatchDescReq
    This call will build and send an Match Descripton Request. Use this function to search for devices/applications that
    match something in the input/output cluster list ofan application.

终端节点代码分析

终端节点加入网络后,会周期性的发送信息给协调器,这是通过定时器timer实现的。
当有相应时间发生时会调用GenericApp_ProcessEvent,该函数判断时间类型中如果指定了GENERICAPP_SEND_MSG_EVT时,就调用GenericApp_SendTheMessage发送信息给协调器。然后使用定时器周期性地发送该消息。

uint16 GenericApp_ProcessEvent( uint8 task_id, uint16 events )
{
  ...
  // Send a message out - This event is generated by a timer
  //  (setup in GenericApp_Init()).
  if ( events & GENERICAPP_SEND_MSG_EVT )
  {
    // Send "the" message
    GenericApp_SendTheMessage();

    // Setup to send message again
    osal_start_timerEx( GenericApp_TaskID,
                        GENERICAPP_SEND_MSG_EVT,
                        GENERICAPP_SEND_MSG_TIMEOUT );

    // return unprocessed events
    return (events ^ GENERICAPP_SEND_MSG_EVT);
  }
  ...
}

配置文件f8wConfig.cfg

/* 终端节点和中控通信加密 */
-DSECURE=1 
/* 默认加密密钥,保证各设备一致 */
-DDEFAULT_KEY="{0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0D}"

/* 告诉中控,我会休眠,中控知道后会将消息放入队列 */
-DRFD_RCVC_ALWAYS_ON=FALSE

/* 想中控查询数据的时间间隔,单位毫秒 */
-DPOLL_RATE=3000

/* Define the default PAN ID.
 *
 * Setting this to a value other than 0xFFFF causes
 * ZDO_COORD to use this value as its PAN ID and
 * Routers and end devices to join PAN with this ID
 */
-DZDAPP_CONFIG_PAN_ID=0x1C9E // PAN ID, 即网络ID。终端设备会加入PAN ID为0x1c9e的网络

End Device

对于终端节点来说,GenericApp_ProcessEvent为主要代码。此外,终端节点通常需要注重休眠的细节,需要着重设计(省电)。

Coordinator

对于协调器(或叫中控)来说,功能通常比较复杂。不过代码框架是不变的,代码框架见OSAL的分析。只不过是添加一些任务。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值