参考资料ug1165、ug585
1、通过ug1165实现如下例子:
2、文档ug585中关于ARM9的中断描述:
理解为:
CPU通过GIC管理中断,中断来自3类:软件中断SGI、私有外设中断PPI、共享外设中断SPI.
各个CPU分别支持16、5、60个SGI、PPI、SPI.
GIC承上启下的管理中断。外设产生中断------GIC管理中断-------CPU响应中断
每个中断都有对应的中断号
这个例子只用到了一个中断,其它中断还得查对应描述。
3、vivado连好的硬件电路图:
4、软件代码分析:
4.1 定义AXI_TMIER设备结构体,这个设备在PL中,通过计数产生中断信号传递给PS
typedef struct {
XTmrCtr_Config Config; /**< Core configuration. */
XTmrCtrStats Stats; /**< Component Statistics */
UINTPTR BaseAddress; /**< Base address of registers */
u32 IsReady; /**< Device is initialized and ready */
u32 IsStartedTmrCtr0; /**< Is Timer Counter 0 started */
u32 IsStartedTmrCtr1; /**< Is Timer Counter 1 started */
XTmrCtr_Handler Handler; /**< Callback function */
void *CallBackRef; /**< Callback reference for handler */
} XTmrCtr;
它的最后两项是函数指针和回调参数,回调参数会传递给函数指针指向的函数。
4.2 定义GIC的结构体:
4.3 main函数分析
4.3.1定义参数、设备结构体
4.3.2init_platform();
4.3.3初始化PL中的AXI_GPIO
4.3.4设置AXI_GPIO为输入
4.3.5初始化AXI_TIMER(找到基地址,此时它的Handler指向一个Xil_AsserVoid,CalBackRef指向本身)
4.3.6再设置AXI_TIMER(将它的Handler指向中断服务程序,CallBackRef指向本身)
4.3.7设置AXI_TIMER的初始值(计数长度)
4.3.8设置AXI_TIMER的中断工作模式
4.3.9找寻PS端的GPIO,并初始化该设备
4.3.10设置PS端GPIO[10]为输出;设置PS端GPIO[10]的输出使能开;
4.3.11设置PS端GPIO[54]为输入;设置PS端GPIO[54]的输出使能关;
4.3.12初始化中断系统,然后可以开始主程序了。
4.4 中断函数分析
4.4.1找到GIC设备
4.4.2初始化GIC设备(对4.2的结构体进行初始化)
(1)GIC的ICC基地址和ICD基地址赋值;
(2)对中断源(支持95个中断)数组进行初始化。如果中断设备没有连接,先给它赋值一个函数。
如果不连接驱动设备,该中断执行的中断函数就是StubHandler,该函数完成的功能就是对该中断计数:
(3)执行DistributorInit和CPUInitialize函数,对相关寄存器赋值。(寄存去定义查找ug585)
这里,GIC设备就初始化完成了。此时,它要注册CPU的异常表 和 连接中断设备(AXI_TIMER),才能让AXI_TIMER产生的中断传给CPU,让CPU执行AXI_TIMER中断时要执行的中断程序。
4.4.3中断设备 -------- GIC中断数组[95] --------异常表-------CPU执行中断函数
异常表的定义:
(1)将中断函数和回调参数写入这个表(其中XIL_EXCEPTION_ID_INT是IRQ的异常号5;XScuGic_InterruptHandler是GIC中断table中的函数指针,XScuGicInstancePtr是GIC结构体指针)
可见,这个表注册了函数指针(该指针指向GIC结构体中中断源的中断函数),可回调参数(GIC结构体指针)
(2)CPU执行中断函数
跳转到了IRQInterrupt函数
CPU执行的中断函数表明:将异常表中对应的回调参数传递给函数指针,执行该函数指针指向的函数。就是(1)中注册的函数。
(3)GIC中断表中对应函数的主要内容
GIC读取中断号(确定哪个中断)InterruptID
找到中断表中的注册函数,并将回调参数传递给该函数,执行该函数。
(4)之前初始化时,GIC的中断注册表都指向了StubHandler函数(该函数只完成对中断发生次数的统计)
(5)现在将GIC的中断注册表中相应的AXI_TIMER中断连接到实际中断函数
AXI_TIMER的中断号是61.
4.4.4 AXI_TIMER中断函数
红色箭头那一句表示将AXI_TIMER结构体中注册的回调参数传递给注册的Handler函数,并执行
注册AXI_TIMER中的中断函数和回调参数,4.3.6中描述
主函数中的中断函数