2. LoRaWAN协议架构与终端角色

LoRaWAN并不是一种单纯的无线调制技术,而是一套建立在LoRa物理层之上的完整通信协议。理解终端在协议中的位置,是设计低功耗节点的第一步。从整体上看,LoRaWAN采用典型的星型拓扑:终端节点(End Device)通过单跳LoRa无线链路连接到一个或多个网关(Gateway),网关再通过标准IP回传网络把数据送到网络服务器(Network Server),最终由应用服务器(Application Server)处理业务数据。终端不直接与网关"配对",也不关心数据经过哪个网关,它只负责把MAC帧发到空中,由网络服务器统一完成去重、鉴权和路由。

在这个架构中,终端承担的角色非常明确:它是数据的采集者和发送者,也是下行命令的执行者。终端的协议栈通常分为两层——MAC层和PHY层。PHY层负责LoRa调制解调、扩频因子(SF)、带宽(BW)、编码率(CR)以及发射功率的控制;MAC层则负责帧格式、入网、信道管理、确认重传、ADR(自适应速率)和各类MAC命令的处理。设计低功耗终端时,真正决定功耗和可靠性的,往往不是PHY层的射频参数,而是MAC层的行为策略,比如发送占空比、接收窗口开启时机和确认机制。

终端分类与入网流程

按入网方式,LoRaWAN终端分为两类:OTAA(Over-The-Air Activation,空中激活)和ABP(Activation By Personalization,个性化激活)。OTAA终端在每次入网时通过Join Request/Join Accept交互动态派生会话密钥,安全性高,适合量产设备;ABP终端则把DevAddr、NwkSKey、AppSKey直接烧录在设备里,上电即可发送,省去入网握手,但密钥固定、无法轮换,安全性较弱。实际产品中,OTAA是主流选择,ABP多用于快速验证或极简场景。

OTAA的入网流程可以概括为:终端在随机信道和速率上发送Join Request,其中包含DevEUI、AppEUI和DevNonce;网络服务器验证后回复Join Accept,携带DevAddr、AppNonce以及加密后的网络会话密钥NwkSKey和应用会话密钥AppSKey;终端用AppKey解密并保存这些参数,随后即可用新密钥发送上行数据。整个过程通常只需几秒,但会消耗一次完整的收发周期,因此终端不应频繁重新入网,而应在掉线或复位后才重新发起。

LoRaWAN 星型架构与终端协议栈 终端 End Device 应用层 传感器 / 执行器 MAC 层 帧格式 / 入网 / 确认 ADR / 信道管理 接收窗口调度 PHY 层 LoRa 调制 / 解调 SF / BW / CR 发射功率控制 网关 Gateway LoRa 射频前端 多信道监听 IP 回传 UDP / MQTT 网络服务器 去重 / 鉴权 / 路由 MAC 命令处理 ADR 决策 Join 会话管理 应用服务器 业务数据解析 下行指令生成 密钥管理 LoRa 无线 IP 回传 数据转发 下行 下行 上行数据 下行数据 MAC 层职责 PHY 层职责

MAC层与PHY层的职责边界

把两层职责分清楚,能避免很多设计误区。PHY层只关心"怎么把比特可靠地送出去":它根据网络服务器下发的速率指令选择SF和带宽,控制发射功率,完成前导码检测和CRC校验。PHY层不关心帧里装的是什么,也不管是否需要重传。MAC层则关心"什么时候发、发给谁、发什么、发完怎么收":它构造MHDR、FHDR、FPort和FRMPayload,维护帧计数器FCnt,处理Confirmed帧的ACK,执行ADR指令调整速率和功率,并在每次上行后按Class规则打开接收窗口。

一个常见的误解是"把SF调大就能传得更远"。实际上,SF越大,符号时间越长,抗干扰能力越强,但空中时间也成倍增加,功耗和占空比压力随之上升。MAC层的ADR机制正是为了在链路质量和功耗之间找平衡:网络服务器根据终端上报的SNR和网关接收情况,动态建议终端使用更高速率或更低功率。终端应尊重ADR指令,但在移动或链路突变场景下,也可以关闭ADR,改用固定速率。

