分析中断注册函数:request_irq

 int butsOpen(struct inode *p, struct file *f)
 {

         int irq;
     int i;
     ;
     printk(KERN_EMERG"butsOpen\r\n");
     ; i < ARRAY_SIZE(buttons); i++) {
         if (!buttons[i].gpio)
             continue;

         irq = gpio_to_irq(buttons[i].gpio);
         err = request_irq(irq, button_interrupt, IRQ_TYPE_EDGE_BOTH,
14                 buttons[i].name, (void *)&buttons[i]);
         if (err)
             break;
     }

     if (err) {
         i--;
         ; i--) {
             if (!buttons[i].gpio)
                 continue;

             irq = gpio_to_irq(buttons[i].gpio);
             disable_irq(irq);
             free_irq(irq, (void *)&buttons[i]);
         }

         return -EBUSY;
     }
     ;
 }
 request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
2         const char *name, void *dev)
 {
     return request_threaded_irq(irq, handler, NULL, flags, name, dev);
 }
 /**
  *    request_threaded_irq - 分配中断线路函数
  *    @irq: Interrupt line to allocate
  *    @handler: Function to be called when the IRQ occurs.
  *          Primary handler for threaded interrupts
  *          If NULL and thread_fn != NULL the default
  *          primary handler is installed
  *    @thread_fn: Function called from the irq handler thread
  *            If NULL, no irq thread is created
  *    @irqflags: Interrupt type flags
  *    @devname: An ascii name for the claiming device
  *    @dev_id: A cookie passed back to the handler function//作为hanler的一个参数
  *
  *    This call allocates interrupt resources and enables the
  *    interrupt line and IRQ handling. From the point this
  *    call is made your handler function may be invoked. Since
  *    your handler function must clear any interrupt the board
  *    raises, you must take care both to initialise your hardware
  *    and to set up the interrupt handler in the right order.
  *
  *    If you want to set up a threaded irq handler for your device
  *    then you need to supply @handler and @thread_fn. @handler ist
  *    still called in hard interrupt context and has to check
  *    whether the interrupt originates from the device. If yes it
  *    needs to disable the interrupt on the device and return
  *    IRQ_WAKE_THREAD which will wake up the handler thread and run
  *    @thread_fn. This split handler design is necessary to support
  *    shared interrupts.
  *
  *    Dev_id must be globally unique. Normally the address of the
  *    device data structure is used as the cookie. Since the handler
  *    receives this value it makes sense to use it.
  *
  *    If your interrupt is shared you must pass a non NULL dev_id
  *    as this is required when freeing the interrupt.
  *
  *    Flags:
  *
  *    IRQF_SHARED        Interrupt is shared
  *    IRQF_SAMPLE_RANDOM    The interrupt can be used for entropy
  *    IRQF_TRIGGER_*        Specify active edge(s) or level
  *
  */ 
 struct irqaction {
     irq_handler_t handler;
     unsigned long flags;
     void *dev_id;
     struct irqaction *next;
     int irq;
     irq_handler_t thread_fn;
     struct task_struct *thread;
     unsigned long thread_flags;
     unsigned long thread_mask;
     const char *name;
     struct proc_dir_entry *dir;
 } ____cacheline_internodealigned_in_smp;

