linux开发深度学习-时钟

这里我们学习在 i.MX6ULL 的最小系统开发中,时钟(Clock)电源(Power) 和**控制(Reset/Control)**是三大核心硬件基础。

时钟系统尤为复杂,因为它直接决定了处理器的性能(主频)以及所有外设能否正常工作

i.MX6ULL 最小系统板上必须包含两颗外部晶振,它们是内部所有高频时钟的基准:

晶振频率 用途 说明
24 MHz 主时钟源 这是最重要的时钟源。它为内部的锁相环(PLL)提供基准输入,进而生成 CPU 内核、总线、USB、以太网等所有高速模块的时钟。精度要求较高(通常需 ±50ppm 以内)。
32.768 kHz RTC 时钟源 专用于实时时钟(RTC)模块。即使在主电源断电(由电池供电)的情况下,也能维持时间和日历信息的走时。

内部时钟架构(时钟树)

i.MX6ULL 内部拥有一个复杂的时钟树(Clock Tree)

从上到下、从左到右拆解一下图中的关键信息

1. 输入源(最左侧)

  • OSC24M :这就是板子上的 24MHz 晶振。它是整个系统的"心脏起搏器",所有高频都源于此。
  • CLK1 / CLK2 (n):这是外部时钟输入引脚。通常最小系统中用不到,或者用来做备用时钟源。图中显示它们可以通过多路选择器(MUX)替代 OSC24M 进入系统。

2. 核心倍频区(中间左侧 - PLLs)

这里就是你问的 7 路锁相环(PLL) 的所在地。请注意图中的逻辑:

  • ARM_PLL:专供 CPU 内核。
  • 528_PLL (SYS_PLL) :系统主 PLL。注意看它后面挂了 4 个 PFD(PFD0, PFD1, PFD2, PFD3)。这是 i.MX6 系列的精髓,一个 PLL 通过 4 个 PFD 变出 4 组不同频率,极大地丰富了时钟源。
  • 480_PLL (USB1_PLL) :同样挂了 4 个 PFD
  • 其他 PLL :下方的 USB2_PLL, ENET_PLL, VIDEO_PLL, AUDIO_PLL 等,各司其职。

关键点 :你会发现所有的 PLL 输入都来自左边的垂直总线,而这条总线的源头就是 OSC24M。这验证了"24MHz 是基准"的说法。

3. 相位分数分频器(中间密集方块 - PFDs)

图中那些标着 528PFD0, 480PFD1 的小方块,就是 PFD

  • 它们的作用是将 PLL 输出的固定高频(如 528MHz),通过相位插值技术,变成各种奇怪的频率(如 396MHz, 352MHz, 480MHz 等),且保持低抖动。
  • 图中的 bypass 信号意味着你可以选择"绕过"PFD,直接使用 PLL 的原始频率。

4. 输出与使能(右侧)

  • REF_xxx_CLK :这些是生成的参考时钟信号,会输送到具体的外设模块(比如 REF_USB1_CLK 会给 USB 控制器用)。
  • ENABLE/BYPASS 控制线 :注意那些细线(如 armpll_enable, 528pfd0_enable)。这就是软件通过寄存器 控制的地方。
    • 如果软件把 enable 置为 0,对应的电路就断电/停振,达到省电目的。
    • 如果软件把 bypass 置为 1,信号就不经过 PLL/PFD,直接直通(通常用于调试或低功耗模式)。

5. 特殊模块(右下角)

  • DIV_ENET:以太网时钟分频器。
  • DIV V 27/49/16 等:视频和音频的专用分频器

实操:把 i.MX6ULL 的默认主频从 528MHz 改为 696MHz (超频,需确保电源稳定),或者改为 396MHz(省电)。

在 U-Boot 源码中,时钟初始化的核心文件通常是:
arch/arm/mach-imx/mx6/clock.c (不同版本路径略有差异,也可能是 spl_board_init.c)

cs 复制代码
// 伪代码示例,展示如何配置 ARM PLL
void init_arm_clk(void)
{
    struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
    
    // 1. 旁路 PLL (Bypass),防止在配置过程中产生毛刺
    setbits_le32(&anatop->pll_arm, ANATOP_PLL_BYPASS);
    
    // 2. 关闭 PLL 输出 (Power Down),准备重新配置
    clrbits_le32(&anatop->pll_arm, ANATOP_PLL_ENABLE);
    
    // 3. 【核心步骤】设置倍频系数 DIV_SELECT
    // 公式:F_out = 24MHz * DIV_SELECT
    // 想要 528MHz: DIV_SELECT = 22  (24 * 22 = 528)
    // 想要 696MHz: DIV_SELECT = 29  (24 * 29 = 696) -> 超频
    // 想要 396MHz: DIV_SELECT = 16.5 (需要小数分频,通常通过寄存器特定位设置)
    
    // 这里以设置为 528MHz (默认) 为例
    // CCM_ANALOG_PLL_ARM[DIV_SELECT] 位域通常是 [0:5] 或类似
    reg = readl(&anatop->pll_arm);
    reg &= ~ANATOP_PLL_DIV_SELECT_MASK; // 清除旧值
    reg |= (22 << ANATOP_PLL_DIV_SELECT_SHIFT); // 写入新值 22
    writel(reg, &anatop->pll_arm);
    
    // 4. 等待 PLL 锁定 (Lock)
    while (!(readl(&anatop->pll_arm) & ANATOP_PLL_LOCK));
    
    // 5. 取消旁路,使能输出
    clrbits_le32(&anatop->pll_arm, ANATOP_PLL_BYPASS);
    setbits_le32(&anatop->pll_arm, ANATOP_PLL_ENABLE);
    
    // 6. 设置 CPU 分频器 (ARM_PODF)
    // PLL 输出是 528MHz,但 CPU 内核可能只需要运行在 528MHz 或更低
    // 这里设置分频比,例如除以 1,则 CPU = 528MHz
    set_arm_podf(0); // 0 代表除以 1
}
  • 想超频 :把代码里的 22 改成 29 (对应 696MHz)。
    • 注意:超频通常需要提高 CPU 电压(LDO 调节),否则系统会不稳定。这需要同时修改 PMIC(电源管理芯片)的代码。
  • 想省电 :把 22 改成 16 (384MHz) 或其他低值。
  • 编译烧录 :修改后编译 U-Boot (make u-boot.imx),烧录到 SD 卡启动,观察串口打印的频率信息。
相关推荐
毕设源码-钟学长1 小时前
【开题答辩全过程】以 基于web的书法学习网站的设计与实现为例,包含答辩的问题和答案
学习
青瓦梦滋1 小时前
Linux进程间通信(IPC)——system V
linux·服务器·c++·文件
XMAIPC_Robot2 小时前
基于RK3588 ARM+FPGA的电火花数控硬件平台总体设计(二)
运维·arm开发·人工智能·fpga开发·边缘计算
皮卡蛋炒饭.2 小时前
学习IO基础
学习
人生苦短,菜的抠脚2 小时前
RK628 Linux 内核驱动开发指南
linux·驱动开发
__雨夜星辰__2 小时前
TypeScript 入门学习笔记(面向对象 + 常用设计模式)
前端·学习·typescript
代码AC不AC2 小时前
【Linux】命名管道
linux·命名管道
陌上花开缓缓归以2 小时前
linux boot 烧写纪要以及内存相关分析
linux·服务器·网络
yy_xzz2 小时前
【Linux开发】 04 Linux UDP 网络编程
linux·网络·udp