3. OpenThread协议栈架构解析
OpenThread 是 Google 开源的 Thread 协议实现,在 nRF52/nRF53 系列 SoC 上通常以库的形式与 Zephyr RTOS 协同工作。理解它的分层结构,是后续调试入网、路由、低功耗和边界路由器功能的基础。本节从协议栈分层、线程角色与设备类型、网络接口抽象、以及与 Zephyr 的集成方式四个角度展开,帮助你在阅读源码和配置 Kconfig 时能准确定位每一层负责什么。
一、OpenThread 在 nRF 上的分层结构
OpenThread 采用经典的 IEEE 802.15.4 + IPv6 协议栈分层模型,自下而上大致可分为五层:
- Radio 层:由 nRF 的 802.15.4 硬件外设(RADIO、TIMER、AES CCM、RNG)驱动,负责 2.4 GHz 信道收发、CSMA/CA 退避、ACK 与自动重传。在 Zephyr 中由
nrf_802154驱动实现,OpenThread 通过otPlatRadio*平台接口调用它。 - MAC 层:处理扩展/短地址、PAN ID、帧过滤、Beacon、扫描与关联,对应 IEEE 802.15.4 MAC 子层。
- 6LoWPAN 与 IPv6 层:完成 IPv6 报头压缩(HC1/HC2)、分片重组、邻居发现(ND)、Mesh Link Establishment(MLE)与 Mesh 路由(基于 RPL 的收敛)。
- 传输层:UDP 为主,CoAP 常用于应用层;TCP 在 OpenThread 中支持有限。
- 应用与 API 层:对外暴露
ot*C API,向上提供 CoAP、DNS、SRP、Joiner/Router 等能力。
在 nRF 上,OpenThread 与 Zephyr 的边界由 openthread 模块和 nrf_802154 驱动共同定义:Zephyr 提供线程、时钟、日志、随机数、非易失存储等基础服务,OpenThread 通过 otPlat* 系列回调使用它们。下图展示了这一分层与接口关系。
二、线程角色与设备类型
Thread 网络中的节点按职责分为若干角色,理解它们有助于判断设备在拓扑中的位置和应配置的参数。
- Leader:每个 Thread 分区(Partition)中唯一,负责分配 Router ID、维护分区数据、决定 Router 升级/降级。它本身也是一个 Router。
- Router:具备转发能力,维护路由表,参与 MLE 和 RPL。Router 数量由
OT_MAX_ROUTERS限制,默认 32。 - REED(Router-Eligible End Device):具备成为 Router 的资格,但当前以 End Device 身份工作,在需要时可由 Leader 升级为 Router。
- End Device(SED/MED):不转发流量。SED(Sleepy End Device)周期性休眠,通过轮询父节点获取下行数据;MED(Minimal End Device)保持接收。
- Child:相对于父节点的角色,任何 End Device 都是某个 Router 或 Leader 的子节点。
设备类型则从“是否具备完整 Thread 协议栈”角度划分:Full Thread Device(FTD)包含 Router、REED、MED,拥有完整路由与 MLE 能力;Minimal Thread Device(MTD)只实现必要部分,通常是 SED,用于电池供电的传感器。在 nRF 上通过 Kconfig 选择:CONFIG_OPENTHREAD_FTD=y 或 CONFIG_OPENTHREAD_MTD=y,二者互斥。
三、网络接口抽象
OpenThread 通过 otPlatRadio 接口与底层射频驱动解耦,关键回调包括:
otPlatRadioEnable/Disable:使能或关闭射频。otPlatRadioTransmit:提交待发送帧,完成后触发otPlatRadioTxDone。otPlatRadioReceive:设置接收信道并启动接收,收到帧后回调otPlatRadioReceiveDone。otPlatRadioEnergyScan、otPlatRadioGetRssi:能量扫描与 RSSI 读取。otPlatRadioSetPanId/ShortAddress/ExtendedAddress:设置过滤参数。
在 Zephyr 中,这些回调由 modules/openthread 下的移植层实现,最终调用 nrf_802154 驱动。这样 OpenThread 核心代码无需关心 nRF 具体寄存器,便于跨平台复用。调试时若发现射频不工作,应优先检查 nrf_802154 是否初始化成功、中断优先级是否与 Zephyr 冲突。
四、与 Zephyr 的集成方式
在 nRF Connect SDK 中,OpenThread 以 Zephyr 模块形式集成,典型配置如下:
CONFIG_NETWORKING=y
CONFIG_OPENTHREAD=y
CONFIG_OPENTHREAD_FTD=y
CONFIG_OPENTHREAD_SHELL=y
CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER=y
CONFIG_NRF_802154_RADIO_DRIVER=y
CONFIG_OPENTHREAD_THREAD_VERSION_1_3=y
集成要点包括:
- 线程模型:OpenThread 在 Zephyr 中运行于独立线程,通过
otTaskletsProcess和消息队列与驱动交互,避免在中断中执行耗时逻辑。 - 时钟:
otPlatAlarmMilli基于 Zephyr 内核定时器实现,用于 MLE、CoAP 重传等超时。 - 非易失存储:网络参数(如 Active Dataset)通过 Zephyr NVS 保存,掉电后可恢复入网状态。
- 日志:OpenThread 日志可重定向到 Zephyr
LOG子系统,通过CONFIG_OPENTHREAD_LOG_LEVEL控制级别。 - Shell:启用
CONFIG_OPENTHREAD_SHELL后可在串口使用ot命令,如ot state、ot ipaddr、ot joiner start,是调试入网最直接的手段。
ot state 能进入 leader 或 router,再逐步加入 Joiner、边界路由器等角色。若 ot state 长期停留在 detached,应检查信道、PAN ID、网络密钥是否与目标网络一致,并确认 nrf_802154 驱动已正确初始化。
掌握以上四部分后,你就能在 nRF 上准确定位 OpenThread 的每一层职责,并根据设备角色选择合适的 Kconfig 组合,为后续的入网、路由与低功耗调试打下基础。