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

文章目录

  • 一、简单描述符
    • 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,                  //  设备应用领域IDZCL_HA_DEVICEID_ON_OFF_LIGHT_SWITCH,//  设备类型IDSAMPLESW_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.mzph.cn/news/689039.shtml

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

相关文章

数据库管理-第151期 Oracle Vector DB AI-03(20240218)

数据库管理151期 2024-02-18 数据库管理-第151期 Oracle Vector DB & AI-03(20240218)1 向量数据库应用场景2 Oracle Vector DB3 Vector数据类型4 Vector运算5 Vector DML插入向量获取向量 总结 数据库管理-第151期 Oracle Vector DB & AI-03&am…

LeetCode 热题 100 Day01

哈希模块 哈希结构: 哈希结构,即hash table,哈希表|散列表结构。 图摘自《代码随想录》 哈希表本质上表示的元素和索引的一种映射关系。 若查找某个数组中第n个元素,有两种方法: 1.从头遍历,复杂度&#xf…

【Spring】三级缓存

目录标题 触发所有未加载的实例a - 开始getBean( doGetBean) - 获取单例beangetSingleton() - 获取单例beancreateBean(doCreateBean) - 创建beancreateBeanInstance - 创建并返回beanaddSingletonFactory -放三级缓存populateBea…

序列发生器

一开始想直接FSM,划分出6状态依次输出对应的。但其实只要6比特的移位寄存器,每次输出高位。复位后的默认值时6’b001_011。这样就可以实现循环,这种移位寄存器也叫barrel_shifter。循环移位。也可以使用循环计数器,然后case计数器…

<爬虫Error篇>:乱码问题

前言: 当涉及到网页编码问题时,经常会遇到不同页面使用不同编码方式的情况。这可能导致在解析页面时出现乱码,使我们无法正确获取页面内容 正文: 网页的编码问题: 在处理网页编码问题之前,我们需要了解一些基础知识。网页中的编码方式通常…

JRT监听-PDF-Excel-Img

依赖全新设计,我们无需再顾虑历史兼容性的束缚;同时,基于多年来累积的深入需求理解,JRT监听机制巧妙地借助CMD命令模式,达成了监听的全面统一。无论是PDF、Excel还是图片文件,都不再需要特殊对待或额外区分…

MT8781核心板_MTK8781安卓核心板规格参数

MT8781安卓核心板以其强大的性能和高效的能耐备受瞩目。其八核CPU架构包括(2x Cortex-A76 2.2GHz 6x Cortex-A55 2.0GHz),以及高性能的Arm Mali G57级GPU。同时,配备高达2,133MHz的LPDDR4X内存和快速的UFS 2.2级存储,大大加速了数据访问速…

java面试集合篇

上面是java中集合的整体框架图。 集合使用的数据结构 算法复杂度分析 时间复杂度分析 时间复杂度分析&#xff1a;来评估代码的执行耗时的 /*** 求1~n的累加和* param n* return*/ public int sum(int n) {int sum 0;for ( int i 1; i < n; i) {sum sum i;}return …

ubuntu22.04-磁盘管理-虚拟机动态扩容-系统monitor

文章目录 1.虚拟机2.ubuntu设置3.命令查看4.系统资源管理器 1.虚拟机 关闭ubuntu22.04&#xff0c;然后修改虚拟机设置&#xff0c;如下图所示&#xff1a; 修改容量 2.ubuntu设置 搜索打开disks&#xff0c;如下图所示&#xff1a; 选择目标磁盘&#xff0c;选择调整大小…

Filterajax

1.Filter概念 概念:表示过滤器,是JavaWeb三大组件(Servlet,Filter,Listener)之一;过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能.过滤器可以完成一些通用操作比如:登录添加购物车,视频广告,敏感字符处理等等... 2.Filter快速入门 3.Listener 4.Ajax学习 1.使用场…

Android 15 第一个开发者预览版

