Linux设备驱动开发基础---Linux内核中断原理

一、Linux中中断原理

1、中断的分类

在Linux操作系统中,中断的分类是非常复杂的。根据不同的角度,可以将中断分为不同的类型。

根据中断的来源,中断可分为内部中断和外部中断,内部中断的中断源来自CPU内部(软件中断指令、溢出、除法错误等,例如,操作系统从用户态切换到内核态需借助CPU内部的软件中断) ,外部中断的中断源来自CPU外部,由外设提出请求。 

根据是否可以屏蔽中断分为可屏蔽中断与不屏蔽中断 (NMI) ,可屏蔽中断可以通过屏蔽字被屏蔽,屏蔽后,该中断不再得到响应,而不屏蔽中断不能被屏蔽。 

根据中断入口跳转方法的不同,中断分为向量中断和非向量中断。采用向量中断的 CPU 通常为不同的中断分配不同的中断号,当检测到某中断号的中断到来后,就自动跳转到与该中断号对应的地址执行。不同中断号的中断有不同的入口地址。非向量中断的多个中断共享一个入口地址,进入该入口地址后再通过软件判断中断标志来识别具体是哪个中断。也就是说,向量中断由硬件提供中断服务程序入口地址,非向量中断由软件提供中断服务程序入口地址。

2、Linux中断处理程序架构

 设备的中断会打断内核中进程的正常调度和运行,系统对更高吞吐率的追求势必要求中断服务程序尽可能地短小精悍。为了在中断执行时间尽可能短和中断处理需完成大量工作之间找到一个平衡点, Linux将中断处理程序分解为两个半部:顶半部(top  half)和底半部(bottom half) 。 

顶半部完成尽可能少的比较紧急的功能,它往往只是简单地读取寄存器中的中断状态并清除中断标志后就进行“登记中断”的工作。 “登记中断”意味着将底半部处理程序挂到该设备的底半部执行队列中去。这样,顶半部执行的速度就会很快,可以服务更多的中断请求。 

这样,中断处理工作的重心就落在了底半部的头上,它来完成中断事件的绝大多数任务。底半部几乎做了中断处理程序所有的事情,而且可以被新的中断打断,这也是底半部和顶半部的最大不同,因为顶半部往往被设计成不可中断。底半部则相对来说并不是非常紧急的,而且相对比较耗时,不在硬件中断服务程序中执行。 

尽管顶半部、底半部的结合能够改善系统的响应能力,但是,如果中断要处理的工作本身很少,则完全可以直接在顶半部全部完成。 

3、Linux中断实现过程

3.1、中断信号线(IRQ)

中断信号线是对中断输入线和终端输出线的统称。终端输入线是指接受中断信号的引脚,中断输出线是指发送中断信号的引脚。

3.2、中断控制器

中断控制器位于ARM处理器核心和中断源之间,外部中断源将中断发到中断控制器,中断控制器根据优先级进行判断,然后通过引脚将中断请求发送给ARM处理器核心。

3.3、申请和释放中断

在Linux设备驱动中,使用中断的设备需要申请和释放对应的中断,分别使用内核提供的request_irq()和free_irq()函数。

1.申请IRQ 

 int request_irq(unsigned int irq, 
                            void  (*handler)(int  irq,  void  *dev_id,  struct  pt_regs *regs), 
                            unsigned long irqflags, 
                            const char * devname, 
                            void *dev_id);   

在Linux2.6中,该函数有<kernel/irq/Manage.c>实现。

irq  是要申请的硬件中断号。 
handler  表示要注册的中断处理函数指针,是一个回调函数,中断发生时,系统调用这个函数来处理中断,dev_id参数将被传递给它。 

irqflags  是中断处理的属性,若设置了 SA_INTERRUPT,则表示中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;若设置了SA_SHIRQ,则表示多个设备共享中断。

devname 表示设备的名字,该名字会在/proc/interrupts中显示。

dev_id  这个指针是为共享中断线而设立的。如果不需要中断共享中断线,那么只要将该指针设为 NULL即可。 很多资料中都建议将设备结构指针作为dev_id参数

