Zephyr 移植、测试与调试指南

Zephyr 移植、测试与调试指南

1. 新板级移植的分层

1
2
3
4
5
Architecture(通常复用)
└─ SoC support(尽量复用已有系列)
└─ Board DTS/defconfig
└─ Shield/overlay
└─ Application

若芯片已有 SoC 支持,新板通常只需:

  • board.yml
  • board .dts
  • <board>_defconfig
  • 可选 Kconfig、board.cmake、runner;
  • pinctrl/connector 描述。

不要把应用策略和大量功能选项塞进 board defconfig;board 默认值应主要描述板上始终存在的硬件能力。

2. Board 移植步骤

  1. 选择最接近的现有 board;
  2. 确认 SoC、flash、SRAM 容量;
  3. 创建 board.yml
  4. include 正确 SoC/参考板 .dtsi/.dts
  5. 配置 clocks;
  6. 配置 console 和 pinctrl;
  7. 启用必要 GPIO/interrupt controller;
  8. 添加 aliases/chosen;
  9. 定义 flash partitions;
  10. 设置最小 defconfig;
  11. 编译 samples/hello_world
  12. 再依次验证 GPIO、UART、I2C/SPI、flash、watchdog;
  13. 添加 board test/CI allowlist。

3. 新 SoC 移植

除 DTS 外还需:

  • SoC Kconfig;
  • CMake/runner/toolchain 选择;
  • reset/early init;
  • clock control;
  • interrupt controller;
  • system timer;
  • pinctrl;
  • memory map/linker;
  • cache/MPU/MMU;
  • reboot、poweroff、SMP;
  • HAL module glue。

优先把可复用寄存器操作放入 driver/HAL,把启动时序和 SoC 特有 glue 放入 soc/

4. Driver 验证层次

  1. 编译期:无实例/单实例/多实例;
  2. init:依赖设备和错误返回;
  3. API 正常路径;
  4. 参数边界;
  5. interrupt/callback;
  6. timeout/abort;
  7. 并发;
  8. runtime PM;
  9. suspend/resume;
  10. fault injection:bus NACK、DMA error、设备掉线。

能编译不代表 DTS binding、pinctrl 和真实硬件时序正确。

5. Ztest

框架路径:

1
2
subsys/testsuite/ztest/
include/zephyr/ztest.h

典型:

1
2
3
4
5
6
ZTEST_SUITE(suite, NULL, setup, before, after, teardown);

ZTEST(suite, test_case)
{
zassert_equal(actual, expected);
}

支持:

  • suite/test fixture;
  • parameterized/generated tests;
  • userspace tests;
  • expected fail/skip;
  • mock/fake;
  • rules 和 test phases。

测试不应依赖执行顺序,fixture 应恢复全局状态。

6. Twister

Twister 读取 testcase.yaml

1
2
3
4
5
6
tests:
subsystem.feature:
tags:
- feature
platform_allow:
- native_sim

作用:

  • 构建矩阵;
  • 运行 native/QEMU/硬件测试;
  • 过滤 architecture、toolchain、RAM/flash;
  • 解析 harness 输出;
  • 生成报告和覆盖率。

常用:

1
2
3
4
west twister -T tests/path
west twister -T tests/path -p native_sim
west twister -T tests/path --inline-logs
west twister -T tests/path --coverage

对 board/driver 代码至少增加 compile-only 和一个可执行场景。

7. Native simulation 与 QEMU

  • native_sim:把 Zephyr 编译为 host process,适合内核/协议/单元测试;
  • QEMU:模拟 CPU、interrupt 和部分外设,更接近目标架构;
  • unit testing architecture:隔离编译特定库;
  • hardware map:Twister 管理真实板。

硬件相关问题仍需板上测试,尤其是 DMA、cache、flash 掉电和时钟。

8. 调试构建

常用配置:

1
2
3
4
5
6
7
8
9
CONFIG_DEBUG=y
CONFIG_DEBUG_INFO=y
CONFIG_ASSERT=y
CONFIG_THREAD_NAME=y
CONFIG_THREAD_STACK_INFO=y
CONFIG_INIT_STACKS=y
CONFIG_STACK_SENTINEL=y
CONFIG_THREAD_ANALYZER=y
CONFIG_LOG=y

