1. C6748定时器系统架构解析
C6748作为TI公司经典的DSP处理器,其定时器子系统在嵌入式实时控制中扮演着关键角色。该芯片搭载了多个64位定时器,每个定时器由两个32位寄存器组成:TIMERxH(高32位)和TIMERxL(低32位)。这种设计既保留了64位宽度的计时能力,又兼容了32位架构的访问方式。
在实际应用中,定时器通常以自由运行模式(free-run mode)工作,即从0开始递增计数直至溢出后重新循环。对于1GHz主频的C6748,32位定时器约4.3秒就会溢出一次,而64位定时器理论上可以连续运行约584年才会溢出,这为长时间精确计时提供了硬件基础。
关键特性速览:
- 64位宽度(实际由两个32位寄存器级联实现)
- 可编程预分频器(1~65536分频)
- 多种工作模式:单次/周期/连续计数
- 支持比较匹配中断
2. 定时器读取的典型问题场景
2.1 寄存器读取的原子性问题
当我们需要获取完整的64位计数值时,必须分别读取高32位(TIMERxH)和低32位(TIMERxL)。由于这两个操作无法在硬件层面保证原子性,在低32位发生进位时(0xFFFFFFFF→0x00000000),如果读取顺序不当,可能导致获取到错误的高32位值。
错误示例:
c复制uint64_t getTimerValue() {
uint32_t hi = TimerRegs.TIMERxH; // 先读高32位
uint32_t lo = TimerRegs.TIMERxL; // 后读低32位
return ((uint64_t)hi << 32) | lo; // 合并为64位
}
这种实现可能在lo溢出时(如从0xFFFFFFFF变为0x00000000)导致hi值未及时更新,最终合并得到的64位值出现巨大跳变。
2.2 中断延迟的影响
即使在单核系统中,中断服务程序(ISR)也可能打断定时器读取过程。假设在读取低32位后触发中断,而ISR执行时间较长,等返回到主程序读取高32位时,实际计数值可能已经发生了多次进位。
3. 可靠的64位定时器读取方案
3.1 双重读取验证法
经过多次实践验证,以下方法能有效解决寄存器读取的同步问题