struct irqaction

 /**
  * struct irq_desc - interrupt descriptor
  * @irq_data:        per irq and chip data passed down to chip functions
  * @timer_rand_state:    pointer to timer rand state struct
  * @kstat_irqs:        irq stats per cpu
  * @handle_irq:        highlevel irq-events handler
  * @preflow_handler:    handler called before the flow handler (currently used by sparc)
  * @action:        the irq action chain
  * @status:        status information
  * @core_internal_state__do_not_mess_with_it: core internal status information
  * @depth:        disable-depth, for nested irq_disable() calls
  * @wake_depth:        enable depth, for multiple irq_set_irq_wake() callers
  * @irq_count:        stats field to detect stalled irqs
  * @last_unhandled:    aging timer for unhandled count
  * @irqs_unhandled:    stats field for spurious unhandled interrupts
  * @lock:        locking for SMP
  * @affinity_hint:    hint to user space for preferred irq affinity
  * @affinity_notify:    context for notification of affinity changes
  * @pending_mask:    pending rebalanced interrupts
  * @threads_oneshot:    bitfield to handle shared oneshot threads
  * @threads_active:    number of irqaction threads currently running
  * @wait_for_threads:    wait queue for sync_irq to wait for threaded handlers
  * @dir:        /proc/irq/ procfs entry
  * @name:        flow handler name for /proc/interrupts output
  */
 struct irq_desc {
     struct irq_data        irq_data;
     struct timer_rand_state *timer_rand_state;
     unsigned int __percpu    *kstat_irqs;
     irq_flow_handler_t    handle_irq;
 #ifdef CONFIG_IRQ_PREFLOW_FASTEOI
     irq_preflow_handler_t    preflow_handler;
 #endif
     struct irqaction    *action;    /* IRQ action list */
     unsigned int        status_use_accessors;
     unsigned int        core_internal_state__do_not_mess_with_it;
     unsigned int        depth;        /* nested irq disables */
     unsigned int        wake_depth;    /* nested wake enables */
     unsigned int        irq_count;    /* For detecting broken IRQs */
     unsigned long        last_unhandled;    /* Aging timer for unhandled count */
     unsigned int        irqs_unhandled;
     raw_spinlock_t        lock;
 #ifdef CONFIG_SMP
     const struct cpumask    *affinity_hint;
     struct irq_affinity_notify *affinity_notify;
 #ifdef CONFIG_GENERIC_PENDING_IRQ
     cpumask_var_t        pending_mask;
 #endif
 #endif
     unsigned long        threads_oneshot;
     atomic_t        threads_active;
     wait_queue_head_t       wait_for_threads;
 #ifdef CONFIG_PROC_FS
     struct proc_dir_entry    *dir;
 #endif
     const char        *name;
 } ____cacheline_internodealigned_in_smp;

struct irq_desc

 int request_threaded_irq(unsigned int irq, irq_handler_t handler,
              irq_handler_t thread_fn, unsigned long irqflags,
              const char *devname, void *dev_id)
 {
     struct irqaction *action;
     struct irq_desc *desc;
     int retval;

     /*
      * Sanity-check: shared interrupts must pass in a real dev-ID,
      * otherwise we'll have trouble later trying to figure out
      * which interrupt is which (messes up the interrupt freeing
      * logic etc).
      */
     if ((irqflags & IRQF_SHARED) && !dev_id)//若终端标志是共享中断,则设备号dev_id不允许为空
         return -EINVAL;

     desc = irq_to_desc(irq);
     if (!desc)
         return -EINVAL;

     if (!irq_settings_can_request(desc))
         return -EINVAL;

     if (!handler) {
         if (!thread_fn)
             return -EINVAL;
         handler = irq_default_primary_handler;
     }

     action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
     if (!action)
         return -ENOMEM;

     action->handler = handler;
     action->thread_fn = thread_fn;
     action->flags = irqflags;
     action->name = devname;
     action->dev_id = dev_id;

     chip_bus_lock(desc);
     retval = __setup_irq(irq, desc, action);
     chip_bus_sync_unlock(desc);

     if (retval)
         kfree(action);

 #ifdef CONFIG_DEBUG_SHIRQ_FIXME
     if (!retval && (irqflags & IRQF_SHARED)) {
         /*
          * It's a shared IRQ -- the driver ought to be prepared for it
          * to happen immediately, so let's make sure....
          * We disable the irq to make sure that a 'real' IRQ doesn't
          * run in parallel with our fake.
          */
         unsigned long flags;

         disable_irq(irq);
         local_irq_save(flags);

         handler(irq, dev_id);

         local_irq_restore(flags);
         enable_irq(irq);
     }
 #endif
     return retval;
 }
 #define irq_to_desc(irq)    (&irq_desc[irq])

