-
Notifications
You must be signed in to change notification settings - Fork 19
时钟中断部分解析
为了实现进程的时间片轮转,我们需要启动一个以一定时间间隔发出中断的计时器。在树莓派 3 上,板载了一个 System Timer,提供了 4 路比较功能(见 BCM2835 ARM Peripherals 中的第 12 节)。
| 偏移量 | 名称 | 描述 | 宽度 |
|---|---|---|---|
| 0x0 | CS | System Timer Control/Status | 32 |
| 0x4 | CLO | System Timer Counter Lower 32 bits | 32 |
| 0x8 | CHI | System Timer Counter Higher 32 bits | 32 |
| 0xc | C0 | System Timer Compare 0 | 32 |
| 0x10 | C1 | System Timer Compare 0 | 32 |
| 0x14 | C2 | System Timer Compare 0 | 32 |
| 0x18 | C3 | System Timer Compare 0 | 32 |
经查阅 资料,我们得知树莓派上的 System Timer 时钟频率为 1 MHz,且 C0 和 C2 被 GPU 占用,故 CPU 所能使用的只有 C1 和 C2 两路比较功能。
为了使计时器能够发出中断信号,我们还需要设置 BCM2837 的中断控制寄存器,以允许时钟中断请求使能。通过设置 ENABLE_IRQ_1 寄存器中的对应位,我们可以将中断信号送入 CPU。有关中断控制的内容,请参见 BCM2835 ARM Peripherals 中的第 7 节。
在 AArch64 中,CPU 在每个 EL 下都有自己的中断允许标志,为了使 CPU 在 EL1 和 EL0 下能够响应中断请求,我们在 boot/init.s 和 boot/asm.s 中分别进行了如下设置:
msr spsr_el2, x0 // el1_sp1 with DAIF = 0
msr spsr_el1, x0 // el0 with DAIF = 0
意为在 EL1 和 EL0 下允许中断使能。DAIF 的含义,请参考 ARM Cortex-A Series Programmer’s Guide for ARMv8-A 中的第 10.1 节。
| 返回类型 | 函数 | 描述 |
|---|---|---|
| u_long | get_system_timer (void) | 获取当前系统时间(单位为微秒) |
| u_long | set_system_timer_irq (u_long delay) | 设置延迟 delay 的时钟中断(单位为微秒) |
| u_long | clr_timer_irq (void) | 清除时钟中断 |
get_system_timer 用于获取自树莓派上电起计算的系统时间,即返回 CHI 和 CLO 拼接后的 64 位值,单位为微秒。
无
系统时间,单位为微秒。
无
set_system_timer_irq 用于设置一个延迟 delay 的时钟中断,其核心是设置 ENABLE_IRQ_1 的第 3 位为 1,并将 C3 设置为当前系统时间与 delay 的和。
-
u_long delay需要延迟的微秒值。
无
当 delay 为 0 时,将使用上次执行时的 delay 值来执行。
clr_timer_irq 用于清除当前已触发的时钟中断,其核心是设置 ARM_SYSTIMER_CS 的第 3 位为 1。
无
无
每次处理时钟中断时都要调用此函数来清除已触发的时钟中断信号。