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

📄 929-931.html

📁 linux-unix130.linux.and.unix.ebooks130 linux and unix ebookslinuxLearning Linux - Collection of 12 E
💻 HTML
字号:
<HTML>

<HEAD>

<TITLE>Linux Unleashed, Third Edition:Writing Device Drivers</TITLE>

<SCRIPT>
<!--
function displayWindow(url, width, height) {
        var Win = window.open(url,"displayWindow",'width=' + width +
',height=' + height + ',resizable=1,scrollbars=yes');
}
//-->
</SCRIPT>
</HEAD>

 -->




<!--ISBN=0672313723//-->

<!--TITLE=Linux Unleashed, Third Edition//-->

<!--AUTHOR=Tim Parker//-->

<!--PUBLISHER=Macmillan Computer Publishing//-->

<!--IMPRINT=Sams//-->

<!--CHAPTER=58//-->

<!--PAGES=929-931//-->

<!--UNASSIGNED1//-->

<!--UNASSIGNED2//-->



<CENTER>

<TABLE BORDER>

<TR>

<TD><A HREF="927-929.html">Previous</A></TD>

<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>

<TD><A HREF="931-935.html">Next</A></TD>

</TR>

</TABLE>

</CENTER>

<P><BR></P>

<H3><A NAME="Heading3"></A><FONT COLOR="#000077">Interrupts</FONT></H3>

<P><I>Interrupts</I> are signals from the devices to the operating system to indicate that attention is required. Interrupts are generated whenever an I/O is processed and the device is ready for another process. The interrupts used by Linux are similar to those used by DOS, so if you are familiar with DOS interrupts, you know most of the story already.</P>

<P>Upon receipt of an interrupt, the operating system suspends whatever it is executing and processes the interrupt. In most cases, interrupts are handled by the device driver. Interrupts must be checked to ensure that they are valid and do not affect operation of a process underway, except to suspend it momentarily.</P>

<P>A problem with handling interrupts is that the interrupt should not suspend the Linux kernel&#146;s operation or that of the device drivers themselves, except under controlled conditions. Interrupts that are not properly handled or carefully checked can cause suspension of a device driver that was processing the I/O that the interrupt requested.</P>

<P>The processing of an interrupt is usually suspended during the stages when critical operation would be affected. The areas of device driver code that should not allow an interrupt to stop their processing are termed <I>non-stoppable</I> or <I>critical</I> code. Typically, interrupt suspension during critical code segments is performed by raising the CPU priority equal to or greater than the interrupt priority level. After critical code execution, the CPU priority level is lowered again.</P>

<P>Interrupt priority is usually manipulated with four functions: <TT>spl5()</TT>, <TT>spl6()</TT>, <TT>spl7()</TT>, and <TT>splx()</TT>. Calling one of the first three causes interrupts <I>not</I> to be acknowledged during processing. <TT>spl5()</TT> disables disk drives, printer, and keyboard interrupts. <TT>spl6()</TT> disables the system clock, while <TT>spl7()</TT> disables all interrupts, including serial devices. These three functions always return a code indicating the previous value of the interrupt level. <TT>splx()</TT> is used to restore interrupts to their previous values.</P>

<P>Therefore, before processing critical code, embedding the command</P>

<!-- CODE SNIP //-->

<PRE>

old_level = spl5();

</PRE>

<!-- END CODE SNIP //-->

<P>in the device driver source disables interrupts until the following command is issued:

</P>

<!-- CODE SNIP //-->

<PRE>

splx(old_level);

</PRE>

<!-- END CODE SNIP //-->

<P>Multiple level changes are combined into device drivers as in the following example:

</P>

<!-- CODE //-->

<PRE>

int level_a, level_b;

level_a = spl5();

/* do any code that can&#146;t be */

/* interrupted by disk drives */

level_b = spl7();

/* do all code that can&#146;t be */

/* interrupted by anything  */

splx(level_b);

/* any final code that&#146;s not */

/* interrupted by disk drives */

splx(level_a);

</PRE>

<!-- END CODE //-->

<P>This seemingly awkward method of bouncing between levels is necessary to avoid freezing the device driver and kernel, which prevents the system from operating normally. The protection mechanisms must be invoked only for as short a time as necessary.

</P>

<P>It is usually unwise to use the <TT>spl6()</TT> and <TT>spl7()</TT> functions. <TT>spl6()</TT> can cause the system clock to lose time in some cases, and <TT>spl7()</TT> causes loss of characters in serial I/O, unless it is used for very short time spans. Even then, it is usually sufficient to use <TT>spl5()</TT> for all interrupts in critical code.</P>

<H3><A NAME="Heading4"></A><FONT COLOR="#000077">Anatomy of a Linux Device Driver</FONT></H3>

<P>Device driver code is similar to normal code in its structure. In Linux, drivers are generally written in C, although assembler and C&#43;&#43; are still occasionally used.

</P>

<H4 ALIGN="LEFT"><A NAME="Heading5"></A><FONT COLOR="#000077">Headers</FONT></H4>

<P>A typical device driver has a header that consists of <TT>include</TT> statements for system functions, device register addresses, content definitions, and driver global variable definitions. Most device drivers use a standard list of <TT>include</TT> files, such as:</P>

<CENTER>

<TABLE WIDTH="90%"><TR>

<TD WIDTH="30%" ALIGN="LEFT"><TT>param.h</TT>

<TD WIDTH="70%" ALIGN="LEFT">Kernel parameters

<TR>

<TD><TT>dir.h</TT>

<TD>Directory parameters

<TR>

<TD><TT>user.h</TT>

<TD>User area definitions

<TR>

<TD><TT>tty.h</TT>

<TD>Terminal and <TT>clist</TT> definitions

<TR>

<TD><TT>buf.h</TT>

<TD>Buffer header information

</TABLE>

</CENTER>

<P>The <TT>tty.h</TT> file is used for character mode drivers, while <TT>buf.h</TT> is used by all block mode devices.</P>

<P>Device registers are defined in the device driver header and are based on the device. For a character mode device, these registers commonly refer to port addresses, such as I/O address, status bits, and control bits. Toggle commands for the device are defined as their device codes.</P><P><BR></P>

<CENTER>

<TABLE BORDER>

<TR>

<TD><A HREF="927-929.html">Previous</A></TD>

<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>

<TD><A HREF="931-935.html">Next</A></TD>

</TR>

</TABLE>

</CENTER>





</td>
</tr>
</table>

<!-- begin footer information -->





</body></html>

⌨️ 快捷键说明

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