4. 创建第一个Thread终端设备工程

在完成开发环境准备之后,真正让Thread终端“跑起来”的第一步,是在Simplicity Studio中建立一个可编译、可烧录、可观察日志的工程。本节以EFR32MG系列无线SoC(例如EFR32MG21或EFR32MG24)为目标,使用Gecko SDK中的Thread示例工程,完成从新建项目到串口日志确认的完整闭环。整个过程的核心不是“点几个按钮”,而是理解工程结构、构建配置、烧录接口与日志通道之间的对应关系。

一、新建Thread工程:从示例到可编译项目

打开Simplicity Studio 5,连接开发板(如BRD4180B/BRD4186A等),在Launcher视图中选中目标设备。点击“Create New Project”,在“Example Projects”中筛选“Thread”。Silicon Labs的Gecko SDK通常提供几类与Thread相关的示例:Thread - SoC - Empty(最小Thread节点,适合作为终端设备起点)、Thread - SoC - Sensor(带传感器采集与上报逻辑)、Thread - SoC - Leader(可成为Leader的完整节点)以及Thread - SoC - Sleepy End Device(休眠终端)。对于“第一个终端设备”,建议选择Thread - SoC - Empty,因为它保留了Thread协议栈与CLI,但去掉了业务逻辑,便于观察入网与状态变化。

选择工程后,Simplicity Studio会提示SDK版本与工具链(GCC)。确认后生成工程,工程目录中关键文件包括:*.slcp(项目配置,定义组件与依赖)、*.sls(SDK配置)、autogen/(自动生成的初始化代码)、main.c(应用入口)、app.c(应用逻辑与事件处理)。其中.slcp是理解工程的关键:它决定了是否启用Thread CLI、是否启用NV存储、是否启用休眠等。若后续需要终端设备低功耗,可在.slcp的“Software Components”中搜索“Sleepy”并添加相关组件。

Thread终端工程:从新建到日志确认的关键链路 ① 新建工程 Launcher → Create New Project 筛选:Thread 选择:Thread - SoC - Empty SDK:Gecko SDK 4.x 工具链:GCC ARM 生成 .slcp / main.c / app.c 关键:CLI组件默认启用 ② 编译与烧录 Project → Build Project 输出:*.hex / *.bin / *.out Debug Adapters → 选择J-Link Flash:Erase + Program 复位后运行 观察:LED/串口输出 关键:烧录前确认芯片型号 ③ 串口日志查看 Console → Serial 1 波特率:115200 8N1 观察启动打印与CLI提示符 输入:help / state / panid 查看:role、RLOC、Leader 判断:是否进入child/router 关键:日志是调试第一入口 ④ 基础调试:从日志到状态判断 启动阶段 打印版本、复位原因 Thread stack init CLI ready 判断:无HardFault 入网阶段 输入:state 输出:detached/child 输入:panid / channel 判断:是否attach成功 角色确认 输入:role 输出:child / router 输入:rloc16 判断:地址是否有效 异常排查 无日志:波特率/引脚 无法入网:信道/密钥 反复复位:供电/看门狗 判断:先看日志再改配置 注:图中参数为教学示例,实际以所用开发板与SDK版本为准

二、编译:理解构建输出与常见错误

工程生成后,右键工程选择“Build Project”。Simplicity Studio会调用GCC完成编译,输出目录通常为GNU ARM v10.3.1 - Default/,其中包含.out(ELF)、.hex(Intel HEX)和.bin(二进制)文件。编译成功的标志是Console中出现“Build Finished”,且无error。若出现“undefined reference to otCli...”一类错误,通常是因为.slcp中未启用Thread CLI组件;若出现“region FLASH overflow”,说明代码量超过所选芯片Flash容量,需要更换芯片型号或裁剪组件。

