工程一台主机挂两块 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_async16188 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。