点击查看&#xff1a;first-developer-preview-android15 点击查看&#xff1a;Get Android 15 2024年2月16日,谷歌发布 Android 15 第一个开发者预览版 翻译 由工程副总裁戴夫伯克发布 今天&#xff0c;我们发布了Android 15的首个开发者预览版&#xff0c;这样我们的开发者就…

腾讯云OSS文件上传功能

腾讯云COS介绍 腾讯云COS&#xff08;Cloud Object Storage&#xff09;是一种基于对象的存储服务&#xff0c;用于存储和管理海量的非结构化数据&#xff0c;如图片、音视频文件、备份数据等。它具有以下特点和优势&#xff1a; 高可靠性&#xff1a;采用分布式存储架构&…

MySQL学习记录——십이 事务

文章目录 1、了解事务2、事务提交3、事务隔离级别1、隔离性和隔离级别2、查看、设置隔离级别3、读未提交4、读提交5、可重复读6、串行化7、总结 4、事务一致性5、事务隔离性1、隐藏字段2、undo日志3、模拟MVCC4、Read View 6、读提交RC、可重复读RR的区别 1、了解事务 MySQL内…

强化学习(TD3)

TD3——Twin Delayed Deep Deterministic policy gradient 双延迟深度确定性策略梯度 TD3是DDPG的一个优化版本&#xff0c;旨在解决DDPG算法的高估问题 优化点&#xff1a; ①双重收集&#xff1a;采取两套critic收集&#xff0c;计算两者中较小的值&#xff0c;从而克制收…

第一个 Angular 项目 - 动态页面

第一个 Angular 项目 - 动态页面 使用的所有技巧都在下面的笔记里&#xff1a; [Angular 基础] - 数据绑定(databinding) [Angular 基础] - 指令(directives) 以上为静态页面&#xff0c;即不涉及到跨组件交流的内容 以下涉及到组件内的沟通&#xff0c;从这开始数据就“活”…

才气系统与逻辑系统道装实现的比较

才气系统与逻辑系统道装实现的比较 道装道装思想简介烛火流形学习引擎&#xff0c;流形学习的引入王船山信息熵&#xff0c;简称王船山熵&#xff1b;凝聚态数学可计算函数科学方法道装由来琴语言简介逻辑与才气的逐层比较表格&#xff08;王船山熵&#xff09; 道装 道装思想…

OpenCV 入门讲解

OpenCV 入门讲解 OpenCV&#xff08;Open Source Computer Vision Library&#xff09; 是一个开源的计算机视觉库&#xff0c;它提供了许多高效实现计算机视觉算法的函数&#xff0c;从基本的滤波到高级的物体检测都有涵盖。OpenCV 使用 C/C 开发&#xff0c;同时也提供了 Pyt…

短链接系统测试报告

目录 项目背景 项目功能 自动化测试 总结 项目背景 随着互联网的发展&#xff0c;链接&#xff08;URL&#xff09;变得越来越长且复杂&#xff0c;这不仅影响用户体验&#xff0c;还可能由于字符限制导致在某些平台或应用中无法完整显示。为了解决这一问题&#xff0c;我…

Ubuntu22.04LTS编译Frida历史版本,环境配制及细节调整

经常使用Frida的朋友们可能会遇到Frida的各种问题需要自定义的&#xff0c;而这时候Frida的本地编译就显得很重要了。 最近一位朋友发现使用Frida14/15/16版的server只能连拉一定数量的设备&#xff0c;超过了frida-device-manager便不能连接设备。 实现没有办法&#xff0c;…

综合练习

目录 查询每个员工的编号、姓名、职位、基本工资、部门名称、部门位置 确定要使用的数据表 确定已知的关联字段 查询每个员工的编号、姓名、职位、基本工资、工资等级 确定要使用的数据表 确定已知的关联字段 查询每个员工的编号、姓名、职位、基本工资、部门名称、工资…