2. 时钟定时器基础:系统时钟概念、硬件定时器类型与工作原理
在嵌入式实时系统(RTOS)中,时钟与定时器是系统的心脏节拍。VxWorks 的 BSP 层需要正确初始化并管理这些硬件资源,才能为任务调度、超时检测、时间片轮转和性能分析提供基础。本章将深入剖析系统时钟的概念、三种核心硬件定时器(PIT、GPT、看门狗)的结构差异,以及它们的工作原理。
2.1 系统时钟概念
系统时钟(System Clock)是 RTOS 运行的时间基准,通常由一个硬件定时器周期性产生中断来驱动。VxWorks 中,系统时钟的每一次中断称为一个 Tick,Tick 的周期决定了系统时间分辨率。
系统时钟在 VxWorks 中的核心作用包括:
- 任务延时: taskDelay()、taskDelaySys() 等 API 依赖 Tick 计数。
- 时间片轮转调度: 同优先级任务按时间片切换。
- 超时检测: 信号量、消息队列、网络协议栈的超时机制。
- 性能监控: 系统时钟提供时间戳用于 Profiling 和 Logging。
2.2 硬件定时器类型
嵌入式 SoC 或 MCU 内部通常集成多种硬件定时器,BSP 开发人员需要根据用途选择合适的定时器资源。下表对比了三种最常用的定时器类型:
| 特性 | PIT(周期中断定时器) | GPT(通用定时器) | 看门狗定时器(WDT) |
|---|---|---|---|
| 主要用途 | 产生周期性中断,驱动系统时钟 | 输入捕获、输出比较、PWM、单次/周期计时 | 系统异常复位检测 |
| 中断能力 | 固定周期中断 | 多种事件中断(捕获、比较、溢出) | 超时中断(通常不可屏蔽) |
| 计数模式 | 递减计数,自动重载 | 递增/递减,多种重载模式 | 递减计数,超时后复位或中断 |
| 精度 | 中等,适合毫秒级 Tick | 高,支持微秒级计时 | 低,主要用于秒级超时 |
| VxWorks 典型用法 | sysClkRateSet() 驱动系统时钟 | 辅助定时器、Profiling、外设时序 | 系统保护、任务级看门狗 |
2.3 定时器工作原理
所有硬件定时器的核心都是一个 计数器,它按照固定的时钟源频率递增或递减。当计数值达到预设的阈值时,触发相应事件(中断、复位、输出电平变化等)。
2.3.1 PIT 工作原理
PIT(Periodic Interrupt Timer)是最简单的定时器,通常包含一个递减计数器和一个自动重载寄存器。工作流程如下:
- BSP 初始化时,将重载寄存器设置为 Tick 周期对应的计数值。
- 计数器从重载值开始递减,每个时钟周期减 1。
- 当计数器减到 0 时,产生中断请求(IRQ),同时自动从重载寄存器加载初始值。
- 中断服务程序(ISR)调用 VxWorks 内核的 tickAnnounce() 函数,通知系统一个 Tick 已过去。
/* PIT 初始化伪代码示例(PowerPC 架构) */
void sysClkInit(void)
{
/* 1. 设置重载值:假设时钟源 100 MHz,Tick 周期 1 ms */
uint32_t reload = 100000000 / 1000; /* 100,000 个时钟周期 */
PIT_RELOAD_REG = reload;
/* 2. 使能自动重载模式 */
PIT_CTRL_REG |= PIT_CTRL_AUTORELOAD;
/* 3. 启动计数器 */
PIT_CTRL_REG |= PIT_CTRL_ENABLE;
/* 4. 使能中断控制器中的 PIT 中断 */
intConnect(INUM_TO_IVEC(PIT_INT_VEC), sysClkIsr, 0);
intEnable(PIT_INT_VEC);
}
2.3.2 GPT 工作原理
GPT(General Purpose Timer)功能更丰富,通常支持输入捕获、输出比较和 PWM 模式。其核心结构包含:
- 自由运行计数器: 可配置为递增或递减模式。
- 捕获寄存器: 在外部事件(如 GPIO 跳变)时锁定当前计数值。
- 比较寄存器: 当计数值与比较值匹配时,触发中断或输出电平翻转。
2.3.3 看门狗定时器工作原理
看门狗定时器(WDT)是一种特殊的定时器,用于检测系统是否正常运行。其工作原理如下:
- 启动: BSP 初始化时设置超时值并启动 WDT。
- 喂狗: 应用程序或内核定期调用看门狗复位函数(如 sysWdogReset()),将计数器重置为初始值。
- 超时: 如果计数器减到 0 且未被喂狗,WDT 触发预定义动作:产生不可屏蔽中断(NMI)或直接复位系统。
2.4 定时器时钟源与分频
所有硬件定时器都需要一个时钟源,通常来自系统主时钟(如 PLL 输出)或专用的低速时钟(如 32.768 kHz RTC 时钟)。BSP 需要通过 预分频器 将时钟源频率降低到定时器可接受的范围。
定时器计数频率计算公式:
定时器计数频率 = 时钟源频率 / (预分频值 + 1)
定时器溢出周期 = 重载值 / 定时器计数频率
例如:时钟源 100 MHz,预分频值 99,重载值 1000,则:
- 计数频率 = 100 MHz / (99 + 1) = 1 MHz
- 溢出周期 = 1000 / 1 MHz = 1 ms
2.5 定时器在 VxWorks BSP 中的初始化流程
在 BSP 的 sysHwInit() 或 sysClkInit() 函数中,定时器初始化通常遵循以下步骤:
- 时钟源配置: 确保定时器时钟源已使能且稳定。
- 预分频器设置: 根据目标 Tick 周期计算预分频值。
- 重载值设置: 写入自动重载寄存器。
- 中断连接: 将定时器中断向量连接到 ISR。
- 启动定时器: 使能计数器并等待第一个 Tick 中断。
2.6 常见问题与调试技巧
调试定时器相关问题时,建议使用以下方法:
- 示波器测量: 将定时器输出引脚(如 TOUT)连接到示波器,直接观察中断频率。
- VxWorks Shell 命令: 使用
i命令查看系统 Tick 计数,使用clock rate查看当前系统时钟频率。 - 寄存器转储: 在 BSP 初始化代码中增加寄存器打印,确认预分频值和重载值是否正确写入。
- 中断计数: 在 ISR 中增加全局计数器,通过 Shell 打印验证中断触发次数。