编译阶段值得关注的是链接脚本与内存布局。Thread协议栈、NV存储、CLI都会占用Flash与RAM。对于EFR32MG21(1024KB Flash / 96KB RAM),Empty示例通常占用约200KB Flash、30KB RAM,剩余空间足够添加传感器与业务逻辑。若后续要加入OTA,需要预留Bootloader区域,此时应在.slcp中启用“Bootloader”相关组件并重新规划分区。

三、烧录:从J-Link到芯片运行

烧录前先确认开发板与调试器连接正常。在Simplicity Studio的“Debug Adapters”视图中应能看到J-Link设备。右键工程选择“Run As → Silicon Labs ARM Program”,工具会执行Erase、Program、Verify、Reset。若使用命令行,也可用commander工具:

commander flash --device EFR32MG21A010F1024IM32 \
  GNU\ ARM\ v10.3.1\ -\ Default/thread_soc_empty.hex

烧录完成后,芯片会自动复位并运行。此时若开发板上有LED,部分示例会以闪烁表示运行状态;但更可靠的观察方式是串口日志。需要注意的是,烧录前必须确认芯片型号与工程目标一致,否则会出现“Flash size mismatch”或烧录后无反应。

四、串口日志:终端调试的第一窗口

Thread终端工程默认启用CLI,并通过UART输出日志。在Simplicity Studio中打开“Console”视图,选择“Serial 1”,波特率设为115200,数据位8,无校验,1位停止位。复位开发板后,应能看到类似以下输出(示例):

Thread SoC Empty Example
Reset cause: Power-on
NVM3: initialized
Thread stack initialized
CLI ready
>

出现>提示符后,即可输入CLI命令。常用命令包括:help查看命令列表,state查看当前Thread状态(detached/child/router/leader),role查看角色,panid查看PAN ID,channel查看信道,rloc16查看短地址。若输入state返回detached,说明设备尚未入网;若返回child,说明已作为终端加入网络。

若串口无任何输出,优先检查三点:一是Console是否选对串口;二是波特率是否为115200;三是开发板UART引脚是否与工程默认配置一致。EFR32MG系列常见默认UART为USART0,TX/RX引脚在.slcp的“Board”组件中可查看。

五、基础调试:从日志判断入网与角色

第一个终端设备的目标不是立刻组网,而是确认“工程能跑、日志能看、状态能查”。建议按以下顺序验证:复位后看到启动日志;输入help有响应;输入state返回detached;若附近有已建立的Thread网络且密钥匹配,设备会自动尝试attach,再次输入state可能变为child。此时输入rloc16应返回一个16位地址(如0x5400),输入role返回child,说明终端已成功入网。

若设备反复打印“Attach attempt failed”,常见原因是信道不匹配或网络密钥不一致。可在CLI中用channel查看当前信道,用panid查看PAN ID,并与边界路由器(Leader)侧配置比对。若使用默认随机密钥,需确保双方使用同一组networkkey。调试阶段建议先用固定信道(如15)和固定PAN ID,减少变量。

不要在没有日志输出的情况下盲目修改代码。Thread终端的问题大多可以通过CLI日志定位:先看复位原因,再看协议栈初始化,最后看attach状态。日志是“第一现场”,比反复烧录更高效。

六、可复用的工程检查清单

检查项预期结果异常处理
工程是否包含Thread CLI组件.slcp中可见“Thread CLI”添加组件后重新Build
编译是否无errorConsole显示Build Finished检查Flash溢出或未定义引用
烧录是否成功Program/Verify通过确认芯片型号与调试器连接
串口是否有启动日志出现“CLI ready”与提示符检查波特率、串口选择、UART引脚
state命令是否响应返回detached/child等确认CLI已启用且输入回车
是否成功入网state为child,rloc16有效核对信道、PAN ID、networkkey

完成以上步骤后,你已经拥有一个可编译、可烧录、可观察日志的Thread终端工程。它既是后续添加传感器、低功耗、OTA等功能的基础,也是排查更复杂网络问题的起点。下一阶段的所有调试,几乎都会回到这条链路:工程配置 → 编译烧录 → 串口日志 → CLI状态判断。