调试功能会改变 timing、stack 和 image size。最终结论需在接近 release 的配置下复测。

9. GDB

1
2
west debug -d build/<name>
west attach -d build/<name>

关键检查:

1
2
3
4
5
6
7
info threads
thread apply all bt
p _current
p _kernel
p/x <device>
info registers
disassemble

优化构建中变量可能被优化掉,必要时仅对问题文件降低优化,而不是长期全局 -O0

10. 启动问题

无输出时按顺序:

  1. reset vector 是否到达;
  2. flash/link address 是否正确;
  3. clock 是否工作;
  4. z_cstart() 是否执行;
  5. console device 是否 status okay;
  6. UART pinctrl/baud;
  7. console driver Kconfig;
  8. init function 返回值;
  9. logging backend 是否启动。

早期 PRE_KERNEL 问题优先用 GPIO、debugger 或 printk,logging 可能尚不可用。

11. Device init 问题

检查构建产物:

1
2
3
rg '<node-name>|<compatible>' build/zephyr/zephyr.dts
rg 'CONFIG_<DRIVER>' build/zephyr/.config
rg '__device_dts_ord' build/zephyr/include/generated/zephyr/devicetree_generated.h

运行时:

  • device_is_ready()
  • init result;
  • shell device list;
  • dependency handles;
  • clock/pinctrl/controller 状态。

12. HardFault/Fatal

记录:

  • reason;
  • exception stack frame;
  • PC/LR/SP;
  • current thread name;
  • stack bounds;
  • fault status registers;
  • build ID/firmware version。

地址解析:

1
2
addr2line -e build/zephyr/zephyr.elf -f -C <pc>
objdump -dS build/zephyr/zephyr.elf

必须使用与设备完全一致、未 strip 的 ELF。

13. Stack 分析

方法:

  • thread analyzer;
  • k_thread_stack_space_get()
  • stack sentinel/canary;
  • compiler stack usage 文件;
  • map 和静态 call graph;
  • 压力场景下 high-water mark。

分别评估:

  • main stack;
  • ISR stack;
  • system workqueue;
  • logging;
  • shell;
  • network RX/TX;
  • 每个业务线程。

14. 性能与实时性

测量对象:

  • ISR latency;
  • ISR-to-thread latency;
  • context switch;
  • mutex contention;
  • workqueue delay;
  • timeout jitter;
  • flash operation blocking;
  • network tail latency。

使用 cycle counter、timing API、tracing/SystemView。避免在被测路径中大量 logging。

15. 内存分析

1
2
west build -d build/<name> -t rom_report
west build -d build/<name> -t ram_report

重点:

  • .text/.rodata
  • .data/.bss/noinit
  • iterable metadata;
  • thread stacks;
  • heap;
  • network buffers;
  • logging buffer;
  • filesystem cache。

功能关闭后若体积未下降,检查引用、select、always-linked library 和 LTO。

16. 配置归档

发布应保存:

  • source commit;
  • west manifest revisions;
  • toolchain/SDK;
  • board/revision;
  • build command;
  • .config
  • zephyr.dts
  • map/ELF;
  • signing metadata;
  • generated version/build descriptor。

只保存 prj.conf 无法重现完整构建。

17. 安全检查

  • userspace/MPU 是否按威胁模型启用;
  • stack protection;
  • fortify;
  • assert 在 release 的策略;
  • entropy/CSPRNG;
  • management shell/MCUmgr 暴露;
  • debug port;
  • firmware signing/rollback;
  • persistent data 权限;
  • network credentials;
  • fatal/coredump 是否泄露敏感信息。

18. 常见误区

  • 把 board defconfig 当应用配置;
  • 手改生成文件;
  • 只看 prj.conf 不看 .config
  • DEVICE_DT_GET() 后不检查 ready;
  • 在 ISR/workqueue 中做长阻塞;
  • 用 heap 解决所有实时对象;
  • 认为 logging 不影响时序;
  • 忽略 MCUboot header/trailer 对 flash 容量的影响;
  • 只测试正常升级,不做掉电和回滚。

文章互动

阅读 --

留言

0 条留言

正在加载留言…