⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux设备驱动程序学习(11)-中断处理 - linux设备驱动程序 - tekkaman ninja.htm

📁 Linux设备驱动程序学习(11)-中断处理 - Linux设备驱动程序.rar
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                                style="COLOR: #000000"><FONT face=新宋体><SPAN 
                                style="COLOR: #0000ff">int</SPAN> 
                                can_request_irq<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">int</SPAN> irq<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">long</SPAN> flags<SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <SPAN 
                                style="COLOR: #ff9900">/*当能够成功分配给定中断,则返回非零值。但注意,在 
                                can_request_irq 和 request_irq 
                                的调用之间给定中断可能被占用*/</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
                              <P><FONT color=#0000ff 
                              size=3><STRONG>快速和慢速处理例程</STRONG></FONT></P>
                              <P>快速中断是那些能够很快处理的中断,而处理慢速中断会花费更长的时间。在处理慢速中断时处理器重新使能中断,避免快速中断被延时过长。在现代内核中,快速和慢速中断的区别已经消失,剩下的只有一个:快速中断(使用 
                              SA_INTERRUPT 
                              )执行时禁止所有在当前处理器上的其他中断。注意:其他的处理器仍然能够处理中断。</P>
                              <P>&nbsp;除非你充足的理由在禁止其他中断情况下来运行中断处理例程,否则不应当使用SA_INTERRUPT.</P>
                              <P><FONT color=#0000ff 
                              size=3><STRONG>&nbsp;x86中断处理内幕</STRONG></FONT></P>
                              <P>这个描述是从 2.6 内核 arch/i386/kernel/irq.c, 
                              arch/i386/kernel/ apic.c, 
                              arch/i386/kernel/entry.S, 
                              arch/i386/kernel/i8259.c, 和 
                              include/asm-i386/hw_irq.h 
                              中得出,尽管基本概念相同,硬件细节与其他平台上不同。</P>
                              <P>底层中断处理代码在汇编语言文件 
                              entry.S。在所有情况下,这个代码将中断号压栈并且跳转到一个公共段,公共段会调用 
                              do_IRQ(在 irq.c 中定义)。do_IRQ 
                              做的第一件事是应答中断以便中断控制器能够继续其他事情。它接着获取给定 IRQ 
                              号的一个自旋锁,阻止其他 CPU 处理这个 IRQ,然后清除几个状态位(包括IRQ_WAITING 
                              )然后查找这个 IRQ 
                              的处理例程。若没有找到,什么也不做;释放自旋锁,处理任何待处理的软件中断,最后 do_IRQ 
                              返回。从中断中返回的最后一件事可能是一次处理器的重新调度。</P>
                              <P>&nbsp;IRQ的探测是通过为每个缺乏处理例程的IRQ设置 IRQ_WAITING 
                              状态位来完成。当中断发生, 因为没有注册处理例程,do_IRQ 清除这个位并且接着返回。 
                              当probe_irq_off被一个函数调用,只需搜索没有设置 IRQ_WAITING 的 
                              IRQ。</P>
                              <P><FONT color=#0000ff size=3><STRONG>/proc 
                              接口</STRONG></FONT></P>
                              <P>当硬件中断到达处理器时, 内核提供的一个内部计数器会递增,产生的中断报告显示在文件 
                              /proc/interrupts中。这一方法可以用来检查设备是否按预期地工作。此文件只显示当前已安装处理例程的中断的计数。若以前<FONT 
                              face=新宋体>request_irq的一个中断,现在已经free_irq了,那么就不会显示在这个文件中,但是它可以显示终端共享的情况。</FONT></P>
                              <P><FONT face=新宋体>/proc/stat记录了几个关于系统活动的底层统计信息, 
                              包括(但不仅限于)自系统启动以来收到的中断数。</FONT><FONT 
                              face=新宋体>&nbsp;stat 的每一行以一个字符串开始, 是该行的关键词:intr 
                              标志是中断计数。第一个数是所有中断的总数, 而其他每一个代表一个单独的中断线的计数, 从中断 0 
                              开始(包括当前没有安装处理例程的中断),无法显示终端共享的情况。</FONT></P>
                              <P><FONT face=新宋体>以上两个文件的一个不同是:<FONT 
                              face="Courier New">/proc/interrupts几乎</FONT>不依赖体系,而/proc/stat的字段数依赖内核下的硬件中断,</FONT><FONT 
                              face=新宋体>其定义在<FONT 
                              color=#0000ff>&lt;asm/irq.h&gt;</FONT>中。ARM的定义为:</FONT> 

                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: #000000"><FONT face=新宋体><SPAN 
                                style="COLOR: #0000cc">#</SPAN><SPAN 
                                style="COLOR: #ff0000">define</SPAN> 
                                NR_IRQS&nbsp;&nbsp;&nbsp;&nbsp;128</FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
                              <P>
                              <HR id=null>

                              <P><FONT color=#0000ff size=4><STRONG>自动检测 IRQ 
                              号</STRONG></FONT></P></DIV><FONT color=#0000ff 
                              size=4>
                              <P><FONT color=#000000>驱动初始化时最迫切的问题之一是决定设备要使用的IRQ 
                              线,驱动需要信息来正确安装处理例程。自动检测中断号对驱动的可用性来说是一个基本需求。</FONT><FONT 
                              color=#000000>有时自动探测依赖一些设备具有的默认特性,以下是典型的并口中断探测程序:</P>
                              <P>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: #000000"><FONT face=新宋体><SPAN 
                                style="COLOR: #0000ff">if</SPAN> <SPAN 
                                style="COLOR: #0000cc">(</SPAN>short_irq <SPAN 
                                style="COLOR: #0000cc">&lt;</SPAN> 0<SPAN 
                                style="COLOR: #0000cc">)</SPAN> <SPAN 
                                style="COLOR: #ff9900">/* 
                                依靠使并口的端口号,确定中断*/</SPAN><BR>&nbsp;<SPAN 
                                style="COLOR: #0000ff">switch</SPAN><SPAN 
                                style="COLOR: #0000cc">(</SPAN>short_base<SPAN 
                                style="COLOR: #0000cc">)</SPAN> <SPAN 
                                style="COLOR: #0000cc">{</SPAN><BR>&nbsp;<SPAN 
                                style="COLOR: #0000ff">case</SPAN> 0x378<SPAN 
                                style="COLOR: #0000cc">:</SPAN> short_irq <SPAN 
                                style="COLOR: #0000cc">=</SPAN> 7<SPAN 
                                style="COLOR: #0000cc">;</SPAN> <SPAN 
                                style="COLOR: #0000ff">break</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN><BR>&nbsp;<SPAN 
                                style="COLOR: #0000ff">case</SPAN> 0x278<SPAN 
                                style="COLOR: #0000cc">:</SPAN> short_irq <SPAN 
                                style="COLOR: #0000cc">=</SPAN> 2<SPAN 
                                style="COLOR: #0000cc">;</SPAN> <SPAN 
                                style="COLOR: #0000ff">break</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN><BR>&nbsp;<SPAN 
                                style="COLOR: #0000ff">case</SPAN> 0x3bc<SPAN 
                                style="COLOR: #0000cc">:</SPAN> short_irq <SPAN 
                                style="COLOR: #0000cc">=</SPAN> 5<SPAN 
                                style="COLOR: #0000cc">;</SPAN> <SPAN 
                                style="COLOR: #0000ff">break</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN><BR>&nbsp;<SPAN 
                                style="COLOR: #0000cc">}</SPAN> 
                                </FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
                              <P>有的驱动允许用户在加载时覆盖默认值:</P>
                              <P>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: #000000"><FONT face=新宋体>insmod 
                                xxxxx<SPAN style="COLOR: #0000cc">.</SPAN>ko 
                                irq<SPAN style="COLOR: #0000cc">=</SPAN>x 
                                </FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
                              <P>当目标设备有能力告知驱动它要使用的中断号时,自动探测中断号只是意味着探测设备,无需做额外的工作探测中断。</P>
                              <P>但不是每个设备都对程序员友好,对于他们还是需要一些探测工作。这个工作技术上非常简单: 
                              驱动告知设备产生中断并且观察发生了什么。如果一切顺利,则只有一个中断信号线被激活。尽管探测在理论上简单,但实现可能不简单。有 
                              2 种方法来进行探测中断: <FONT 
                              color=#0000ff><STRONG>调用内核定义的辅助函数</STRONG><FONT 
                              color=#000000>和</FONT><STRONG>DIY探测</STRONG></FONT>。</P>
                              <P><STRONG><FONT color=#0000ff>(1)</FONT><FONT 
                              color=#0000ff>调用内核定义的辅助函数</FONT></STRONG><BR></P></FONT><PRE class=programlisting></FONT>Linux 内核提供了一个底层设施来探测中断号,且只能在非共享中断模式下工作,它包括 2 个函数, 在&lt;linux/interrupt.h&gt; 中声明( 也描述了探测机制 ):<BR></PRE>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: #000000"><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">long</SPAN> 
                                probe_irq_on<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">void</SPAN><SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #ff9900">/*这个函数返回一个未分配中断的位掩码。驱动必须保留返回的位掩码, 
                                并在后面传递给 probe_irq_off。在调用probe_irq_on之后, 
                                驱动应当安排它的设备产生至少一次中断*/</SPAN><BR><BR><SPAN 
                                style="COLOR: #0000ff">int</SPAN> 
                                probe_irq_off<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">long</SPAN><SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #ff9900">/*在请求设备产生一个中断后, 驱动调用这个函数, 
                                并将 probe_irq_on 
                                返回的位掩码作为参数传递给probe_irq_off。probe_irq_off 
                                返回在"probe_on"之后发生的中断号。如果没有中断发生, 返回 0 
                                ;如果产生了多次中断,probe_irq_off 
                                返回一个负值*/</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE>
                              <P>程序员应当注意在调用 probe_irq_on 之后启用设备上的中断, 并在调用 
                              probe_irq_off 前禁用。此外还必须记住在 probe_irq_off 
                              之后服务设备中待处理的中断。<BR>以下是LDD3中的并口示例代码,(并口的管脚 9 和 10 
                              连接在一起,探测五次失败后放弃):</P>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -