Linux字符设备驱动--No.2
分析中断注册函数: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的更多相关文章
- 深入理解Linux字符设备驱动
		
文章从上层应用访问字符设备驱动开始,一步步地深入分析Linux字符设备的软件层次.组成框架和交互.如何编写驱动.设备文件的创建和mdev原理,对Linux字符设备驱动有全面的讲解.本文整合之前发表的& ...
 - Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】
		
本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...
 - Smart210学习记录----beep linux字符设备驱动
		
今天搞定了beep linux字符设备驱动,心里还是很开心的,哈哈...但在完成的过程中却遇到了一个非常棘手的问题,花费了我大量的时间,,,, 还是把问题描述一下吧,好像这个问题很普遍的,网上许多解决 ...
 - Linux字符设备驱动实现
		
Linux字符设备驱动实现 要求 编写一个字符设备驱动,并利用对字符设备的同步操作,设计实现一个聊天程序.可以有一个读,一个写进程共享该字符设备,进行聊天:也可以由多个读和多个写进程共享该字符设备,进 ...
 - Linux字符设备驱动基本结构
		
1.Linux字符设备驱动的基本结构 Linux系统下具有三种设备,分别是字符设备.块设备和网络设备,Linux下的字符设备是指只能一个字节一个字节读写的设备,不能随机读取设备内存中某一数据,读取数据 ...
 - (57)Linux驱动开发之三Linux字符设备驱动
		
1.一般情况下,对每一种设备驱动都会定义一个软件模块,这个工程模块包含.h和.c文件,前者定义该设备驱动的数据结构并声明外部函数,后者进行设备驱动的具体实现. 2.典型的无操作系统下的逻辑开发程序是: ...
 - Linux字符设备驱动框架
		
字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l ...
 - Linux 字符设备驱动模型
		
一.使用字符设备驱动程序 1. 编译/安装驱动 在Linux系统中,驱动程序通常采用内核模块的程序结构来进行编码.因此,编译/安装一个驱动程序,其实质就是编译/安装一个内核模块 2. 创建设备文件 通 ...
 - linux字符设备驱动学习笔记(一):简单的字符设备驱动
		
最近在鼓捣lnux字符设备驱动,在网上搜集的各种关于linux设备驱动的代码和注释,要么是针对2.4的,要么是错误百出,根本就不能运行成功,真希望大家在发博客的时候能认真核对下代码的正确性,特别是要把 ...
 - Linux字符设备驱动
		
一.字符设备基础 字符设备 二.字符设备驱动与用户空间访问该设备的程序三者之间的关系 三.字符设备模型 1.Linux内核中,使用 struct cdev 来描述一个字符设备 动态申请(构造)cdev ...
 
随机推荐
- l2tp over ipsec
			
搭建教程: 转自: https://segmentfault.com/a/1190000006125737 http://www.wangyuxiong.com/blog/ti-yan-qiang-w ...
 - 【转】Linux中/etc/profile,/etc/bashrc,~/.profile,~/.bashrcd的区别
			
//因为在原文章中博主说以下内容是网友说的,所以我就只加个转了,找不到原作者 /etc/profile,/etc/bashrc 是系统全局环境变量设定 ~/.profile,~/.bashrc用户家目 ...
 - 网络分析 ANP
			
在许多实际问题中,各层次内部元素往往是依赖的. 低层元素对高层元素亦有支配作用,即存在反馈. 此时系统的结构更类似于网络结构.网络分析法正是适应这种需要,由AHP延伸发展得到的系统决策方法. AN ...
 - [零基础学JAVA]Java SE基础部分-03. 运算符和表达式
			
转自:http://redking.blog.51cto.com/27212/116751 1.课程名称:运算符.表达式 讲解了JAVA中各种运算符的使用,包括与.或.非.大于.小于等. 2.知识点 ...
 - 【HAOI2010】工厂选址题解
			
题目描述 某地区有m座煤矿,其中第i号矿每年产量为ai吨,现有火力发电厂一个,每年需用煤b吨,每年运行的固定费用(包括折旧费,不包括煤的运费)为h元,每吨原煤从第i号矿运到原有发电厂的运费为Ci0(i ...
 - cin,get,getline
			
一.cin 1.cin使用空白(空格.制表符和换行符)来确定字符串结束的位置,并且对于换行符,cin会把换行符留在输入队列.cin读取字符串放到数组中,并自动在结尾添加空字符. 例如: ]; cin& ...
 - 一张图解释 implicit
 - 【题解】洛谷P2704 [NOI2001] 炮兵阵地(状压DP)
			
洛谷P2704:https://www.luogu.org/problemnew/show/P2704 思路 这道题一开始以为是什么基于状压的高端算法 没想到只是一道加了一行状态判断的状压DP而已 与 ...
 - HDU 2089(暴力和数位dp)
			
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2089 不要62 Time Limit: 1000/1000 MS (Java/Others) M ...
 - java线程安全单例
			
public class MySingleton { // 使用volatile关键字保其可见性 volatile private static MySingleton instance = null ...