Skip to content

时钟中断部分解析

Kangxu Liu edited this page Jun 27, 2016 · 2 revisions

为了实现进程的时间片轮转,我们需要启动一个以一定时间间隔发出中断的计时器。在树莓派 3 上,板载了一个 System Timer,提供了 4 路比较功能(见 BCM2835 ARM Peripherals 中的第 12 节)。

System Timer 寄存器列表

偏移量 名称 描述 宽度
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.sboot/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) 清除时钟中断

函数信息

u_long get_system_timer(void)

简述

get_system_timer 用于获取自树莓派上电起计算的系统时间,即返回 CHI 和 CLO 拼接后的 64 位值,单位为微秒

参数

返回值

系统时间,单位为微秒

额外信息

void set_system_timer_irq(u_long delay)

简述

set_system_timer_irq 用于设置一个延迟 delay 的时钟中断,其核心是设置 ENABLE_IRQ_1 的第 3 位为 1,并将 C3 设置为当前系统时间与 delay 的和。

参数
  • u_long delay

    需要延迟的微秒值。

返回值

额外信息

当 delay 为 0 时,将使用上次执行时的 delay 值来执行。

void clr_timer_irq(void)

简述

clr_timer_irq 用于清除当前已触发的时钟中断,其核心是设置 ARM_SYSTIMER_CS 的第 3 位为 1。

参数

返回值

额外信息

每次处理时钟中断时都要调用此函数来清除已触发的时钟中断信号。

Clone this wiki locally