ZigBee学习——基于AF的数据通信

news2025/1/18 10:56:11

文章目录

  • 一、简单描述符
    • 1.1 简单介绍
    • 1.2 简单描述结构体介绍
    • 1.3 结构体中的簇
    • 1.4 应用场景
  • 二、AF通信原理
    • 2.1 通信过程
    • 2.2 端点号分类
    • 2.3 通信方式
    • 2.4 注册简单描述符
  • 三、数据发送API简介
    • 3.1 AF层数据发送API
    • 3.2 基于AF层封装的通信API
      • 3.2.1 点对点通信API
      • 3.2.2 广播通信API
      • 3.2.3 组播通信API
  • 四、实战

一、简单描述符

1.1 简单介绍

  在ZigBee中,简单描述符(Simple Descriptor)是一种数据结构,它提供了关于某个设备的端点(EndPoint)的基本信息。简单描述符包括端点的ID,设备的类型,以及设备支持的簇(Cluster)。
  如果设备是一个智能灯泡,那么它可能有一个简单描述符,其中的设备类型就是"智能灯泡",支持的簇可能包括"开关控制",“亮度控制"等等。这样,当其他设备(比如一个开关或者调光器)想与这个智能灯泡交互时,就可以通过查看这个简单描述符来了解该设备的功能以及如何与其交互。
  比如说,一个智能开关在连接一个智能灯泡时,它可以查看灯泡的简单描述符,发现这个灯泡支持"开关控制"和"亮度控制”,那么,这个开关就知道它可以通过发送特定的信号来控制灯泡的开关和亮度。
  所以,可以说简单描述符在ZigBee网络中起到了"设备说明书"的作用,它描述了设备的功能以及设备之间如何交互,帮助设备之间的正常通信。

1.2 简单描述结构体介绍

  简单描述符结构体

typedef struct{
uint8    EndPoint;//端点号
uint16   AppProfId;//描述所在应用场景,例如家居自动化
uint16   AppDeviceId;//设备ID
uint8    AppDevVer:4;//由开发者自定义,表示版本号
uint8    Reserved:4;//保留字段
uint8    AppNumInClusters;//端点支持的输入簇个数
cId_t    *pAppInClusterList;//指向输入簇列表的指针
uint8    AppNumOutClusters;//端点支持的输出簇个数
cId_t    *pAppOutClusterList;//指向输出簇列表的指针
}SimpleDescriptionFormat_t;
  • 端点号:EndPoint,可以理解为简单描述符的编号,取值范围是0~255。在同一个ZigBee设备中,每一个简单描述符都有一个不同的端点号,可以利用端点号来找到对应的简单描述符。
  • AppProfId:Profile ID,表示这个简单描述符所属的应用场景。这个应用场景可以是家居自动化、智能照明和智慧零售等。ZigBee联盟为不同的场景定义了对应的ID值,称为Profile ID。
  • AppDeviceId:Device ID,表示这个简单描述符所属的设备类型。这个设备类型可以是插座、灯或者传感器等。类似地,ZigBee联盟为不同类型的设备定义了对应的ID值,称为Device ID。
  • AppDevVer:这个值可以由开发者自定义,用来表示版本号。
    Reserved:保留字段,暂时可以忽略。
  • Cluster:簇,或者集群,可以划分为输入簇(In Cluseter)和输出簇(Out Cluster),用来描述这个服务的具体内容。一个简单描述符中可以包含多个Cluster,这些Cluster共同描述了这个服务的具体内容,后续章节将会详细讲解。

1.3 结构体中的簇

  在ZigBee中,"簇"或"集群"是指一组基于某种特定功能组合在一起的设备。这些设备能够按照固定规则进行交互或执行特定任务。
  比如,我们可以把灯泡、开关和调光器看作一个“簇”。开关负责控制灯泡的开启或关闭,调光器则可以调节灯泡的亮度。它们三个围绕着"控制照明"这个功能组成了一个簇。
  在这个簇中,当你使用开关,开关会发送一个信号给灯泡,告诉它要开或者关。如果你用调光器,调光器会发送一个信号给灯泡,告诉它调到什么样的亮度。这就是开关、调光器和灯泡在这个“簇”中的交互方式。
所以,通过设置簇,我们可以更好地将相关设备组织在一起,更有效地实现环境控制、智能家居等复杂应用。不同的簇可以包含不同类型的设备,以满足不同场景的需求。

1.4 应用场景

