如果你想实际地"看到"产生的中断, 向硬件设备写不足够; 一个软件处理必须在系统中配 置. 如果 Linux 内核还没有被告知来期待你的中断, 它简单地确认并忽略它.

中断线是一个宝贵且常常有限的资源, 特别当它们只有 15 或者 16 个时. 内核保持了中 断线的一个注册, 类似于 I/O 端口的注册. 一个模块被希望来请求一个中断通道(或者 IRQ, 对于中断请求), 在使用它之前, 并且当结束时释放它. 在很多情况下, 也希望模块 能够与其他驱动共享中断线, 如同我们将看到的. 下面的函数, 声明在

<linux/interrupt.h>, 实现中断注册接口:

int request_irq(unsigned int irq,

irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags,

const char *dev_name, void *dev_id);

void free_irq(unsigned int irq, void *dev_id);

从 request_irq 返回给请求函数的返回值或者是 0 指示成功, 或者是一个负的错误码, 如同平常. 函数返回 -EBUSY 来指示另一个驱动已经使用请求的中断线是不寻常的. 函数 的参数如下:

unsigned int irq

请求的中断号 irqreturn_t (*handler)

安装的处理函数指针. 我们在本章后面讨论给这个函数的参数以及它的返回值. unsigned long flags

如你会希望的, 一个与中断管理相关的选项的位掩码(后面描述). const char *dev_name

这个传递给 request_irq 的字串用在 /proc/interrupts 来显示中断的拥有者(下 一节看到)

void *dev_id

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

flags 中可以设置的位如下:

221

SA_INTERRUPT

当置位了, 这表示一个"快速"中断处理. 快速处理在当前处理器上禁止中断来执行 (这个主题在"快速和慢速处理"一节涉及).

SA_SHIRQ

这个位表示中断可以在设备间共享. 共享的概念在"中断共享"一节中略述.

SA_SAMPLE_RANDOM

这个位表示产生的中断能够有贡献给
/dev/random 和 /dev/urandom 使用的加密 池. 这些设备在读取时返回真正的随机数并且设计来帮助应用程序软件为加密选择 安全钥. 这样的随机数从一个由各种随机事件贡献的加密池中提取的. 如果你的设 备以真正随机的时间产生中断, 你应当设置这个标志. 如果, 另一方面, 你的中断
是可预测的( 例如, 一个帧抓取器的场消隐), 这个标志不值得设置 -- 它无论如 何不会对系统加密有贡献. 可能被攻击者影响的设备不应当设置这个标志; 例如, 网络驱动易遭受从外部计时的可预测报文并且不应当对加密池有贡献. 更多信息看 drivers/char/random.c 的注释.

中断处理可以在驱动初始化时安装或者在设备第一次打开时.
尽管从模块的初始化函数中 安装中断处理可能听来是个好主意, 它常常不是, 特别当你的设备不共享中断. 因为中断 线数目是有限的, 你不想浪费它们. 你可以轻易使你的系统中设备数多于中断数.如果一 个模块在初始化时请求一个 IRQ, 它阻止了任何其他的驱动使用这个中断, 甚至这个持有 它的设备从不被使用. 在设备打开时请求中断, 另一方面, 允许某些共享资源.

例如, 可能与一个 modem 在同一个中断上运行一个帧抓取器, 只要你不同时使用这 2 个 设备. 对用户来说是很普通的在系统启动时为一个特殊设备加载模块, 甚至这个设备很少 用到. 一个数据获取技巧可能使用同一个中断作为第 2 个串口. 虽然不是太难避免在数 据获取时联入你的互联网服务提供商(ISP), 被迫卸载一个模块为了使用 modem 确实令人 不快.

调用 request_irq 的正确位置是当设备第一次打开时, 在硬件被指示来产生中断前. 调 用
free_irq 的位置是设备最后一次被关闭时, 在硬件被告知不要再中断处理器之后. 这 个技术的缺点是你需要保持一个每设备的打开计数, 以便于你知道什么时候中断可以被禁
止.

尽管这个讨论,
short 还在加载时请求它的中断线. 这样做是为了你可以运行测试程序而 不必运行一个额外的进程来保持设备打开. short, 因此, 从它的初始化函数

( short_init )请求中断, 不是在 short_open 中做, 象一个真实设备驱动.

下面代码请求的中断是
short_irq. 变量的真正赋值(即, 决定使用哪个 IRQ )在后面显 示, 因为它和现在的讨论无关. short_base 是使用的并口 I/O 基地址;
接口的寄存器 2 被写入来使能中断报告.

if (short_irq >= 0)

{

222

result =
request_irq(short_irq, short_interrupt,

SA_INTERRUPT, "short", NULL);

if (result) {

printk(KERN_INFO
"short: can't get assigned irq %i\n", short_irq);

short_irq = -1;

} else { /* actually
enable it -- assume this *is* a parallel port */ outb(0x10,short_base+2);

}

}

代码显示,
安装的处理是一个快速处理(SA_INTERRUPT), 不支持中断共享(SA_SHIRQ 没 有), 并且不对系统加密有贡献(SA_SAMPLE_RANDOM
也没有). outb 调用接着为并口使能 中断报告.

