Skip to content
ZIGBEE 协议栈分层 · 交互教学

一条 LED 命令,是怎么「包了一层又一层」发出去的?

协调器的应用层写下 2 个字节的开关命令 [01 01],要送到 3 米外的终端。它会依次穿过 应用 → APS → NWK → MAC → PHY 五层:每一层都往上套一个自己的「信封」(帧头),最后由天线把整封信发到空中。接收端再一层层拆开,直到拿到原始命令点亮 LED。本页用 ns-3 真实仿真跑出了这个过程,你看到的所有字节和时序都来自真实运行日志。

数据源:ns-3.48 zigbee 模块 · zigbee-stack-layers.cc 真实输出
应用层
APS 层
NWK 层
MAC 层
PHY 层
先搞懂 · 为什么协议栈要分层

想象寄一封国际快递

协议栈分层不是学术刁难,它就是一套「分工寄件」的规矩。每一层只做自己的事,不关心别的层怎么干活。

把终端设备想象成一座写字楼,协调器是另一座楼,要寄一封信过去:

  • 应用层——写信的人。只负责写内容:「把灯点亮」。
  • APS 层——楼内收发室。写上「寄件人房间 8 号 → 收件人房间 3 号」和「办什么事(开关灯业务)」。
  • NWK 层——城市邮局。写上「从 0x0000 寄到 0x7582」、最多经手 10 站、信件的编号。
  • MAC 层——快递员 + 信封。贴上本网络名(PAN)、收寄件地址、是否需要回执,最后装箱。
  • PHY 层——货车 / 无线电。把整封信调制到 2.4GHz 电磁波里发出去。

接收端收到后,把顺序反过来:货车卸货 → 快递员拆箱 → 城市邮局查地址 → 收发室核对房间号 → 最后把信纸内容交给收件人。

为什么要分?因为每一层都能独立升级、独立测试。Zigbee 底下的 MAC/PHY 直接用 IEEE 802.15.4 标准(不用自己发明),上层只要把 NWK/APS 做好就行。ns-3 里也是这么实现的——所以你学的分层,就是真实芯片里跑的分层。
认识五层 · 点一层看它在干什么

五层各司其职

点击下面的层,查看它负责什么、它在帧头里写了什么、在 ns-3 里对应哪个日志组件。所有帧头字段都是下面真实空中帧里能逐字节对上的。

应用层
写内容 · 端点
APS 层
端点 · 簇 · Profile
NWK 层
组网 · 寻址 · 路由
MAC 层
802.15.4 帧 · PAN
PHY 层
调制 · 收发比特
亲手走一遍 · 发送端逐层封装

点「发送一次」,看数据怎么一层层穿下去

协调器应用端点 8 → 终端端点 3。点击按钮后,一个 2 字节命令会从应用层出发,每经过一层就在头上「叠」一个该层的信封,最后变成一个完整的 29 字节空中帧。右下角会实时告诉你这一层做了什么。

应用层APP写下内容 [01 01],交给 APS
APS 层APS加 APS 头:端点 · 簇 · Profile
NWK 层NWK加 NWK 头:源/目的短地址 · 跳数 · 编号
MAC 层MAC加 MAC 头:PAN · 短地址 · 帧序号
PHY 层PHY调制并发射到空中(2.4 GHz)
点击「发送一次」开始。
看真实数据 · 29 字节空中帧解剖

这条命令在空中长什么样

下面是 ns-3 真实运行时、PHY 层交给射频发送的完整 29 字节。点击任意一个字节,查看它属于哪一层、代表什么。颜色与协议栈五层一一对应。

MAC 头 · 9 字节
NWK 头 · 8 字节
APS 头 · 8 字节
应用载荷 · 2 字节
MAC 校验 FCS · 2 字节
MAC 头
9 字节
61 9830b1 1b82 7500 00
NWK 头
8 字节
4c 0082 7500 000add
APS 头
8 字节
000306 0004 010800
应用载荷
2 字节
01 01
MAC 校验
2 字节
00 00
点击上面的字节或左侧图例,查看每一层帧头的字段解释。这些字节来自 ns-3 真实运行输出,可逐字节核对。
反向再看一次 · 接收端逐层解封装

收到的是 29 字节,交给应用的是 2 字节

接收端(终端)把过程完全反过来:天线收到比特 → PHY 解调 → MAC 拆掉自己的头 → NWK 查短地址是不是自己的 → APS 按端点号投递 → 应用层拿到最里面的 2 个字节 [01 01]。

