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”并添加相关组件。
二、编译:理解构建输出与常见错误
工程生成后,右键工程选择“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,说明已作为终端加入网络。
.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组件 | .slcp中可见“Thread CLI” | 添加组件后重新Build |
| 编译是否无error | Console显示Build Finished | 检查Flash溢出或未定义引用 |
| 烧录是否成功 | Program/Verify通过 | 确认芯片型号与调试器连接 |
| 串口是否有启动日志 | 出现“CLI ready”与提示符 | 检查波特率、串口选择、UART引脚 |
| state命令是否响应 | 返回detached/child等 | 确认CLI已启用且输入回车 |
| 是否成功入网 | state为child,rloc16有效 | 核对信道、PAN ID、networkkey |
完成以上步骤后,你已经拥有一个可编译、可烧录、可观察日志的Thread终端工程。它既是后续添加传感器、低功耗、OTA等功能的基础,也是排查更复杂网络问题的起点。下一阶段的所有调试,几乎都会回到这条链路:工程配置 → 编译烧录 → 串口日志 → CLI状态判断。