@[toc]
在这里插入图片描述

问题背景分析

在Linux环境下开发STM32H7系列芯片时,发现系统时钟sys_ck的时钟源并非手册标明的默认HSI(High Speed Internal oscillator),而是被配置为PLL1。这种现象需要从系统启动流程的底层进行分析。

关键发现

通过追踪系统启动流程,发现u-boot引导阶段已经对时钟进行了重新配置。在u-boot的时钟驱动代码中明确设置了PLL1作为系统时钟源:

1
2
3
4
/* 选择PLL1作为系统时钟源(sys_ck) */
clrsetbits_le32(&regs->cfgr, RCC_CFGR_SW_MASK, RCC_CFGR_SW_PLL1);
while ((readl(&regs->cfgr) & RCC_CFGR_SW_MASK) != RCC_CFGR_SW_PLL1)
;

这段代码位于drivers/clk/stm32/clk-stm32h7.c文件的configure_clocks函数中,执行以下操作:

  • 清除RCC_CFGR寄存器中的时钟源选择位
  • 设置PLL1作为新的系统时钟源
  • 通过循环等待确保时钟切换完成

!

技术原理

STM32H7的时钟系统具有以下特点:

  • 上电复位后默认使用HSI(64MHz)作为系统时钟
  • 允许通过修改RCC_CFGR寄存器的SW[2:0]位动态切换时钟源
  • 时钟源切换需要等待状态位稳定

解决方案建议

如需恢复默认HSI时钟源,可考虑以下方法:

修改u-boot的板级配置文件,注释掉相关的时钟配置代码:

1
// clrsetbits_le32(&regs->cfgr, RCC_CFGR_SW_MASK, RCC_CFGR_SW_PLL1);

或者在Linux驱动中重新初始化时钟:

1
2
3
writel(RCC_CFGR_SW_HSI, &regs->cfgr);
while ((readl(&regs->cfgr) & RCC_CFGR_SW_MASK) != RCC_CFGR_SW_HSI)
;

经验总结

嵌入式系统开发中需要注意:

  • 硬件初始化可能分布在bootloader和OS多个阶段
  • 官方手册标注的”默认值”可能被前期引导程序修改
  • 完整的时钟树分析需要追踪从复位到应用的全流程
  • 开发过程中建议使用示波器或逻辑分析仪验证实际时钟信号

建议通过STM32CubeMX工具生成参考配置代码,对比分析各阶段的时钟配置差异,这样可以更全面地理解系统行为。