• MicroBlaze里面的中断管理


    MicroBlaze里面的中断主要有两类:一类是外部中断,另一类是内部中断。

    1. 外部中断:

    如果只有一个元件产生中断(比如只有一个定时器产生中断)或者只有一个外部中断管脚连接MB(这儿说的外部是相对于CPU说的,可以是FPGA内部的其他模块产生的中断,也可以是FPGA外部的输入中断),那么Intc可以不使用。

    这种情况,在EDK里面实现是最简单的。

    下面摘录MHS文件:

    PORT fifo_full_pin = fifo_full, DIR = I, SIGIS = INTERRUPT, SENSITIVITY = LEVEL_HIGH

    BEGIN microblaze

     PARAMETER INSTANCE = microblaze_0

     PARAMETER HW_VER = 4.00.a

     BUS_INTERFACE DLMB = dlmb

     BUS_INTERFACE ILMB = ilmb

     BUS_INTERFACE DOPB = mb_opb

     BUS_INTERFACE IOPB = mb_opb

     PORT CLK = sys_clk_s

     PORT Interrupt = fifo_full

    END

    PORT后面的几个参数(SIGIS等)参见psf_rm.pdf。从实际操作看,这些不加也可以。建议加上。特别是SENSITIVITY,可以设置中断是上升沿、下降沿、高电平、低电平中断。

    Note:By the way, interrupts connected to the microblaze directly needs to be level sensitive, in case of using an edge triggered interrupt you'll need an interrupt controller.

    注册中断函数可以在C文件里面调用注册函数,更为简单的办法是在MSS文件里面直接说明。

    注: 如果既有外部中断,又有内部中断,那么还是要用中断控制器,在mhs文件中加上PORT fifo_full_pin = fifo_full, DIR = I, SIGIS = INTERRUPT, SENSITIVITY = LEVEL_HIGH,之后, fifo_full_pin会自动连接到中断控制器的输入端Intr,点击加入就好了。加好之后的mhs文件如下所示:

    BEGIN opb_intc

    parameter INSTANCE = myintc 

    parameter HW_VER = 1.00.b

    parameter C_BASEADDR = 0xFFFF1000 

    parameter C_HIGHADDR = 0xFFFF10ff

    bus_interface SOPB = opb_bus

    port Irq = interrupt

     

    port Intr = uart_int & ext_int & gpio_int & fifo_full

    MSS文件摘录:

     

    PARAMETER VERSION = 2.2.0

    PARAMETER int_handler = gpio_int_handler, int_port = fifo_full_pin

    BEGIN OS

     PARAMETER OS_NAME = standalone 

     PARAMETER OS_VER = 1.00.a

     PARAMETER PROC_INSTANCE = microblaze_0

    END

    特 意把OS也摘出来是为了说PARAMETER int_handler = gpio_int_handler, int_port = fifo_full_pin这个是全局设定,不要放在Begin … End里面。此外,需要注意这个int_port,与它连接的应该是Port,而不是Interrupt Signal (注意:这里说的是外部中断,如果是内部中断,比如定时器中断,那么PARAMETER int_handler = gpio_int_handler, int_port = fifo_full_pin得放入Timer的Begin End里面,int_port指Timer的Interrupt Port,参见psf_rm.pdf )。gpio_int_handler,中断服务程序,需要在c中定义。

    注:现在新出的EDK版本,XPS9.2,已经将这种在mss文件中添加句柄(handler)的作用去掉了,句柄(handler)最好在软件中添加。

     

     2.内部中断

    内部中断需要使用中断控制器。

    如果在EDK的生成CPU向导中,选GPIO时选择了中断,那么中断控制器(以下称 Intc )会自动被加上。

     

    这个中断控制器的使用是非常简单的。

     

    很多中断都连接到Intc的Intr端口,然后从它的Irq端口连接MB的Interrupt。

     

    MHS文件描述如下:

     

    BEGIN opb_intc

     

    parameter INSTANCE = myintc

     

    parameter HW_VER = 1.00.b

     

    parameter C_BASEADDR = 0xFFFF1000

     

    parameter C_HIGHADDR = 0xFFFF10ff

     

    bus_interface SOPB = opb_bus

     

    port Irq = interrupt

     

    port Intr = uart_int & ext_int & gpio_int

     

    END

     

    begin microblaze

     

    parameter INSTANCE = mblaze

     

    parameter HW_VER = 1.00.c

     

    bus_interface DOPB = opb_bus

     

    bus_interface DLMB = d_lmb

     

    bus_interface ILMB = i_lmb

     

    port INTERRUPT = interrupt

     

    end

     

    需要说明一下的是中断优先级的设定。大家看这句:

     

    port Intr = uart_int & ext_int & gpio_int

     

    在 这种情况下,EDK会自动设定OPB_INTC的C_NUM_INTR_INPUTS参数为3,因为有三个中断。其中gpio_int的优先级是最高的, 因为它连接到intr[0]上。中断优先级右边最高,左边最低,即uart_int最低。因此,大家可以根据实际需要来设定。

     

    在MHS设定完毕后,生成的Lib里面的xparameters.h会定义一些比较重要的宏,包括了所有中断信号的一些属性。它们的命名符合一定的格式。

     

    大家可以在头文件里面看到:

     

    XPAR_< font="" />的实例名> _<产生中断的元件的实例名>_<中断信号名>_MASK

     

    XPAR_<产生中断的元件的实例名>_<中断信号名> _INTR

     

    比如说我们上面这段MHS, gpio_int中断的相关宏定义(跟具体设置有关,可能名字有出入):

     

    #define XPAR_DIP_SWITCHES_IP2INTC_IRPT_MASK 0X000001

     

    #define XPAR_OPB_INTC_0_DIP_SWITCHES_IP2INTC_IRPT_INTR 0

     

    INTR中的0拥有最高中断优先级。

     

    我们在写OPB_Intc的c程序时,代码是基本相同的,大家只要copy一下,做一些参数的修改即可。

     

    代码片断如下:

     

    /* 允许MB中断*/

     

        microblaze_enable_interrupts();

     

       /*注册中断子程序,就是告诉MB,发生中断之后,执行哪个中断服务程序 */

     

       XIntc_RegisterHandler(XPAR_OPB_INTC_0_BASEADDR, \   /* Intc的基址 */

     

             XPAR_OPB_INTC_0_DIP_SWITCHES_IP2INTC_IRPT_INTR, \

     

    /*这个参数就是上面提到的XPAR_<产生中断的元件的实例名>_<中断信号名> _INTR */

     

               (XInterruptHandler)gpio_int_handler, \  /* 中断服务程序名,因此我们在c文件里还应该写一个void gpio_int_handler(void *bassaddr_p) ,用于处理中断 */

     

                  (void *)XPAR_DIP_SWITCHES_BASEADDR);

     

      /* 这个是产生中断的元件基址,如果是外部中断,就用 NULL */

      

     /* start the interrupt controller */

     

        XIntc_mMasterEnable(XPAR_OPB_INTC_0_BASEADDR);

      

        /* enable the gpio interrupt*/

     

        XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR, XPAR_DIP_SWITCHES_IP2INTC_IRPT_MASK); /*这个就是上面提到的XPAR_< span="" />的实例名> _<产生中断的元件的实例名>_<中断信号名>_MASK */

    OPTIMISM, PASSION & HARDWORK
  • 相关阅读:
    destoon代码从头到尾捋一遍
    php中foreach()函数与Array数组经典案例讲解
    刷题比赛
    #Math
    福慧双修(both)
    NOIP17提高模拟训练18 长途旅行(travel)
    NOIP提高组模拟训练18 正确答案(answer)
    NOIP17提高组模拟赛17 -乐曲创作(music)
    #2017 Multi-University Training Contest
    CodeForces
  • 原文地址:https://www.cnblogs.com/hiramlee0534/p/5731188.html
Copyright © 2020-2023  润新知