zoukankan      html  css  js  c++  java
  • zedboard中断例程学习

    参考资料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中描述

        

        主函数中的中断函数

        

        

        

  • 相关阅读:
    14.5.5 Creating a File-Per-Table Tablespace Outside the Data Directory
    14.5.5 Creating a File-Per-Table Tablespace Outside the Data Directory
    php session 管理
    php session 管理
    CURD特性
    RabbitMQ学习总结(1)——基础概念详细介绍
    RabbitMQ学习总结(1)——基础概念详细介绍
    RabbitMQ学习总结(1)——基础概念详细介绍
    Java基础学习总结(39)——Log4j 1使用教程
    Java基础学习总结(39)——Log4j 1使用教程
  • 原文地址:https://www.cnblogs.com/yangtuzi/p/7106913.html
Copyright © 2011-2022 走看看