Class A / B / C 终端行为差异

LoRaWAN定义了三种终端类别,核心区别在于接收窗口的开启方式,这直接决定了功耗和下行时延。

Class A是最基础的类别,所有终端都必须支持。它采用"上行触发接收":每次上行发送结束后,终端在固定延时后打开两个短接收窗口(RX1和RX2)。RX1通常使用与上行相同的信道和速率,RX2使用固定速率和频率。除此之外,终端一直处于休眠状态。Class A功耗最低,但下行只能在终端主动上报后到达,时延不可控,适合电池供电、以周期上报为主的传感器。

Class B在Class A基础上增加了周期性接收窗口(Ping Slot)。终端通过Beacon同步到网络时间,网关在约定时隙发送下行,终端只需在Ping Slot时刻短暂唤醒。这样下行时延从"等下一次上行"缩短到秒级,代价是需要维持与Beacon的同步,功耗略高于Class A。Class B适合需要一定下行响应能力、但仍以电池供电的场景。

Class C几乎一直保持接收窗口开启,只在发送时短暂关闭。它的下行时延最低,可以随时接收命令,但接收机持续工作,功耗最高,通常需要持续供电。Class C适合市电供电的执行器、网关辅助设备或需要实时下发的控制类终端。

类别 接收窗口 下行时延 功耗 典型供电
Class A 上行后 RX1/RX2 高(等下次上行) 最低 电池
Class B RX1/RX2 + Ping Slot 中(秒级) 中等 电池
Class C 持续接收 低(随时) 最高 市电
选择终端类别时,先问三个问题:下行是否频繁?下行时延能否容忍?供电方式是什么?如果只是每天上报几次温湿度,Class A足够;如果需要远程下发开关命令且要求几秒内响应,Class B更合适;如果是持续供电的路灯控制器,Class C最直接。

入网参数与关键配置示例

以OTAA入网为例,终端需要预先烧录DevEUI、AppEUI和AppKey。DevEUI是终端唯一标识,AppEUI标识应用提供方,AppKey是根密钥,用于加密Join Accept。入网成功后,终端获得DevAddr、NwkSKey和AppSKey,后续通信使用这些会话密钥。下面是一段典型的入网参数配置示例,字段含义与LoRaWAN 1.0.x规范一致:

DevEUI  = 70B3D57ED0000001   // 终端唯一标识,8字节
AppEUI  = 70B3D57ED0000000   // 应用标识,8字节
AppKey  = 2B7E151628AED2A6ABF7158809CF4F3C  // 根密钥,16字节

// 入网成功后由网络服务器分配
DevAddr = 26011F2A           // 32位设备地址
NwkSKey = ...                // 网络会话密钥,16字节
AppSKey = ...                // 应用会话密钥,16字节

// 上行帧计数器,从0开始,每发一帧加1
FCntUp  = 0
FCntDown = 0

需要特别注意的是帧计数器FCnt。终端和网络服务器各自维护上下行计数器,一旦计数器不同步,网络服务器会丢弃帧。终端在复位后如果不清零FCnt,而网络服务器仍保留旧值,就会出现"发得出去、收不到"的现象。实际调试中,可以通过关闭帧计数器校验或重新入网来恢复。对于低功耗终端,建议在非易失存储中定期保存FCnt,避免掉电后计数器回退。

OTAA入网时,DevNonce必须每次递增或随机变化。如果终端反复使用相同的DevNonce,网络服务器可能拒绝入网请求。部分LoRaWAN 1.0.4之前的实现要求DevNonce单调递增,设计时应在复位后从存储中读取上次值并加一。

综合来看,终端角色可以概括为:在PHY层按网络指令选择调制参数,在MAC层按类别规则调度收发窗口,在入网阶段完成密钥协商,在运行阶段维护帧计数器和ADR状态。Class A/B/C的选择不是协议限制,而是功耗、时延和供电条件之间的工程权衡。理解这三层关系,后续设计天线、电源和固件状态机时,才能做出与场景匹配的决策。