zoukankan      html  css  js  c++  java
  • C6000系列之C6455DSP的中断系统

    转自:http://blog.csdn.net/ruby97/article/details/7538125

    C6000系列DSP的中断系统


    上一篇介绍了C6455的GPIO系统,最后把GPIO4配置成了中断/事件模式,本文将介绍C6455的中断系统,介绍完基本概念后,给出把GPIO4映射到INT4的代码。

    完成了GPIO和中断的配置,我们就可以开始着手DSP与FPGA之间的通讯了。废话不多说,下面开始介绍C6455的中断系统。


    ----------------------------------------------------华丽分割------------------------------------------------------


    中断模块框图

    仔细观察上图,可以看出C6455有一下几种中断:

    • 1.   Reset
    • 2.   NMI 不可屏蔽中断
    • 3.   EXCEP 硬件异常
    • 4.   12个普通中断INT[15:4]
    我们使用的最多的也就是普通中断,所以这也是本文的重点。


    ----------------------------------------------------华丽分割------------------------------------------------------


    接下来,沿着INT[15:4]往后退,看到的是Interrupt Selector,它的功能好比一个筛子(shuffle),对所有中断事件进行选择性映射。如下图示:


    看了这个图,我们又不难发现,中断选择器是一个128-->12的映射,这也就意味着,有116个系统事件被过滤掉了。

    接着往回走,可以看到,中断选择器有三个输入,分别是:

    • RESET
    • Event[3:0]
    • Event[127:4]

          

    RESET不看了,硬件重启。


    EVENT[127:4]是系统事件,这个事件的编号根据芯片的不同而不同,拿6455来说,部分映射情况如下面两个图片所示:




    不难看出,这些编号都是固定的,基本囊括了芯片上所有模块的事件。

     

    最后,比较特别的是Event[3:0],它是组合事件,通过下图的介绍应该就一目了然了。




    可见,Event0对应 4-31号事件的组合事件,Event2对应32-63号事件的组合事件,以此类推。

     

    ----------------------------------------------------华丽分割------------------------------------------------------


    那么,怎么组合呢?

    这就不得不从寄存器开始说起了。首先,先看如下3个寄存器组:




    (注:每组都是4个32位寄存器,每一组的EVTxxx0[3:0]都不使用,故这里不涉及到组合事件)


          系统事件发生时(124个),它们在事件标志寄存器中(EVTFLAGx)的对应位会被置1,此时可以通过向EVTCLR寄存器中对应位写入1来清除中断标志,然后执行中断服务程序。若不清除,那么相同事件再次发生时会产生问题。故,手动清除中断标志是必须的!且只能通过向EVTCLR寄存器中写入1来清除,不能直接向EVTFLAG寄存器写入0,因为EVTFLAG寄存器是Read Only的。


          另外,EVTSET寄存器的存在意义就是我们可以手动产生中断,这一点可以让我们测试中断服务程序的功能。

     


          介绍完上面三个基本的寄存器组,我们可以开始讨论组合事件的机制了。先看下图:



    可以明显的看出,124个事件被分成了4组。然后经过两个寄存器的运算,产生组合事件。


    下面介绍EVTMASKMEVT FLAG两个寄存器组。

    •       EVT MASK寄存器组用于决定每一个组中的哪些事件被屏蔽掉。默认情况下,没有事件被屏蔽(全0)。

    •       鉴于最终的组合事件EVTx的发生机制是对Group中所有事件进行或运算,即只要Group中有一个事件发生,就代表组合事件发生。

     

    举个例子:

    假如EVTMASK3=0x0FFFFFFF,那么代表只有事件124,125,126,127参与组合。其他事件96-123都被忽略。


    •       MEVT FLAG寄存器同EVT FLAG寄存器的值相同,表示事件是否发生。这样一旦知道了EVTMASK和MEVT FLAG两个寄存器的值就可以断定组合事件EVTx(0<=x<=3)是否发生了。


    ----------------------------------------------------华丽分割----------------------------------------------------- 


    通过上面的介绍,应该已经很清楚C6455的中断机制了,再贴一张图来巩固一下上面所说的内容:



    说到这里,我们对上图中红色框以及它之前的东西了解的很清楚了,下面就是Interrupt Selector的机制了。

    其实很简单,为12个中断分别配置对应的事件编号即可。只需要3个寄存器就OK啦。


    分别是INTMUX1,INTMUX2,INTMUX3。贴一个图就应该很明了了。



    举个例子:

    假设我要让INT4映射到GPIO4,那么通过查找前面的图,发现GPINT4的事件编号是55,那么只要把INTMUX1的低7位设置成0x37即可。

     


    此外,官方文档里还说了下面一段话:


    可见,INT4优先级最高,INT15优先级最低


    ----------------------------------------------------华丽分割------------------------------------------------------

    中断模块CSL库使用

    上面介绍了很多,其实就是想说清楚C6455的中断机制。实际使用还是CSL比较方便。

          使用CSL配置中断需要如下几个步骤:

    • 1.   初始化中断模块
    • 2.   使能NMI
    • 3.   全局中断使能
    • 4.   打开中断模块
    • 5.   绑定中断服务程序
    • 6.   使能相应事件

     

    完整中断配置例子----把GPIO4事件映射到INT4


    1. CSL_Status                  intStat;  
    2. CSL_IntcContext             gpiocontext;  
    3. CSL_IntcEventHandlerRecord  isr_gpio;  
    4. CSL_IntcEventHandlerRecord  record[1];  
    5. CSL_IntcGlobalEnableState   state;  
    6. CSL_IntcParam               vectId;  
    7. CSL_IntcHandle              gpioIntcHandle;  
    8. CSL_IntcObj                 gpioIntcObj;  
    9.   
    10.   
    11. static void HANDLE_INTR4(void *arg)  
    12. {  
    13.     //中断服务程序  
    14. }  
    15. /*----------------------------------------------------------------------------------- 
    16.  *  
    17.  *                  初始化外部中断4     
    18.  *  
    19.  -----------------------------------------------------------------------------------*/  
    20. void InitAndEnableIntc4(void)  
    21. {      
    22.     //初始化  
    23.     gpiocontext.numEvtEntries = 1;  
    24.     gpiocontext.eventhandlerRecord = record;  
    25.     intStat = CSL_intcInit(&gpiocontext);     
    26.       
    27.     //使能NMI(不可屏蔽中断)  
    28.     intStat = CSL_intcGlobalNmiEnable();  
    29.       
    30.     //全局中断使能  
    31.     intStat = CSL_intcGlobalEnable(&state);   
    32.       
    33.     //打开中断模块(把GPIO4中断事件映射到系统中断INT4)  
    34.     vectId = CSL_INTC_VECTID_4;  
    35.     gpioIntcHandle = CSL_intcOpen(&gpioIntcObj, CSL_INTC_EVENTID_GPINT4, &vectId, &intStat);      
    36.         
    37.     //绑定中断服务程序  
    38.     isr_gpio.handler = (CSL_IntcEventHandler)&HANDLE_INTR4;  
    39.     CSL_intcPlugEventHandler(gpioIntcHandle, &isr_gpio); //绑定  
    40.       
    41.     //使能该事件(开始监听)  
    42.     CSL_intcHwControl(gpioIntcHandle, CSL_INTC_CMD_EVTENABLE, NULL);  
    43. }  




    通过本文以及上一篇文章,我们应该对DSP6000系列的GPIO和中断系统有了一定的了解。(注,本文只是基本的介绍C6000的中断系统,有不少部分没有涉及,若要了解更多,请参考TI官方文档)


    接下来将介绍:

    • DSP的EDMA系统与EMIFA接口
    • FPGA的乒乓RAM应用
    • CCIR656视频标准(PAL)
    • FPGA与DSP实现的视频采集与传输实验

  • 相关阅读:
    Servlet 规范 简介
    Redis简介
    some tips
    初识Servlet
    JVM基础知识
    使用typora编辑博客
    航海が始まる日
    比较好的IT教程网
    vue 使用心得---工作中一些关键点
    Vue父组件主动获取子组件的数据和方法
  • 原文地址:https://www.cnblogs.com/youngforever/p/3104729.html
Copyright © 2011-2022 走看看