request_irq() 返回0表示成功,否则返回对应错误的负值,返回-INVAL 表示中断号无效或处理函数指针为NULL,返回-EBUSY 表示中断已经被占用且不能共享。 

2.释放IRQ

当设备不需要中断线时,需要释放中断线,中断信号线是非常紧缺的。

与request_irq()向对应的函数为free_irq(),free_irq()的原型如下: 
 void free_irq(unsigned int irq,void *dev_id);   
free_irq()中参数的定义与request_irq()相同。 

3.4、底半部机制

Linux系统实现底半部的机制主要有tasklet、工作队列和软中断(后续补充)

3.5、


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux设备驱动开发是一个相对复杂的过程,需要开发人员掌握操作系统理论知识以及底层编程技术。开发Linux设备驱动需要遵循一定的规范,如采用统一的设备文件接口和驱动模型等。 最新的Linux 4.0内核设备驱动开发做出了许多改进和完善。例如,内核提供了一套完整的设备模型框架,支持不同种类的设备驱动程序,为驱动程序的开发提供了强大的支撑力。此外,内核还提供了许多通用的接口,如字符设备接口、块设备接口和网络接口等,方便开发人员进行设备的编程。 在Linux设备驱动开发中,驱动程序是核心部分。驱动程序可分为字符设备驱动、块设备驱动、网络设备驱动和USB设备驱动等不同类型。不同类型的驱动程序有着不同的运行机制和编程模式。作为开发人员,需要根据实际应用场景选择相应的驱动类型并进行开发。 此外,在开发Linux设备驱动时,需要注意一些问题。如调试技巧、安全问题、性能优化等。在进行驱动程序开发的同时,应当通过逐步加强对Linux内核的认识,提高自身的综合能力和编程素质。 综上所述,Linux设备驱动开发是一个相对复杂的过程,需要开发人员具备扎实的理论基础和编程技术,掌握各种设备驱动模型和接口,同时要不断深入内核,提高自身的综合能力和开发水平。 ### 回答2: 随着互联网的快速发展,Linux系统在嵌入式领域、智能设备、服务器等方面得到了广泛的应用。而在这些应用场景中,设备驱动Linux系统中至关重要的一个组成部分,设备驱动开发难度也是相当大的。 随着Linux内核的不断更新,设备驱动开发也在不断地得到改进和完善。最新的Linux 4.0内核设备驱动开发带来了很多新的特性和改进。 在Linux 4.0内核中,设备驱动开发已经不再是需要手动编写大量代码的繁琐工作了。新的特性如内核自带的驱动框架、自动化的内存管理、图形化的用户空间接口等,都大大简化了设备驱动开发难度。 此外,Linux 4.0内核还增强了对硬件设备的支持,包括新的USB 3.1规范、Type-C接口、Intel Skylake等新型硬件设备。 总之,Linux设备驱动开发是一项很复杂的任务,需要掌握大量的专业知识和技能。但是,随着Linux内核的不断更新和完善,设备驱动开发也变得更加容易和快速了。我们只需要了解最新版本的Linux内核所提供的特性和工具,就能够轻松地开发高效、可靠的设备驱动。 ### 回答3: Linux设备驱动开发详解是一本基于最新的Linux 4.0内核的书籍,主要介绍了Linux设备驱动开发的相关知识和技术。 在Linux系统中,设备驱动是让硬件与操作系统进行交互的重要组成部分。本书介绍了Linux设备驱动的编写和调试方法,深入探讨了驱动开发中的各个环节和技术,包括硬件接口、设备结构体、内存映射、中断处理、定时器、信号量、进程管理等。此外,该书还详细说明了字符设备、块设备、网络设备和USB驱动的编写方法及技巧,让读者能够全面深入地了解设备驱动开发过程。 Linux设备驱动开发详解利用大量实例和案例进行讲解,在保证理论知识的基础上,加深了读者对各种情况下的设备驱动开发实践的理解,确保读者能够迅速上手开发和调试自己的设备驱动程序。 总之,此书深度剖析了Linux设备驱动开发的方方面面,可以为学习、实践Linux设备驱动开发的读者提供全面、深入的指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值