跳到主要内容

学习路线

这里记录我们使用 Zephyr 的过程:读一段源码,提出一个问题,改动程序,再用构建结果和板上现象检查理解。遇到结论不成立的情况,也保留原因和适用条件。

目前以手头的 ESP32-S3-Touch-LCD-1.28 为实验载体,代码维护在独立的 esp32-zephyr 仓库。后续换板时,继续比较哪些应用代码能够复用、哪些配置必须调整,不把某块板的成功经验写成普遍结论。

快速体验与学习主线​

Hello World、背光 PWM 和 LVGL 圆屏用于检查工具链和硬件,也可以先看运行效果。它们放在“示例程序”中;后面的讨论再回到这些程序,分析配置、调度和外设之间的关系。

学习主线按下面顺序阅读:

顺序现有笔记可以一起验证的问题
1Zephyr 的组成说清内核、驱动、板卡和应用的分工
2选择 Linux 环境、west 使用指南、初始化工作区安装依赖,理解清单管理,确认工具与源码位置
3应用与构建不复制整套 sample,建立一个独立应用
4Kconfig定义自己的打印周期,查看最终值
5设备树从 C 代码追踪到 GPIO2 的板卡配置
6线程、时间和驱动调用区分休眠、忙等、初始化失败和 API 失败
7自己的固件仓库保存应用和配置,让同伴能够重新构建
8板卡适配与移植判断该写 overlay、板卡定义还是新驱动

这些是已有的基础入口,还不等于完整的系统开发笔记。特别是线程同步、故障分析、联网和升级,目前需要继续实验与补充。

后续研究路径​

参考从工具、硬件描述到内核、可靠性和升级的顺序,我们用同一个小项目逐步增加功能:先周期打印,再采集和显示数据,再接入网络,最后处理故障与升级。每个阶段单独记录,不为了展示完整功能一次打开所有子系统。

1. 开发工具​

讨论 west 怎样选择工作区和依赖,CMake 怎样选择应用,构建缓存为什么会造成误判。已有 west 使用指南 和 工作区说明;下一步补 VS Code 的源码跳转、compile_commands、构建任务和调试配置。

动手内容:在独立代码仓库编译 learning 应用,修改一个配置,找出最终 .config 和编译命令的变化。先让命令行构建可复现,再把相同命令接到编辑器,避免 IDE 隐藏真实参数。

记录依据:应用提交、Zephyr 提交、工具版本、构建目录和日志。断点调试还要确认板卡调试接口、连接方式与 runner,不能把串口 monitor 当成 GDB 调试器。

2. 硬件描述与驱动​

沿着原理图、DTS、binding、设备实例和驱动 API 追踪一次操作。已有 设备树 和 板卡移植,后续增加 I2C/SPI 设备的完整分析。

动手内容:使用同一份 GPIO 应用,通过不同 overlay 选择输出;再给第二块实际拿到的 ESP32 板建立配置,比较需要改动的文件。更换显示器时,也要检查分辨率、驱动、初始化与接口能力。

设备树可以减少硬件参数写死在业务代码中的情况,但不代表“代码与硬件彻底解耦”。缺少驱动、接口能力不同或时序要求改变时,代码仍可能需要调整。

记录依据:原理图对应引脚、最终 zephyr.dts、设备 ready 状态、总线调用返回值和实际现象。

3. 内核与并发​

现有 线程与设备接口 只覆盖入门概念,后续需要独立讨论优先级、信号量、互斥锁、消息队列、Workqueue 和定时器。

动手内容:把采集和界面更新拆成不同任务,通过消息队列交接数据;比较忙等与阻塞等待,再观察队列积压、资源竞争和超时。构造可控的锁顺序错误分析死锁,随后固定锁顺序或改用消息传递,验证问题是否消失。

同时检查把耗时任务塞进公共 Workqueue 的影响。LVGL 操作需按当前版本的同步规则进行,不能让所有线程任意修改同一个界面对象。

记录依据:带时间戳的事件、任务优先级、队列容量、栈占用与触发步骤。先解释时序,再讨论优化。

4. 故障分析与恢复​

研究硬件看门狗与任务健康检查的分工,以及异常信息、线程栈、复位原因和 Coredump 怎样帮助复现故障。这一阶段尚未完成实验。

动手内容:先让某个任务可控地停止报告状态,观察是否能识别“部分任务卡住”;再在测试固件中触发异常,保存对应 ELF 和可用的故障信息,尝试定位出错位置。不能靠一个仍在运行的喂狗线程就断言整个系统健康。

MPU、用户态隔离、栈保护和 Coredump 后端要按当前 ESP32-S3/Zephyr 组合分别检查。参考规划使用的 STM32 板与本板不同,不能照搬其 MPU 配置,也不把这些机制写成已经在本板验证通过。

记录依据:故障触发方式、检测延迟、复位原因、保留的上下文以及恢复后是否满足预期。只有完成这些测试,才讨论可靠性,不能用“工业级”替代验证结果。

5. 网络与固件升级​

先分析网络连接、Socket、超时和断线恢复,再逐步增加 MQTT 与 TLS;最后研究 MCUboot 的镜像、分区、签名、确认和回退。这一阶段目前是研究计划。

动手内容:从向本地测试服务发送数据开始,断网后观察任务是否被长期阻塞、数据如何处理;升级实验先设计 Flash 布局和恢复路径,再验证新镜像启动、确认,以及支持的回退机制。

本项目目前使用 ESP Simple boot,不能在现有镜像上只加一个 OTA 开关就声称完成 MCUboot 升级。需要先核对该版本的 ESP32 集成、sysbuild 流程、Flash 余量与具体升级模式;双槽也不等于任意模式都具有相同回退行为。

记录依据:连接与重连日志、镜像版本、分区地址、签名检查结果和故障恢复记录。签名私钥、网络凭据留在本地,不进入示例仓库。

记录方式​

每次笔记围绕一个具体问题展开:当前理解是什么,依据哪份源码,改了哪个条件,观察到了什么,下一步还有哪里不确定。软件编译、硬件运行与推测分开标注,不把预期输出当成实测日志。

近期先完成 west 与独立应用仓库的衔接,再补 VS Code;之后进入线程同步与 Workqueue。后续主题有实际代码和记录后再新增章节,不提前堆满只有标题的目录。

实验基线​

  • 安装说明:Ubuntu / Fedora 并列可选,只执行自己系统对应的依赖命令,后续共用工作区流程。
  • Zephyr:main 的固定提交 52b48529aecc3ad0ef9b159996bdb5d2b3e5b794,开发版本 4.4.99。
  • 工具链:SDK 1.0.1,Python 3.12;当前命令统一 main 工作区。
  • 示例板卡:Waveshare ESP32-S3-Touch-LCD-1.28,主核目标 esp32s3_touch_lcd_1_28/esp32s3/procpu。

本机固件编译在 Fedora 上完成,Ubuntu 安装流程尚未在全新机器复验。旧版 4.2.0 的 Hello World、背光已有实板记录;main 构建及 LVGL 的实板状态分别写在对应章节,不能用旧固件的运行结果替代新固件验收。

阅读代码的约定​

CONFIG_* 是软件配置,DT_* 一般来自设备树,k_* 通常是内核 API。先记住各自要查哪里,不需要背完全部函数。

不认识的参数先回到最终 .config 或 zephyr.dts 查,不往项目里追加来历不明的配置。实验时每次只改一个条件,并留下源码提交和串口日志。

已有环境从 自己的最小应用 开始;尚未见过板卡工作,可先运行 Hello World。