最近,笔者在学习和搭建 Zephyr RTOS 的开发环境,整个过程虽耗费了不少精力,但最终调试环境成功运行。
初步体验下来,Zephyr 的架构较为复杂,可能并不适合嵌入式开发的初学者。相比之下,MDK搭配uC/OS或许更适合入门教学。不过,从实际项目开发的角度看,Zephyr 提供了许多强大的特性。例如,其设备树(Device Tree)的实现,对驱动开发非常友好,能显著提升开发效率。
在官方提供的 STM32H743ZI-Nucleo 开发板上,运行基础的 LED 闪烁和 Hello World 例程非常顺利,调试过程也未见异常。
然而,当笔者尝试测试开发板的以太网功能时,问题接踵而至。无论怎样修改和编译代码,系统总是出现总线故障(Bus Fault)。
起初询问 AI 助手,其建议可能是 MPU(内存保护单元)的配置问题。由于笔者对 MPU 及 Zephyr 在 VSCode 下的高级调试技巧并不十分熟悉,此前仅会使用基本断点,因此花费了大量时间在此方向上排查,却一无所获。
另一个关键的“坑”在于,Zephyr 的线程栈底部有一部分区域似乎未用于错误检测,这导致笔者迟迟没有怀疑到栈溢出问题上。后来,通过使用内存监视(Watch)功能观察栈指针的变化,才最终确认问题根源就是栈溢出,而此时串口并未打印任何相关的错误信息。
解决了各个任务线程的栈溢出问题后,系统终于能够正常运行。但随即出现了新的挑战:网络 Ping 不通。

根据目前的体验,Zephyr 还难以真正做到“开箱即用”。运行简单的示例可能没问题,但对于功能稍复杂的模块,若缺乏足够的嵌入式系统及 Zephyr 框架本身的开发调试经验,会遇到不少障碍。例如,在尝试调试 STM32F1 平台时也遇到了不顺利的情况。此外,开启调试日志打印时,曾直接导致递归调用使栈空间耗尽,这个问题似乎尚未被广泛讨论。
尽管如此,与从零开始实现一个实时操作系统的所有底层功能相比,使用 Zephyr 仍然极大地简化了开发流程。它集成了众多成熟组件,为复杂的嵌入式项目提供了坚实的基础。
|