一、引言
在嵌入式系统中,时钟、定时器与中断构成了处理器正常运行的三大基础支柱。时钟为整个系统提供统一的时序节拍,定时器基于该节拍实现精确的时间计量,而中断则使得处理器能够以异步方式响应外部或内部事件。本文以NXP i.MX6ULL处理器为核心,结合硬件手册与底层代码实现,系统梳理这三者之间的内在联系与工作机制,为嵌入式底层开发提供理论支撑与实践参考。
二、时钟系统:从晶体到内核的倍频与分频链路
2.1 时钟源与锁相环
i.MX6ULL的时钟系统始于一个24MHz的外部晶体振荡器(OSC)。晶体振荡器利用石英晶体的压电效应产生高度稳定的振荡信号,作为整个时钟树的原始输入。然而,24MHz的频率远不足以满足处理器内核及高速外设的运行需求,因此需要通过锁相环电路进行频率提升。
锁相环通过反馈控制实现输入频率的整数倍放大。i.MX6ULL内部集成了多个PLL,各自服务于不同的功能域:
-
PLL1(ARM PLL):专为Cortex-A7内核提供时钟,输出频率可配置,典型值为1056MHz或792MHz。
-
PLL2(System PLL / 528 PLL):固定输出528MHz,为大部分系统总线及外设提供基准时钟。该PLL后接四个相位分数分频器(PFD0~PFD3),分别产生352MHz、594MHz、400MHz(实际为396MHz)、297MHz等频率。
-
PLL3(USB1 PLL / 480 PLL):固定输出480MHz,主要用于USB、UART等外设,同样带有四个PFD通道。
-
PLL4~PLL7:分别服务于音频、视频、以太网及USB2.0,按需配置。
2.2 相位分数分频器(PFD)
PFD是i.MX6ULL时钟系统中区别于传统分频器的关键结构。传统分频器仅支持整数分频,而PFD允许输出频率在PLL基频基础上实现分数倍调整。其本质是在PLL输出后插入一个相位插值电路,通过控制输出脉冲的占空比与相位插值步数,获得非整数倍的分频结果。以PLL2为例,528MHz经PFD0分频后得到352MHz,其分频比为528/352 = 1.5,即为分数分频。
2.3 系统时钟分配路径
从PLL到最终的外设时钟,需要经过多级选择与分频。以AHB总线时钟(AHB_CLK_ROOT)为例,其典型值为132MHz,生成路径如下:
-
PLL2的528MHz输出经PFD0分频后得到352MHz。
-
该频率进入预分频选择器(PRE_PERIPH_CLK_SEL),可选择来自PLL2或PLL3的路径。
-
随后进入外设时钟选择器(PERIPH_CLK_SEL),决定最终输出至AHB分频器的源时钟。
-
最后经过AHB分频器(AHB_PODF)进行分频,得到132MHz。
IPG_CLK_ROOT(66MHz)则由AHB_CLK_ROOT经过IPG分频器二分频得到。PERCLK_CLK_ROOT可选IPG_CLK_ROOT或晶振直接输入,并带有独立分频器。
2.4 ARM PLL的动态重配置
ARM PLL在运行过程中的频率切换需要谨慎操作,以避免内核时钟中断导致系统崩溃。标准流程如下:
-
将PLL1的输出源临时切换至step_clk(24MHz晶振),使内核工作于安全频率。
-
修改PLL1的倍频因子,将输出调整为目标频率。
-
将PLL1的输出源切换回PLL1自身,恢复内核主频。
该流程确保了在整个倍频调整期间,内核始终有稳定时钟供给。
三、定时器:基于时钟计数的硬件计时单元
3.1 定时器的本质
定时器的核心是一个计数器,在已知频率的时钟驱动下累加,当计数值达到预设阈值时触发中断或输出信号。其精度取决于输入时钟频率和计数器的位宽。
3.2 EPIT(增强型周期中断定时器)
EPIT是一个32位递减计数器,支持两种工作模式:
-
设置一次模式(Set-and-Forget):计数值减至0时产生中断,计数器停止,需软件重新加载。
-
自动重装模式(Auto-reload):计数值减至0时自动从加载寄存器重新装载,连续产生周期性中断。
EPIT的输入时钟可来源于IPG_CLK_ROOT(66MHz)或经过分频的高频时钟,通过预分频器进一步降低计数频率。例如,若需产生1秒中断,可将时钟源配置为66MHz,经过预分频器分频至1MHz,再将EPIT的加载值设为1,000,000,即可实现每秒一次中断。
3.3 GPT(通用目的定时器)
GPT相较于EPIT功能更为丰富,支持:
-
自由运行模式:计数器从0递增至0xFFFFFFFF后回绕,适用于实现高精度延时。
-
输入捕获:在外部引脚发生边沿跳变时锁存当前计数值,用于测量脉冲宽度或频率。
-
输出比较:当计数值匹配预设值时翻转输出引脚电平,可生成PWM波形。
GPT的时钟源可选晶振(24MHz)、PLL输出或外部引脚输入,灵活性更高。在自由运行模式下,通过读取当前计数值并计算时间差,可实现微秒级的阻塞延时函数,适用于对时序有严格要求的驱动初始化阶段。
四、中断系统:GIC与异常处理机制
4.1 从轮询到中断
轮询方式下,处理器需要不断检查外设状态,效率低下且存在事件漏检风险。中断机制允许外设在需要处理时主动向处理器发出请求,处理器完成当前指令后响应,执行中断服务函数(ISR),而后恢复现场继续执行。这一机制是实现实时响应的基础。
4.2 GIC(通用中断控制器)
i.MX6ULL采用ARM Cortex-A7内核,其中断控制器为GICv2架构。GIC由两部分组成:
-
Distributor(分发器):管理所有中断源,配置中断优先级、目标CPU核、触发方式(边沿/电平)及使能状态。
-
CPU Interface:每个CPU核对应一个接口,负责将最高优先级的中断传递给该核。
GIC支持三种中断类型:
-
SGI(软件产生中断):由软件向GICD_SGIR寄存器写入触发,用于多核通信。
-
PPI(私有外设中断):每个CPU核独享,如每个核的本地定时器中断。
-
SPI(共享外设中断):外设中断,可由任意CPU核处理,如GPIO中断、UART中断等。
i.MX6ULL中,外设中断编号范围在MCIMX6Y2.h中定义为IRQn_Type枚举,从0至159,对应GIC中的SPI 32至191。
4.3 中断初始化流程
在Cortex-A7上使能中断需要配置以下层次:
-
外设层:配置GPIO引脚复用为中断功能,设置触发条件(上升沿、下降沿或双边沿),并使能GPIO模块的中断。
-
GIC层:通过Distributor配置对应中断号的分发属性(优先级、目标CPU),并清除挂起状态,最终使能该中断。
-
CPU层:通过CP15协处理器配置系统控制寄存器(SCTLR)中的中断向量基址寄存器(VBAR),设置中断向量表位置;同时使能CPSR中的I位(IRQ中断总开关)。
4.4 CP15协处理器与中断向量表
Cortex-A7通过CP15协处理器管理系统控制功能,中断相关寄存器包括:
-
SCTLR(系统控制寄存器):bit13(V位)决定向量表基址为0x00000000还是0xFFFF0000;bit12(I位)使能指令缓存。
-
VBAR(向量基址寄存器):存储中断向量表的物理地址,支持重定位。
中断向量表通常放置在内存起始位置(如0x87800000),包含复位、未定义指令、软中断、预取终止、数据终止、IRQ、FIQ七个异常向量。IRQ向量指向一个跳转指令,进入统一的IRQ入口函数,该函数读取GIC的IAR寄存器获取中断号,再跳转至对应的ISR。
