读取其信息,那么这些信息就会丢失。
在 Linux 下,硬件中断被称为 IRQ (Interrupt ReQuests)。IRQ 有两种类型,短的与长%
-的。一个短的 IRQ 是一种预计需要很短时间 IRQ,在此期间机器的其余部分将被阻塞并%
-且不会处理其它中断。长 IRQ 可能需要更长的时间,并且在此期间可能会发生其它中断(%
-但不是来自同一设备的中断)。如果可能的话,最好将中断处理程序声明的较长。
-
-当 CPU 收到一个中断时,它会停止正在做的任何事情(除非它正在处理一个更重要的中断,%
-在这种情况下,只有当更重要的中断完成时,它才会处理这个中断)。将某些参数保存在堆%
-栈上并调用中断处理程序。这意味着中断处理程序本身不允许执行某些操作,因为系统处%
-于未知状态。Linux 内核通过将中断处理分为两部分来解决这个问题。第一部分立即执行%
-并屏蔽中断线,硬件中断必须快速处理,这就是为什么我们需要第二部分来处理繁重的工%
-作,并从中断处理中延后执行。历史上,BH (Linux 称为 \textit{Bottom Halves})以统%
-计方式记录延迟函数。\textbf{Softirq} 与它的高级抽象,\textbf{Tasklet},从 Linux %
-2.3 开始替换 BH。
-
-实现的方法是,当有关的 IRQ 被收到时,使用 \cpp|request_irq()| 得到你的中断处理%
-被调用。
-
-在实践中,IRQ 处理可能是有此复杂。硬件通常以链接两个中断控制器的方式被设计,以%
+的。一个短的 IRQ 是一种预计需要很短的时间 IRQ,在此期间机器的其余部分指令将被%
+阻塞并且不会处理其它中断。长 IRQ 可能需要更长的时间,并且在此期间可能会发生其%
+它中断\,(\,但不是来自同一设备的中断\,)。如果可能的话,最好将中断处理程序声明%
+为长中断类型。
+
+当 CPU 收到一个中断时,它会停止正在做的任何事情\,(\,除非它正在处理一个更重要%
+的中断,在这种情况下,只有当更重要的中断完成时,它才会处理这个中断)。将某些参%
+数保存在堆栈上并调用中断处理程序。这意味着中断处理程序本身不允许执行某些操作,%
+因为系统处于未知状态。Linux 内核通过将中断处理分为两部分来解决这个问题。第一部%
+分立即执行并屏蔽中断线,硬件中断必须快速处理,这就是为什么我们需要第二部分来处%
+理繁重的工作,并从中断处理中延后执行。历史上,BH (\,Linux 称为 \textit{Bottom Halves\/}\,)\,%
+以统计方式记录延迟函数。\textbf{Softirq} 与它的高级抽象,\textbf{Tasklet},从 %
+Linux 2.3 开始替换 BH。
+
+实现的方法是,当有关的 IRQ 被收到时,使用 \cpp|request_irq()| 得到你被调用的%
+中断处理例程。
+
+在实践中,IRQ 处理可能是有些复杂。硬件通常以链接两个中断控制器的方式被设计,以%
便来自中断控制器 B 的所有 IRQ 都级联到中断控制器 A 的某个 IRQ。当然,这需要内核%
随后找出它到底是哪个 IRQ,这会增加额外的开销。其它架构提供一些特殊的,非常低的%
-开销,所谓的``快速IRQ''或 FIQ,要利用它们,需要用汇编语方编写处理程序,因此它%
-们并不真正融入内核。
-
-可以使它们与其它 IRQ 类似地工作,但在该过程之后,它们不再比``常见'' IRQ 更快。%
-在具有多个处理器的系统上运行的支持 SMP 的内核需要解决一大堆问题。仅仅知道某个 %
-IRQ 是否发生是不够的,了解它是针对哪个 CPU 也很重要。人们仍然对更多细节感兴趣,%
-现在可能想参考``APIC''。
+开销,所谓的\,``快速IRQ''\,或 FIQ,要利用它们,需要用汇编语言编写处理程序,因此%
+它们并不真正融入内核。可以使它们与其它 IRQ 类似地工作,但在该过程之后,它们不%
+再比``常见'' IRQ 更快。在具有多个处理器的系统上运行的支持 SMP 的内核需要解决一%
+大堆问题。仅仅知道某个 IRQ 是否发生是不够的,了解它是针对哪个 CPU 也很重要。人%
+们仍然对更多细节感兴趣话,现在可能想参考``APIC''。
这个函数接收 IRQ 数字,该函数的名字,标记,为 \verb|/proc/interrupts| 设定的名%
称与一个被传递到中断控制处理程序的参数。通常这里有一定数量的 IRQ 可用。有多少 %
-IRQ 是依赖于硬件的。标记可以包括 \cpp|SA_SHIRQ| 来指示你将与其它中断处理程序(%
-通常是因为许多硬件设备位于同一个 IRQ 上)共享 IRQ,并且 \cpp|SA_INTERRUPT| 来指%
-æ\98\8eè¿\99æ\98¯ä¸\80个快é\80\9f䏿\96ã\80\82ä»\85å½\93æ¤ IRQ ä¸\8aå°\9aæ\97 å¤\84ç\90\86ç¨\8båº\8fæ\88\96å\8f\8cæ\96¹é\83½æ\84¿æ\84\8få\85±äº«æ\97¶ï¼\8cæ¤å\87½æ\95°æ\89\8dä¼\9aæ\88\90å\8a\9fã\80\82
-
+IRQ 是依赖于硬件的。标记可以包括 \cpp|SA_SHIRQ| 来指示你将与其它中断处理程序\,(\,%
+通常是因为许多硬件设备位于同一个 IRQ 上\,)\,共享 IRQ,并且 \cpp|SA_INTERRUPT| %
+æ\9d¥æ\8c\87æ\98\8eè¿\99æ\98¯ä¸\80个快é\80\9f䏿\96ã\80\82ä»\85å½\93æ¤ IRQ ä¸\8aå°\9aæ\97 å¤\84ç\90\86ç¨\8båº\8fæ\88\96å\8f\8cæ\96¹é\83½æ\84¿æ\84\8få\85±äº«æ\97¶ï¼\8cæ¤å\87½æ\95°æ\89\8d%
+会成功。
\section{探测按钮按下}
\label{sec:detect_button}
要使用中断,因此,与其让 CPU 浪费时间和电池电量来轮询输入状态的变化,不如让输入%
触发 CPU 然后运行特定的处理函数。
-这里是一个示例,在这里按钮被连接到 GPIO 数字 17 与 18,并且一个 LED 被连接到 %
-GPIO 4。你可以为你的单板机修改合适的引脚数字。
+这里是一个示例,在这里按钮被连接到 GPIO 编号 17 与 18,并且一个 LED 被连接到 %
+GPIO 编号\,4。你可以根据你的单板机修改合适的引脚编号。
\samplec{examples/intrpt.c}
\section{底半部分}
\label{sec:bottom_half}
-假设你想在中断例程内执行一系列操作。在不使中断长时间不可用的情况下,实现此目的%
-的一种常见方法是将其与一个 tasklet 联系起来。这将大部分工作推入调度程序。
+假设你想在中断例程内执行一系列操作。一种常见的实现方法,且此方法不会因处理任务%
+时间太长,而招致中断不可用时,是采用与一个 tasklet 组合使用来解决问题。这将大%
+部分工作推给调度器例程。
下面的示例修改了前面的示例,以便于在触发中断时也运行附加任务。