由于某些合理原因, i386
和 x86_64 体系定义了一个函数来询问一个中断线的能力:

int
can_request_irq(unsigned int irq, unsigned long flags);

这个函数当试图分配一个给定中断成功时返回一个非零值. 但是, 注意, 在 can_request_irq 和
request_irq 的调用之间事情可能一直改变.

linux 安装一个中断处理的更多相关文章

  1. linux 安装一个共享的处理者

    共享中断通过 request_irq 来安装就像不共享的一样, 但是有 2 个不同: SA_SHIRQ 位必须在 flags 参数中指定, 当请求中断时. dev_id 参数必须是独特的. 任何模块地 ...

  2. linux安装fasttext报错,升级gcc后成功解决

    首先说一下存在问题: 本人打算在linux安装一个fasttext用来训练词向量,本来是想要从gensim来调用fasttext的,但是加载大的本地txt一直不对,没办法了只好在linux安装一个fa ...

  3. Memcahce(MC)系列(两)Linux下一个Memcache安装

    Linux下一个memcache安装 memcache是高性能.分布式的内存对象缓存系统,用于在动态应用中降低数据库负载.提升訪问速度.眼下用memcache解决互联网上的大用户读取是很流行的一种使用 ...

  4. 在本机使用虚拟机安装一个linux系统,并搭建ftp服务器

    一.Linux基础使用:linux服务器环境搭建(FTP服务器), 在本机使用虚拟机安装一个linux系统,并搭建ftp服务器,要求能使用ftp服务将本机文件到保存linux虚拟机上 资料: VMwa ...

  5. Linux安装LAMP开发环境及配置文件管理

    Linux主要分为两大系发行版,分别是RedHat和Debian,lamp环境的安装和配置也会有所不同,所以分别以CentOS 7.1和Ubuntu 14.04做为主机(L) Linux下安装软件,最 ...

  6. linux安装php

    接上篇:linux安装apache 一.安装php 先安装libxml2库 [root@ctxsdhy package]# yum -y install libxml2-devel 最新地址在:htt ...

  7. linux安装oracle11g

    准备oracle安装文件 Oracle11gR2包含两个文件linux_11gR2_database_1of2.zip和linux_11gR2_database_2of2.zip,将这两个文件通过SS ...

  8. Symantec Backup Exec 2010 Agent For Linux安装

    以前写过一篇文章介绍过Symantec Backup Exec 2012 Agent For Linux安装安装,今天介绍一下Symantec Backup Exec 2010 Agent For L ...

  9. Linux安装软件总结(二.几种安装命令介绍)

    一.rpm包安装方式步骤: 1.找到相应的软件包,比如soft.version.rpm,下载到本机某个目录: 2.打开一个终端,su -成root用户: 3.cd soft.version.rpm所在 ...

随机推荐

  1. ES6 中字符串的扩展

    1. 字符的Unicode表示法 JavaScript允许采用 \uxxxx 形式表示一个字符,其中 xxxx 表示字符的 Unicode 码点. "\u0061" // 表示小写 ...

  2. js将canvas保存成图片并下载

    <canvas id="canvas" width="400" height="400"></canvas> < ...

  3. LintCode A+B问题

    给出两个整数a和b, 求他们的和, 但不能使用 + 等数学运算符. 说明 a和b都是 32位 整数么? 是的 我可以使用位运算符么? 当然可以 样例 如果 a=1 并且 b=2,返回3 1.(忽略进位 ...

  4. 遗传算法MATLAB实现(3):多元函数优化举例

    多峰的Shubert为: 求f(x,y)在[-10,10]x[-10,10]上的最大值. MATLAB代码: fun_mutv函数为: function my=fun_mutv(x,y) t1=zer ...

  5. Spring Boot 学习填的坑一

    1.关于springBoot自动扫描规则: SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描! "Application"类是指 ...

  6. day39-Spring 14-Spring的JDBC模板:DBCP连接池配置

    一般常用的连接池是DBCP和C3P0. package cn.itcast.spring3.demo1; import java.sql.DriverManager; import org.junit ...

  7. 「WC2018」即时战略

    「WC2018」即时战略 考虑对于一条链:直接随便找点,然后不断问即可. 对于一个二叉树,树高logn,直接随便找点,然后不断问即可. 正解: 先随便找到一个点,问出到1的路径 然后找别的点,考虑问出 ...

  8. 为什么printf()用%f输出double型,而scanf却用%lf呢?

    之前没有注意过这个问题,  转自: http://book.51cto.com/art/200901/106880.htm 问:有人告诉我不能在printf中使用%lf.为什么printf()用%f输 ...

  9. 【NS2】ubuntu安装和同时使用不同版本的ns2(转载)

    有时候我们可能会遇到要同时安装两个ns版本的问题,比如我研究wimax/802.16,因为协议太复杂,用的是长庚大学和nist的wimax补丁.长庚大学的wimax补丁是在ns2.29下开发的,nis ...

  10. mysql 计算两个时间之间有多少分钟

    SELECT TIMESTAMPDIFF(MINUTE, (DATE_FORMAT('2015-08-12 10:38:00','%Y-%m-%d %H:%i')), (DATE_FORMAT('20 ...