Zynq 的每个 Cortex-A9 处理器都有自己的专用 32 位定时器和 32 位看门狗定时器,两个处理器共享一个全局 64 位定时器,这些计时器的时钟频率始终为 CPU 频率的 1/2。本文主要介绍 Zynq 芯片 CPU 私有定时器的工作特性,以及私有定时器的基本使用方法。
私有定时器
Zynq 的每个 Cortex-A9 处理器都有自己的专用 32 位定时器和 32 位看门狗定时器,两个处理器共享一个全局 64 位定时器,这些计时器的时钟频率始终为 CPU 频率的 1/2。
CPU 私有定时器具有以下特性:
- 32 位计数器,当计数达到 0 时产生中断
- 8 位预分频器,可更好地控制中断周期
- 可配置的单发(Single-shot)或自动重装(Auto-reload)模式
- 可配置的计数器起始值
- 时钟频率为 CPU 时钟的 1/2
使用 CPU 私有定时器时,可以直接读写相关寄存器,也可以采用高层次的方法。Xilinx 官方已经将函数封装好,只需要声明头文件 "xscutimer.h" 即可。
#include "xparameters.h"
#include "xscugic.h"
#include "xscutimer.h"
#define TIMER_DEVICE_ID XPAR_XSCUTIMER_0_DEVICE_ID
#define TIMER_LOAD_VALUE 0xFFFF
XScuGic IntcInstance; // GIC
XScuTimer TimerInstance; // Timer
void Timer_Init(XScuGic *IntcInstancePtr, XScuTimer *TimerInstancePtr,
u16 deviceId, u16 TimerIntrId)
{
XScuTimer_Config *ConfigPtr;
// 初始化CPU私有定时器
ConfigPtr = XScuTimer_LookupConfig(deviceId);
XScuTimer_CfgInitialize(TimerInstancePtr, ConfigPtr,
ConfigPtr->BaseAddr);
// 自测试,确保硬件工作
XScuTimer_SelfTest(TimerInstancePtr);
// 使能自动重载模式
XScuTimer_EnableAutoReload(TimerInstancePtr);
// 配置计数器值
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE);
// 启动定时器
XScuTimer_Start(TimerInstancePtr);
// 连接中断子系统
TimerSetupIntrSystem(IntcInstancePtr,
TimerInstancePtr, TimerIntrId);
}
在头文件 "xscutimer.h" 中可以看到 XScuTimer_EnableAutoReload() 与 XScuTimer_LoadTimer() 函数的定义,本质上是在写 Timer 相关寄存器。