SOC定时器与中断配置
1 定时器与中断工作原理
定时器原理:
Soc每一个核拥有一个32位的私有定时器和一个32位的私有看门狗定时器,两个核还拥有一个共享的64位全局定时器。
私有定时器工作方式是32位自减模式,当计数值递减到0时产生中断;8位的预分频器,支持1-0xff的分频;支持单次触发模式和自动重载模式,单次触发模式下,计数值递减到0后定时器停止,自动重载模式下,计数值递减到0后会从重加载寄存器拷贝计数值到计数寄存器中,产生中断后继续从该计数值执行递减操作。私有定时器和看门狗定时器的时钟为CPU时钟的2分频。计时时间计算:(预分频配置值+1) x (计时开始值+1)x工作时间周期。
中断原理:
中断控制器主要使用的是GIC控制器,该控制器分为中断分配器和CPU接口控制器两部分,其架构图如图1所示。
图1 GIC控制器体系结构
中断分配器(Distributor)的作用是分配各个中断的优先级,并将各个中断分配给适当处理器的CPU 接口(CPU interface)。CPU接口(CPU interface)的作用是实现中断优先级屏蔽控制,并实现与中断连接的相应处理器的中断嵌套处理策略。上述每个模块均具有各自的配置模块,它主要由寄存器组成。对于系统中实现的多个CPU接口(多核系统中,每个处理器对应一个CPU接口),它们的配置模块基本相同。
中断分配器:
中断分配器(Distributor)集中所有中断源,设置每个中断的优先级,具体如下:
(1)将中断向下级CPU接口传送的全局使能控制;
(2)使能或不使能中断控制;
(3)为每个中断设置优先级;
(4)对于外部中断,设置其为电平有效或边沿有效控制;
如果GIC实现了安全性扩展功能(Security Extensions)时,设置每个中断的安全模式:安全模式(Secure)或非安全模式(Non-Secure);将软件中断(SGI)送入一个或多个目标处理器的控制;另外,中断分配器(Distributor)提供以下两个功能:各个中断状态的可视化;软件设置或清除外部中断的挂起(Pending)状态控制。
CPI接口控制器:
每个CPU接口(CPU interface)是GIC与处理器的一个接口,它是一个可编成的接口,具体功能如下:
(1)中断信号使能;
(2)中断应答;
(3)设置中断完成标识;
(4)设置处理器的中断屏蔽优先级;
(5)设置处理器中断嵌套策略;
(6)设置处理器挂起中断的最高优先级;
当CPU 接口使能后,CPU接口为与其连接的处理器选择一个最高优先级的被挂起的中断,然后判断该中断是否具有将其请求传送给处理器足够高的优先级,CPU接口根据中断优先级屏蔽设置及中断嵌套设置对中断进行判定。在任意时刻,处理器可以对读取正在处理(active)的多个中断的最高优先级。
值得注意的是:
将中断请求传给处理器的传统机制是通过设置nIRQ或nFIQ;处理器通过读取CPU接口的中断响应寄存器(Interrupt Acknowledge register)来响应中断请求,通常情况下,当中断的优先级足以使产生中断,则读取的数值是挂起中断的最该优先级;否则,返回伪中断。
中断映射表(如表1所示):
表1 中断映射表
对应中断ID | 中断源 | 中断描述 |
保留 | Reserved INT | 保留 |
85 | I2C1_IRQ | I2C1中断 |
84 | I2C0_IRQ | I2C0中断 |
83 | DDR_INT | DDR中断 |
82 | GPIO_EXTINT2 | GPIO[2]扩展外部中断2 |
81 | GPIO_EXTINT1 | GPIO[1]扩展外部中断1 |
80 | GPIO_EXTINT0 | GPIO[0]扩展外部中断0 |
79 | EXTINT3 | 外部中断3 |
78 | EXTINT2 | 外部中断2 |
77 | EXTINT1 | 外部中断1 |
76 | EXTINT0 | 外部中断0 |
75 | QSPI_INT | QSPI中断 |
74 | HDLC_INT | 4路HDLC共享中断 |
73 | UART_INT[11] | 第11路UART中断 |
72 | UART_INT[10] | 第10路UART中断 |
71 | UART_INT[9] | 第9路UART中断 |
70 | UART_INT[8] | 第8路UART中断 |
69 | UART_INT[7] | 第7路UART中断 |
68 | UART_INT[6] | 第6路UART中断 |
67 | UART_INT[5] | 第5路UART中断 |
66 | UART_INT[4] | 第4路UART中断 |
65 | UART_INT[3] | 第3路UART中断 |
64 | UART_INT[2] | 第2路UART中断 |
63 | UART_INT[1] | 第1路UART中断 |
62 | UART_INT[0] | 第0路UART中断 |
61 | X1553B1_INT | 1553B1中断 |
60 | X1553B0_INT | 1553B0中断 |
59 | CAN1_INT | CAN1中断 |
58 | CAN0_INT | CAN0中断 |
57 | Timer_INT | GPIO/PWM/Freq共享中断 |
56 | SPI3_IRQ | 第3路SPI中断 |
55 | SPI2_IRQ | 第2路SPI中断 |
54 | SPI1_IRQ | 第1路SPI中断 |
53 | SPI0_IRQ | 第0路SPI中断 |
52 | DMA_Slow_IRQ[5] | 第5路慢速DMA中断 |
51 | DMA_Slow_IRQ[4] | 第4路慢速DMA中断 |
50 | DMA_Slow_IRQ[3] | 第3路慢速DMA中断 |
49 | DMA_Slow_IRQ[2] | 第2路慢速DMA中断 |
48 | DMA_Slow_IRQ[1] | 第1路慢速DMA中断 |
47 | DMA_Slow_IRQ[0] | 第0路慢速DMA中断 |
46 | DMA_Slow_IRQ_Abort | 6路慢速DMA共享异常中断 |
45 | DMA1_IRQ | 第1路快速DMA中断 |
44 | DMA0_IRQ | 第0路快速DMA中断 |
43 | DMA_IRQ_Abort | 2路快速DMA共享异常中断 |
42 | SBD_INTR_O | 以太网控制器中断 |
41 | L2C_DECERRINTR | L2 Cache译码错误中断 |
40 | L2C_SLVERRINTR | L2 Cache从机接收错误中断 |
39 | L2C_ERRRDINTR | L2 Cache读数据RAM错误中断 |
38 | L2C_ERRRTINTR | L2 Cache读标记RAM错误中断 |
37 | L2C_ERRWDINTR | L2 Cache写数据RAM错误中断 |
36 | L2C_ERRWTINTR | L2 Cache写标记RAM错误中断 |
35 | L2C_PARRDINTR | L2 Cache读数据RAM奇偶校验错误中断 |
34 | L2C_PARRTINTR | L2 Cache读标记RAM奇偶校验错误中断 |
33 | L2C_ECNTRINTR | L2 Cache事件计数器上溢中断 |
32 | L2C_L2CCINTR | L2 Cache联合输出中断 |
从图中可以看出私有定时器中断对应的中断ID号为29,看门狗定时器的中断ID号为30。
2 配置流程
定时器的配置:
- 配置重加载定时器的数值和定时器开始计数数值,配置寄存器为私有定时器加载寄存器和私有定时器计数寄存器(加载寄存器地址为0x10002600计数寄存器地址为0x10002604)。
- 配置定时器时钟预分频系数,这里配置为1,使用2分频,配置私有定时器控制寄存器的15-8bit为0x1(控制寄存器地址为0x10002608)。
- 使能定时器的自动重加载功能,配置控制定时器的第1bit为0x1。
- 使能定时器中断,配置控制寄存器的第2bit为0x1。
- 使能定时器外设功能,配置控制寄存器的第0bit为0x1。
- 中断服务函数的必要处理,需要清除定时器中断标识,配置中断状态寄存器的的第0bit写0x1(中断状态寄存器地址为0x1000260c)。
中断配置:
- 关闭中断分配器的中断使能,中断分配器控制寄存器ICDICR的0bit写0x0(控制寄存器的地址为0x10003000)。
- 配置中断触发为边沿模式,向中断配置寄存器IDCIFR的对应中断位写1。
- 配置中断优先级,向中断优先级寄存器DCDIPR的对应中断位写入中断优先级数值解。
- 将中断映射到CPU0,向中断处理器目标寄存器ICDIPTR的对应中断位写入0x1.
- 清除被挂起的中断,向中断挂起状态撤销寄存器ICDICPR的对应中断位写入0x1.
- 使能GIC中对应的外设中断,向中断使能设置寄存器ICDISER中的对应中断为写入0x1.
- 关闭CPU接口控制器,向CPU接口控制寄存器ICCICR写入0x00。
- 设置CPU优先级中断掩码,配置256级优先级中断都能够送入到CPU中断接口中,向中断优先级屏蔽寄存器ICCPMR中写入0xff。
- 使能CPU接口控制器,向CPU接口控制寄存器ICCICR写入0x3。
- 使能中断分配器,向中断分配器控制寄存器ICDICR写入0x0;
- 使能A9处理器核心的中断,向cpsr_c写入0x80.
3 数据结构封装
根据定时器模块寄存器地址与中断寄存器模块地址在内存分配图中的分布,将其地址定义为整型宏定义,将寄存器定义为各位各个功能位域的结构联合体。这样子将整型地址转换成寄存器的结构联合体指针,就能够通过寄存器位域去编写底层驱动了,图2表示定时器模块宏定义寄存器的定义和类型转换,图3表示中断模块宏定义寄存器的定义和类型转换,图4表示定时器模块寄存器结构联合体定义,图5表示中断模块寄存器结构联合体定义。
图2
图3
图4
图5