简单描述符一般定义在App层,如下图所示:
在这里插入图片描述

SimpleDescriptionFormat_t zclSampleSw_SimpleDesc =
{
  SAMPLESW_ENDPOINT,                  //  端点号
  ZCL_HA_PROFILE_ID,                  //  设备应用领域ID
  ZCL_HA_DEVICEID_ON_OFF_LIGHT_SWITCH,//  设备类型ID
  SAMPLESW_DEVICE_VERSION,            //  版本号
  SAMPLESW_FLAGS,                     //  保留字段
  ZCLSAMPLESW_MAX_INCLUSTERS,         //  最大输入簇数量
  (cId_t *)zclSampleSw_InClusterList, //  表示输入簇列表
  ZCLSAMPLESW_MAX_OUTCLUSTERS,        //  最大输出簇数量
  (cId_t *)zclSampleSw_OutClusterList //  表示输出簇列表
};

二、AF通信原理

2.1 通信过程

AF的全称是Application Framework,中文意思是应用框架,AF层也就是应用框架层,它在ZigBee协议层次中位置如图所示。开发者可以基于这个层次编写代码,实现ZigBee设备之间的数据通信。
在这里插入图片描述
图片来源于:善学坊

需要知道的是ZigBee在很多情况下是基于服务的,也就是单单依靠网络地址是不够的,还需要端点号来确认通信的最终目的。

处于网络中的ZigBee设备都会被分配一个网络地址,用于标识设备所处的位置。通过这个网络地址就可以找到对应的设备了。我们知道ZigBee 3.0是利用简单描述符来描述特定的服务的,并且设备上的每个简单描述符都配有一个唯一的端点号
在这里插入图片描述
图片来源于:善学坊

  假设现在ZigBee网络中有一个协调器和一个智能插座终端,这个智能插座的网络地址为0x0EF1,并且配有一个简单描述符描述这个插座具备的一些功能,这个简单描述符的端点号是8。

  如果协调器要向这个插座发送一个打开指令,不能简单地使用网络地址0x0EF1来说明把命令发送给这个插座,还需要利用端点号8来说明把命令发送给端点号8对应的服务。

2.2 端点号分类

端点号的分类
端点号的取值范围是0~255,其中:

  • 端点号0被分配给了ZDO(ZigBee Device Object)。
  • 端点号255是广播,也就是向这个端点号发送数据时,设备的所有服务(简单描述符)都会收到这个数据。
  • 端点号241~254是暂时保留起来的端点号,暂时不能使用。
  • 剩下的端点号1~240可以供开发者自由地使用,例如读者一直学习的SampleSwitch这个工程所使用的端点号可以在工程中找到,如图所示。

在这里插入图片描述

2.3 通信方式

ZigBee支持3种通信方式,分别是点对点、广播和组播。

  • 点对点通信(P2P,Peer to Peer):顾名思义,就是两个设备之间一对一通信。
  • 广播:给其他的所有设备发送数据。
  • 组播:给一部分的设备发送数据,这里的“一部分”说的就是一个特定的组。

2.4 注册简单描述符

在使用AF通信前,需要先注册简单描述符并且让对应的端点号生效,或者说让这个简单描述符对应的服务生效。这个流程是:

(1)创建一个简单描述符。在讲解简单描述符的章节中,我们已经看到相关的定义了。

(2)注册这个简单描述符。打开配套的工程,在zcl_samplesw.c文件中的zclSampleSw_Init()这个函数中可以找到以下代码,如图所示。
在这里插入图片描述

在应用层初始化函数zclSampleSw_Init()中,有两种注册简单描述符的方法:
(1)可以调用bdb_RegisterSimpleDescriptor()来在BDB中注册简单描述符。
(2)也可以直接调用afRegister()直接在AF中注册简单描述符。

在注册完简单描述符之后,就可以使用AF层的通信API来收发数据了。

三、数据发送API简介

3.1 AF层数据发送API

  数据发送API
在AF.c这个文件中可以找到一个名为AF_DataRequest()的数据发送API,如图所示。
在这里插入图片描述
  参数说明

/*
* @param dstAddr 目标设备地址,包含网络地址和端点号
* @param srcEP 发送设备的简单描述符
* @param cID Cluster ID,后续章节将会详细讲解
* @param len 待发送数据的长度
* @param buf 待发送的数据
* @param transID 传输ID,可以用来给每一次发送的数据包编一个号
* @param options 附加选项,可以用来给这次数据发送添加一些说明                      
* @param radius 最大的路由跳转级数
*/
afStatus_t AF_DataRequest(
	afAddrType_t *dstAddr, 
	endPointDesc_t *srcEP,
	uint16 cID,
	uint16 len, 
	uint8 *buf,
	uint8 *transID,
	uint8 options,
	uint8 radius );

