zephyrrtos.cnZephyr 生态 · 中国驱动软件系统

一台主机挂两块 STM32F030:一块没焊晶振看着像坏板,真因是时钟驱动在等一颗不存在的晶体

2026-11-03 · 场景:一台 RK3588 主机(rock-5b-plus)用 USB 同时挂着两块 STM32F030F4P6——一块用片上 ADC 做 8 通道采样,一块外挂 ADS1256(8 通道 24 位)做高精度采样。这类双板环境真正难的从来不是写应用,而是三件事:能不能编译(工具链版本互相咬合)、能不能上板(两块板的烧写通道与控制台串口不能搞混)、装不装得下(16 KB flash 是硬约束)。…

2026-11-03

工程一台主机挂两块 STM32F030:一块没焊晶振看着像坏板,真因是时钟驱动在等一颗不存在的晶体

场景:一台 RK3588 主机(rock-5b-plus)用 USB 同时挂着两块 STM32F030F4P6——一块用片上 ADC 做 8 通道采样,一块外挂 ADS1256(8 通道 24 位)做高精度采样。这类双板环境真正难的从来不是写应用,而是三件事:能不能编译(工具链版本互相咬合)、能不能上板(两块板的烧写通道与控制台串口不能搞混)、装不装得下(16 KB flash 是硬约束)。这次最值钱的一条记录是:板 2 烧完完全没输出、也不报错——查下去是板子上没有焊 8 MHz HSE 晶振,而基础板 DTS 写着 &clk_hse status="okay",于是时钟驱动在 set_up_fixed_clock_sources() 的 while (LL_RCC_HSE_IsReady() != 1) 里死等一颗不存在的晶体。

rock-5b-plus(开发主机)
  Zephyr 工作区 /mnt/raid1/shared/zephyrproject · .venv312(Python 3.12.14 · cmake 4.4.4 · ninja 1.13.2)· SDK arm-zephyr-eabi 14.3.0
  hwmap.yaml:板1 = stm32f030_demo     板2 = stm32f030_demo_no_hse
        │ west flash --dev-id 000069610657              │ west flash --dev-id 000069610517
        ▼                                               ▼
  板1 · stm32f030_demo                             板2 · stm32f030_demo_no_hse(无 HSE 晶振)
  ADC1 PA0–PA7 · 12 bit · ACQ 240 周期             外挂 ADS1256 · 8ch · 24 bit · vref 2.5 V
  丢首样本 → 均值 → adc_power_measure              SPI1 PA5/PA6/PA7 · CS PA4 · DRDY PA8 · RESET PB1 · SYNC PA3
  USART1 → J-Link VCP(ttyACM0)                   adc_sequence / ads1256_async(单线程内核)
        │                                           USART1 → CH340(ttyUSB0)
        ▼                                               │
  #CFG,ch=8,… / D,<ms>,<8 个原始码>                 ADC sequence reading / ADC input N value: X uv
        └───────────► 主机脚本 / twister 按协议解析、积分功耗 ◄───────────┘
  • 没有晶振要建模成板级属性:新 `stm32f030_demo_no_hse` 变体把 &clk_hse 设为 disabled,PLL 改由 HSI 供(HSI 8 MHz → PLL 输入 HSI/2 = 4 MHz → mul = 12 → 48 MHz,与晶振版同频);其余 SoC/UART 引脚/115200/runners 与基础板一致
  • 单线程内核是两块板共用的底层改造:CONFIG_MULTITHREADING=n 时内核没有信号量/队列,而 ADC 与 SPI 驱动都要 k_sem_take → 链接失败。补齐 10 个 kernel/*_single.c(共 1451 行)并顺手修 spi_context.h 里对 Z_SEM_INITIALIZER 的无条件依赖。收益:adc_sequence 15596 B → 13340 B(81.42%)
  • ADS1256 驱动 620 行(阻塞式 spi_transceive_dt)+ Kconfig + binding,接线全部归板 DTS;踩到一次 API 漂移:SPI_DT_SPEC_INST_GET(n, op, 0) 在当前 main 只接受 2 个参数(编译期直接报错)
  • 「省空间开关」在两个版本上结论相反:旧分支有用的四个开关(SPI_STM32_INTERRUPT=n、NUM_PREEMPT_PRIORITIES=0、CORTEX_M_FAULT_FULL_PROCESS=n、MINIMAL_LIBC_LL_PRINTF=y)实测全部 16188 → 16188 B 空转——LTO 已把故障路径裁到 262 B。要再省只能砍功能,不是调开关
  • 尺寸与字节构成:ads1256_async 16188 B(98.80%),只剩 196 B;按符号聚合 35.7% 是 STM32 驱动、27.1% 零散小符号、13.8% 内核+arch、12.8% ADC、7.5% libc/printk

验证与边界:烧写后用 J-Link 回读 flash 头部与本地镜像逐字节比对,两次都一致;两块板串口抓取都打通(板 2 的 0 uv 是因为 8 路输入真的接地)。已知限制:ADS1256 镜像只剩 196 B(1.2%),log 改单字符 printk 才装得下;RAM 还有余量(三个 1 KB 栈可减半,约能到 50%);fault.c 裁剪那版基于旧上游、整份拿来会回退约 500 行新代码而收益接近零,明确不做;与内部 ADC 那条 lc_power_shield 分支是两条并行线,尚未合并。代码与文档在 zephyrrtos_china/zephyr 的 board-no-hse 分支(commit 5e92f1c,私有库需账号);提交同样标了 Assisted-by: DSH with deepseek-v4-flash。

↗
分享到朋友圈

点击右上角 ··· → 选择「分享到朋友圈」。微信不提供网页直接分享接口,这一步需要在微信内完成。想自己写配文?先点本条动态的「复制图文摘要」(已带 #zephyrrtos_cn),回到朋友圈粘贴即可。

问智能体 Zephyr 问题问答 · 直接问智能体