• 【转】对于中断函数返回值的分析


    原文网址:http://blog.csdn.net/kangear/article/details/8131125

    在一次自己编写中断处理函数的时候,没有写函数的返回值,make的时候是正常编译通过的,但是在运行过程中就报错了,于是对中断函数的返回值进行了一定的了解,总结一下。

    1.中断的注册与释放:
    实现中断注册接口:

    [cpp] view plaincopy
     
    1. /*------------------------------------------------------------------------------------*/  
    2. int request_irq(unsigned int irq,  
    3. irqreturn_t (*handler)(int, void *,  
    4. struct pt_regs *),  
    5. unsigned long flags,  
    6. const char *dev_name,  
    7. void *dev_id);  
    8.   
    9. void free_irq(unsigned int irq, void *dev_id);  
    10. /*------------------------------------------------------------------------------------*/  

    其中函数中的参数说明
    unsigned int irq:所要注册的中断号
    irqreturn_t (*handler)(int, void *, struct pt_regs *):中断服务程序的入口地址。
    unsigned long flags:与中断管理有关的位掩码选项,有三组值:
    (1). SA_INTERRUPT :快速中断处理程序,当使用它的是后处理器上所有的其他中断都被禁用。
    (2). SA_SHIRQ :该中断是在设备之间可共享的
    (3). SA_SAMPLE_RANDOM:这个位表示产生的中断能够有贡献给 /dev/random和 /dev/urandom 使用的加密池。
    const char *dev_name:设备描述,表示那一个设备在使用这个中断。

    void *dev_id:用作共享中断线的指针。它是一个独特的标识, 用在当释放中断线时以及可能还被驱动用来指向它自己的私有数据区(来标识哪个设备在中断) 。这个参数在真正的驱动程序中一般是指向设备数据结构的指针。在调用中断处理程序的时候它就会传递给中断处理程序的void *dev_id。(这是我的理解)如果中断没有被共享, dev_id 可以设置为 NULL, 但是使用这个项指向设备结构不管如何是个好主意。我们将在"实现一个处理"一节中看到 dev_id 的一个实际应用。

    中断号的查看可以使用下面的命令:“cat /proc/interrupts”。

    /proc/stat 记录了几个关于系统活动的低级统计量, 包括(但是不限于)自系统启动以来收到的中断数。stat 的每一行以一个文本字串开始, 是该行的关键词。
    第一个数是所有中断的总数, 而其他每一个代表一个单个 IRQ 线, 从中断 0 开始,所有的计数跨系统中所有处理器而汇总的。这个快照显示, 中断号 4 已使用 1 次, 尽管当前没有安装处理。

    以下是一个统计中断时间间隔的中断服务程序。

    [cpp] view plaincopy
     
    1. /*------------------------------------------------------------------------------------*/  
    2. irqreturn_t short_interrupt(int irq, void *dev_id, struct pt_regs *regs)  
    3. {  
    4. static long mytime=0;  
    5. static int i=0;  
    6. struct net_device *dev=(struct net_device *)dev_id;  
    7.   
    8. if(i==0){  
    9. mytime=jiffies;  
    10. }else  
    11. if(iname,dev->irq);  
    12. }  
    13.   
    14. i++;  
    15. return IRQ_HANDLED;  
    16. }  
    17. /*------------------------------------------------------------------------------------*/  

    这个函数实现的只是对两次发生中断的时间间隔的统计,时间单位是毫秒

    函数参数说明:
    int irq :在这里很明显传递过来的是中断号
    void *dev_id :这个传递来的是设备的id号,可以根据这个设备id号得到相应设备的数据结构,进而的到相应设备的信息和相关数据。下面以提取网路数据为例来说明一下。
    struct net_device *dev=( struct net_device *)dev_id; (这里的dev_id的值是注册中断的时候宏传递过来的,是注册中断函数的最后一个参数)
    在这之后就可以用dev->name; dev->irq;等得到网络设备的信息了,当然提取ip数据报还得进行一些其它的工作。
    struct pt_regs *regs :它指向一个数据结构,此结构保存的是中断之前处理器的寄存器和状态。主要用在程序调试。
    关于中断处理函数的返回值:中断程序的返回值是一个特殊类型—irqreturn_t。但是中断程序的返回值却只有两个—IRQ_NONE和IRQ_HANDLED。

    /* irqreturn.h */

    #ifndef _LINUX_IRQRETURN_H

    #define _LINUX_IRQRETURN_H

    typedef int irqreturn_t;

    /*For 2.4.x compatibility, 2.4.x can use
    * typedef void irqreturn_t;
    * #define IRQ_NONE
    * #define IRQ_HANDLED
    * #define IRQ_RETVAL(x)
    ...
    * To mix old-style and new-style irq handler returns.
    * IRQ_NONE means we didn't handle it.
    * 中断程序接收到中断信号后发现这并不是注册时指定的中断原发出的中断信号.
    *此时返回次值
    * IRQ_HANDLED means that we did have a valid interrupt and handled it.
    * 接收到了准确的中断信号,并且作了相应正确的处理
    * IRQ_RETVAL(x) selects on the two depending on x being non-zero (for handled)
    */

    #define IRQ_NONE (0)

    #define IRQ_HANDLED (1)

    #define IRQ_RETVAL(x) ((x) != 0) //这个宏只是返回0或非0

    #endif

  • 相关阅读:
    05_XML的解析_01_dom4j 解析
    04_SSM框架整合(Spring+SpringMVC+MyBatis)
    03_入门程序(注解方式,掌握)
    02_入门程序(非注解方式,了解)
    01_SpringMVC流程架构图
    21_resultMap和resultType总结
    20_高级映射:多对多查询
    inline函数的总结
    【C++】C++函数重载的总结
    优先队列
  • 原文地址:https://www.cnblogs.com/wi100sh/p/4875088.html
Copyright © 2020-2023  润新知