协议栈里面的SampleSwitch这个例程基于这个API封装出了点对点通信API、广播通信API和组播通信API。

3.2 基于AF层封装的通信API

3.2.1 点对点通信API

/*
* @param destNwkAddr 目标设备的网络地址
* @param cid Cluster ID,后续课程将会详细讲解
* @param len 数据长度
* @param data 数据内容
*/
static void zclSampleSw_AF_P2P(
	uint16 destNwkAddr, 
	uint16 cid, 
	uint8 len, 
	uint8 *data)
{    
	afAddrType_t dstAddr; //寻址信息配置 
	static uint8 transferId = 0;//传输ID,是数据包的标识符

	/* Destination */    
	dstAddr.addrMode = afAddr16Bit;// 设置目标地址模式为16位网络地址,表示使用P2P的通信方式
	dstAddr.addr.shortAddr = destNwkAddr;//目标设备的网络地址  
	dstAddr.endPoint = SAMPLESW_ENDPOINT;//目标设备的端点号

	 transferId++;    
	AF_DataRequest(&dstAddr, 
		&sampleSw_TestEp,//已经创建好的简单描述符
		cid,    
		len, 
		data,    
		&transferId,
		AF_DISCV_ROUTE,//进行路由扫描操作,用于建立发送数据报文的通信路径。关于这个参数,暂时保持例程默认的代码就可以了
		AF_DEFAULT_RADIUS);//指定最大的路由跳转级数
}

这个API中使用了一个afAddrType_t类型变量,该变量类型被定义在AF.h中,用于配置寻址信息。这个变量定义如下:

typedef struct
{
  union
  {
    uint16      shortAddr;
    ZLongAddr_t extAddr;
  } addr;
  afAddrMode_t addrMode;
  uint8 endPoint;
  uint16 panId;  // used for the INTER_PAN feature
}  afAddrType_t;

这个API中也使用了一个afAddrMode_t变量,表示地址模式(类型),用于说明使用的是点对点、广播还是组播的通信方式。同样地,可以查看其定义,代码如下:
在这里插入图片描述

可以看到,afAddrMode_t是一个枚举类型变量。

在zclSampleSw_AF_P2P()函数的的最后,可以看到最终就是调用AF_DataRequest()来发送数据的。开发者也可以基于AF_DataRequest()来编写自己的点对点通信API,而不使用这个工程中的默认的这个zclSampleSw_AF_P2P()。

3.2.2 广播通信API

在zcl_samplesw.c文件中可以找到广播通信API,代码如下:

/*
* @param cid Cluster ID
* @param len 待发送数据的长度
* @param *data 待发送数据的内容
*/
static void zclSampleSw_AF_Broadcast(
	uint16 cid,
	uint8 len,
	uint8 *data)
{
	afAddrType_t dstAddr;  
	static uint8 transferId = 0;  

	/* Destination */  
	dstAddr.addrMode = afAddrBroadcast;   // 使用广播模式
	dstAddr.addr.shortAddr = 0xFFFF; // 广播地址
	dstAddr.endPoint = SAMPLESW_ENDPOINT; // 目标设备的端点号
	
	 /* Transfer id */  
	transferId++;  
	
	/* Send */  
	AF_DataRequest(
		&dstAddr, 
		&sampleSw_TestEp,//已经创建好的简单描述符
		cid,  
		len, 
		data,  
		&transferId,
		AF_TX_OPTIONS_NONE,
		AF_DEFAULT_RADIUS );//指定了最大的路由跳转级数
}

从广播通信API的定义可以发现,它和点对点通信API是相似的。广播通信API中使用了网络地址0xFFFF,这表示把数据发送到该网络上的所有设备中。但其实ZigBee的广播地址一共有3个,如下所示:

0xFFFF:广播给该网络中的所有设备
0xFFFD:只广播给该网络中打开收听功能的设备
0xFFFC:只广播给该网络中的协调器和路由设备

同样地,开发者也可以基于AF_DataRequest()来编写自己的广播通信API,而不使用这个工程中的默认的这个zclSampleSw_AF_Broadcast()

3.2.3 组播通信API