Linux字符设备驱动--No.2的更多相关文章

  1. 深入理解Linux字符设备驱动

    文章从上层应用访问字符设备驱动开始,一步步地深入分析Linux字符设备的软件层次.组成框架和交互.如何编写驱动.设备文件的创建和mdev原理,对Linux字符设备驱动有全面的讲解.本文整合之前发表的& ...

  2. Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】

    本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...

  3. Smart210学习记录----beep linux字符设备驱动

    今天搞定了beep linux字符设备驱动,心里还是很开心的,哈哈...但在完成的过程中却遇到了一个非常棘手的问题,花费了我大量的时间,,,, 还是把问题描述一下吧,好像这个问题很普遍的,网上许多解决 ...

  4. Linux字符设备驱动实现

    Linux字符设备驱动实现 要求 编写一个字符设备驱动,并利用对字符设备的同步操作,设计实现一个聊天程序.可以有一个读,一个写进程共享该字符设备,进行聊天:也可以由多个读和多个写进程共享该字符设备,进 ...

  5. Linux字符设备驱动基本结构

    1.Linux字符设备驱动的基本结构 Linux系统下具有三种设备,分别是字符设备.块设备和网络设备,Linux下的字符设备是指只能一个字节一个字节读写的设备,不能随机读取设备内存中某一数据,读取数据 ...

  6. (57)Linux驱动开发之三Linux字符设备驱动

    1.一般情况下,对每一种设备驱动都会定义一个软件模块,这个工程模块包含.h和.c文件,前者定义该设备驱动的数据结构并声明外部函数,后者进行设备驱动的具体实现. 2.典型的无操作系统下的逻辑开发程序是: ...

  7. Linux字符设备驱动框架

    字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l ...

  8. Linux 字符设备驱动模型

    一.使用字符设备驱动程序 1. 编译/安装驱动 在Linux系统中,驱动程序通常采用内核模块的程序结构来进行编码.因此,编译/安装一个驱动程序,其实质就是编译/安装一个内核模块 2. 创建设备文件 通 ...

  9. linux字符设备驱动学习笔记(一):简单的字符设备驱动

    最近在鼓捣lnux字符设备驱动,在网上搜集的各种关于linux设备驱动的代码和注释,要么是针对2.4的,要么是错误百出,根本就不能运行成功,真希望大家在发博客的时候能认真核对下代码的正确性,特别是要把 ...

  10. Linux字符设备驱动

    一.字符设备基础 字符设备 二.字符设备驱动与用户空间访问该设备的程序三者之间的关系 三.字符设备模型 1.Linux内核中,使用 struct cdev 来描述一个字符设备 动态申请(构造)cdev ...

随机推荐

  1. iotop使用详解

    iotop是top和iostat程序的混合体,能够显示系统中所有运行进程并将进程根据I/O统计信息排序. 这个软件使用了Linux内核的一些新特性,所以需要2.6.20或者更新的内核. 一般默认情况下 ...

  2. jQuery解决高度统一问题

    <div class="itemdl over"> <dl class="fl"> <dt><img src=&quo ...

  3. dedecms Ajax异步获取文章列表

    dedecms如何通过ajax(异步)动态获取文章列表数据. 第一步添加:服务端(PHP)代码 打开plus目录下面的list.php文件,在12行代码下面添加以下代码: if(isset($_GET ...

  4. mongodb 备份、还原、导入、导出

    mongodump备份数据库 常用的备份命令格式 mongodump -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -o 文件存在路径 如果想导出所有数据库,可以去掉-d - ...

  5. 大数因式分解 Pollard_rho 算法详解

    给你一个大数n,将它分解它的质因子的乘积的形式. 首先需要了解Miller_rabin判断一个数是否是素数 大数分解最简单的思想也是试除法,这里就不再展示代码了,就是从2到sqrt(n),一个一个的试 ...

  6. 通过渲染器Shader实现图像变换效果

    在上一篇文章中,一起学习了通过设定画笔风格来实现图形变换,没读过的朋友可以点击下面链接: http://www.cnblogs.com/fuly550871915/p/4886455.html 是不是 ...

  7. Django CreateView 简单使用

    django.views.generic中的CreateView类,是基于View的子类.CreateView可以简单快速的创建表对象. 下面记录小作代码. # polls/views.py from ...

  8. UVa 1609 - Foul Play

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  9. UVA151 Power Crisis

    嘟嘟嘟 这道题被评为紫题完全是在假(虽然我也跟风评了紫题),顶多黄题难度. 评黄题的主要原因是得知道约瑟夫递推公式,即fn = (fn - 1 +m) % n.表示n个人报数最后的获胜者,需要注意的是 ...

  10. waring L16: uncalled segement ----keil

    1.keil中出现waring:uncalled segement 2.waring L16:这个应该是一个waring等级 3.  转载自 wpb3dm 在Keil C中,如果没有显式调用到定义过的 ...