PHY 层PHY解调比特流,还原 29 字节帧
MAC 层MAC校验 FCS · 剥离 MAC 头(PAN/地址)
NWK 层NWK目的短地址 0x7582 是自己 → 剥离 NWK 头
APS 层APS端点 3 是自己 → 剥离 APS 头
应用层APP拿到 [01 01] → 点亮 LED
动手 · 在 ns-3 里打开每一层

怎么自己跑出这些数据

本页所有数据来自示例 zigbee-stack-layers.cc 在 ns-3.48 里的真实运行。它的关键做法就两件事:开日志、挂 trace。

第 1 步 · 开启各层日志组件(main 函数开头)
LogComponentEnable("ZigbeeAps", LOG_LEVEL_DEBUG);
LogComponentEnable("ZigbeeNwk", LOG_LEVEL_DEBUG);
LogComponentEnable("LrWpanMac", LOG_LEVEL_DEBUG);
LogComponentEnable("LrWpanPhy", LOG_LEVEL_INFO);

日志组件名与协议栈层一一对应:APS 层 = ZigbeeAps,网络层 = ZigbeeNwk,MAC 层 = LrWpanMac(802.15.4 的 MAC),PHY 层 = LrWpanPhy。把它们打开,ns-3 就会在每一层进出时打印日志。

第 2 步 · 挂 PHY trace 打印完整空中帧(发送端/接收端)
dev->GetPhy()->TraceConnectWithoutContext("PhyTxBegin",
                                    MakeCallback(&OnPhyTxBegin));
dev->GetPhy()->TraceConnectWithoutContext("PhyRxEnd",
                                    MakeCallback(&OnPhyRxEnd));

PHY 层有现成的 trace 源:PhyTxBegin 在帧真正发出前触发,PhyRxEnd 在接收端解调完成后触发。回调里把 Ptr<Packet> 逐字节打印出来,就是上面那份 29 字节帧。

第 3 步 · 应用层发送(协调器侧)
ApsdeDataRequestParams req;
req.m_srcEndPoint = 8;      // 源端点:控制器应用
req.m_dstEndPoint = 3;      // 目的端点:LED 执行器
req.m_profileId  = 0x0104;  // Profile:Home Automation
req.m_clusterId  = 0x0006;  // 簇:On/Off(开关灯)
req.m_dstAddr16  = 终端短地址; // 0x7582
Ptr<Packet> p = Create<Packet>(buf, 2); // [01 01]
Simulator::ScheduleNow(&ZigbeeAps::ApsdeDataRequest, aps, req, p);

真实运行日志(本页数据来源,摘录):

收个尾 · 一张表记牢五层

五层对照速查

层一句话职责它在帧头里写了什么本页真实示例ns-3 日志组件
应用层决定「干什么」,用端点区分多个应用(不带头)内容即载荷端点 8 发 [01 01]无(应用自己)
APS端点寻址 + 业务(簇/Profile)标识帧控制 · 源/目的端点 · 簇 ID · Profile ID端 8→3 · 簇 0x0006 · Profile 0x0104ZigbeeAps
NWK组网、短地址寻址、路由、跳数限制帧控制 · 源/目的短地址 · 半径 · 序列号0x0000→0x7582 · 半径 10ZigbeeNwk
MAC802.15.4 帧格式、PAN、确认、信道访问帧控制 · 帧序号 · PAN ID · 短地址 · FCSPAN 0x1bb1 · 帧序号 0x30LrWpanMac
PHY调制解调、发送/接收比特流(不带头)负责把整帧调制到 2.4GHz29 字节帧发射LrWpanPhy
一句话总结:发送端从里往外一层层套信封,接收端从外往里一层层拆信封。中间那 2 个字节 [01 01] 从头到尾都没变——变的只是它外面包了多少层「地址 + 说明」,这就是「逐层封装 / 逐层解封装」。
本页为教学演示页 · 已纳入 aioteer 课程站(ZigBee 实验教室),支持 AI 伴学。
所有字节、地址、日志均为 ns-3.48 + zigbee 模块 真实运行输出(示例 zigbee-stack-layers.cc),非示意图。短地址、PAN ID 等由仿真随机决定,每次运行可能略有不同,但分层结构与字段含义不变。
配套源码:E:\ns3_zigbee\stack-layers\zigbee-stack-layers.cc · 真实日志:E:\ns3_zigbee\output\zigbee-stack-layers.log

aioteer · 物联网专业课程群

💬AI 伴学配置