使用组播通信API,可以只给指定的一组设备发送数据。在zcl_samplesw.c文件中可以找到组播通信API,代码如下:

/*
* @param groupId 组ID
* @param cid ClusterID,后续章节将会详细讲解
* @param len 待发送数据的长度
* @param data 待发送数据的内容
*/
static void zclSampleSw_AF_Groupcast(
	uint16 groupId,
	uint16 cid,
	uint8 len,
	uint8 *data)
{    
	afAddrType_t dstAddr;    
	static uint8 transferId = 0;    

	/* Destination */    
    dstAddr.addrMode = afAddrGroup;//使用组播通信模式
	dstAddr.addr.shortAddr = groupId;
	dstAddr.endPoint = SAMPLESW_ENDPOINT;//组中的设备的端点号
	
	/* Transfer id */    
	transferId++;   
 
	/* Send */    
	AF_DataRequest(&dstAddr, 
		&sampleSw_TestEp,//已经创建好的简单描述符
		cid, 
		len, 
		data,    
		&transferId, 
		AF_TX_OPTIONS_NONE,
		AF_DEFAULT_RADIUS );//指定最大的路由跳转级数,暂时可忽略
}

四、实战

在学习完AF层通信API后,本章将以实验的方式讲解如何使用这些API,实验设备包含一个协调器和一个路由器(或终端),内容是:

  • 路由器(或终端)定时地通过点对点的方式向协调器发送数据。
  • 让路由器(或终端)加入到一个组中。
  • 协调器定时地发送广播数据和组播数据。

这部分根据善学坊教程:3.4 ZigBee 3.0 通信实验

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1455632.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

124.乐理基础-五线谱-大三度、小三度

内容参考于:三分钟音乐社 上一个内容:123.乐理基础-五线谱-大二度、小二度、音数-CSDN博客 上一个内容里的练习答案: 大三度、小三度:还是数音数,详情看上一个内容里写的 练习:

mmap映射文件使用示例

mmap 零拷贝技术可以应用于很多场景,其中一个典型的应用场景是网络文件传输。 假设我们需要将一个大文件传输到远程服务器上。在传统的方式下,我们可能需要将文件内容读入内存,然后再将数据从内存复制到网络协议栈中,最终发送到远…

C++Qt:noteBookPro_01

一、创建项目 选择Qt Widgets 常用的是QWidgets和MainWindow。两者的区别: QWidgets用于简单的窗口,没有内置的菜单栏、工具栏和状态栏。适用于简单专用的应用程序,不需要复杂的界面组件。 MainWindow是包含完整的菜单栏、工具栏和状态栏的主…

初始树莓派 + VMware17 安装树莓派(Raspberry Pi 4B/5)

文章目录 树莓派入门 VMware17 安装树莓派(Raspberry Pi 4/5B)前言一、树莓派入门指南:从零开始探索树莓派树莓派4B和5对比 二、在VMware Workstation 17上安装树莓派4B/5操作系统:实现强大性能与便捷模拟工具准备开始安装树莓派1.创建一个虚拟机2. 选择…

<网络安全>《39 网络攻防专业课<第五课 - 常见漏洞利用与修复>》

1 Windows服务器系统入侵流程 1.1 NetBios漏洞攻防 NetBIOS(Network Basic Input Output System,网络基本输入/输出系统)是一种应用程序接口(API),系统可以利用WINS服务、广播及Lmhost文件等多种模式&…

day04-股票K线功能实现

股票K线功能实现 今日目标 1.理解股票T和T-1概念,实现成交量对比功能; 2.理解个股涨跌幅度统计功能; 2.1 分析业务,SQL落地; 2.2 完善不存在数据的区间默认回显功能; 3.理解个股分时线业务,并实现功能; 4.理解个股日K线业务,并实…

2.18作业

作业要求&#xff1a;使用fgets统计给定文件的行数 程序代码&#xff1a; #include<stdlib.h> #include<string.h> #include<stdio.h>int main(int argc, const char *argv[]) {if(argc!2){printf("input file error\n");printf("usage:./a…

爬虫之正则表达式

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 概念&#xff1a; 正则表达式(regular expression)描述了一种字符串匹配的模式&#xff08;pattern&#xff09;&#xff0c;正则匹配是一个模糊的匹配(不是精确匹配) 如下四个方法经常使用&#xff1a; match()search()f…

数据分析师SQL面试准备(part1)

1. SQL 万能框架 2. SQL的书写顺序&#xff0c;跟程序真的执行顺序不同 3. 4. 5. 6. 7. case when utilization 8. 9. 10. 11.

【RL】Monte Carlo Learning(蒙特卡洛学习)

Lecture 5: Monte Carlo Learning The simplest MC-based RL algorithm: MC Basic 理解MC basic算法的关键是理解如何将policy iteration算法迁移到model-free的条件下。 Policy iteration算法在每次迭代过程中有两步&#xff1a; { Policy evaluation: v π k r π k γ…

【HarmonyOS】鸿蒙开发之Button组件——第3.4章

按钮类型 Capsule&#xff08;默认值&#xff09;&#xff1a;胶囊类型 Button("默认样式").height(40)//高度.width(90)//宽度.backgroundColor(#aabbcc)//背景颜色运行结果: Normal&#xff1a;矩形按钮&#xff0c;无圆角 Button({type:ButtonType.Normal}){Te…

防御保护---防火墙综合实验

拓扑图 实验要求 办公区的设备可以通过电信链路和移动链路上网分公司设备可以通过总公司的移动链路和电信链路访问到DMZ区域的HTTP服务器分公司内部的客户端可以通过公网地址访问到内部的服务器FW1和FW2组成主备模式双击热备办公区上网用户限制流量不超过60M&#xff0c;其中销…

人工智能技术应用笔记(二):OpenAI SORA文生视频模型技术报告全文中英对照 (GPT4翻译+人工润色)

目录 Video generation models as world simulators&#xff08;视频生成模型作为世界模拟器&#xff09; Turning visual data into patches &#xff08;将视觉数据转换为图像块&#xff09; Video compression network &#xff08;视频压缩网络&#xff09; Spacetim…

Linux系统中 uboot、内核与文件系统之间的关系

前言&#xff1a; 最近正在学习Linux&#xff0c;总结了一下Linux系统中 uboot、内核与文件系统之间的关系 Linux初学者首先要搞清楚的三个文件: 引导程序(bootoader):uboot.bin/uboot.imx Linux内核镜像: zlmage 文件系统镜像:system.img/rootfs.tar.ba2 初期很多工作都是围…

Eclipse - Format Comment

Eclipse - Format & Comment 1. Correct Indentation2. Format3. Toggle Comment4. Add Block Comment5. Remove Block CommentReferences 1. Correct Indentation Ctrl A: 选择全部代码 Ctrl I: 校正缩进 or right-click -> Source -> Correct Indentation 2. F…

OLMo论文里的模型结构的小白解析

模型参数量 以7B为例&#xff0c;隐藏层为4086&#xff0c;attention heads为32 训练的token量为2.46T 训练策略 超参数 在我们的硬件上优化训练吞吐量&#xff0c;同时最小化损失峰值和缓慢发散的风险来选择超参数 损失峰值&#xff1a;在机器学习中&#xff0c;"损失峰…

RabbitMQ保证消息的可靠性

1. 问题引入 消息从发送&#xff0c;到消费者接收&#xff0c;会经理多个过程&#xff1a; 其中的每一步都可能导致消息丢失&#xff0c;常见的丢失原因包括&#xff1a; 发送时丢失&#xff1a; 生产者发送的消息未送达exchange消息到达exchange后未到达queue MQ宕机&…

【MATLAB GUI】 1. 普通按钮、静态文本和可编辑文本

看B站up主freexyn的freexyn编程实例视频教程系列36Matlab GUI的学习笔记 文章目录 初步认识普通按钮静态文本和可编辑文本设计一个简易计算机 初步认识普通按钮 任务要求&#xff1a;点击一次“100”按钮&#xff0c;按钮上的文字值就递增1&#xff1b;点击“close”按钮&…

边坡位移监测设备:守护工程安全的前沿科技

随着现代工程建设的飞速发展&#xff0c;边坡位移监测作为预防山体滑坡、泥石流等自然灾害的重要手段&#xff0c;日益受到人们的关注。边坡位移监测设备作为这一领域的关键技术&#xff0c;以其高精度、实时监测的特点&#xff0c;成为守护工程安全的重要武器。 一、边坡位移…

20-k8s中pod的调度-nodeSelector节点选择器

一、概念 我们先创建一个普通的deploy资源&#xff0c;设置为10个副本 [rootk8s231 dns]# cat deploy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: dm01 spec: replicas: 10 selector: matchLabels: k8s: k8s template: metadata: …