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

📄 linux设备驱动程序学习(9)-与硬件通信 - linux设备驱动程序 - tekkaman ninja.htm

📁 Linux设备驱动程序学习(9)-与硬件通信 - Linux设备驱动程序 .rar
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                              端口</STRONG></FONT></P>
                              <P>在驱动程序注册I/O 
                              端口后,就可以读/写这些端口。大部分硬件会把8、16和32位端口区分开,不能像访问系统内存那样混淆使用。驱动必须调用不同的函数来存取不同大小的端口。</P>
                              <P>只支持内存映射的 I/O 
                              寄存器的计算机体系通过重新映射I/O端口到内存地址来伪装端口I/O。为了提高移植性,内核向驱动隐藏了这些细节。Linux 
                              内核头文件(体系依赖的头文件 <FONT 
                              color=#0000ff>&lt;asm/io.h&gt;</FONT> ) 
                              定义了下列内联函数(有的体系是宏,有的不存在)来访问 I/O 端口:</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"><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> inb<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #0000ff">void</SPAN> outb<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">char</SPAN> byte<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #ff9900">/*读/写字节端口( 8 位宽 )。port 
                                参数某些平台定义为 unsigned long ,有些为 unsigned short 。 
                                inb 的返回类型也体系而不同。*/</SPAN><BR><BR><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> inw<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #0000ff">void</SPAN> outw<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">short</SPAN> word<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #ff9900">/*访问 16位 端口( 一个字宽 
                                )*/</SPAN><BR><BR><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> inl<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #0000ff">void</SPAN> outl<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> 
                                longword<SPAN style="COLOR: #0000cc">,</SPAN> 
                                <SPAN style="COLOR: #0000ff">unsigned</SPAN> 
                                port<SPAN style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #ff9900">/*访问 32位 端口。 longword 
                                声明有的平台为 unsigned long ,有的为 unsigned 
                                int。*/</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE>
                              <P><STRONG><FONT color=#0000ff size=3>在用户空间访问 I/O 
                              端口</FONT></STRONG></P>
                              <P>以上函数主要提供给设备驱动使用,但它们也可在用户空间使用,至少在 PC上可以。 GNU C 
                              库在 &lt;sys/io.h&gt; 
                              中定义了它们。如果在用户空间代码中使用必须满足以下条件:</P>
                              <P>(1)程序必须使用 -O 选项编译来强制扩展内联函数。</P>
                              <P>(2)必须用ioperm 和 iopl 系统调用<FONT 
                              color=#660099>(#include &lt;sys/perm.h&gt;)</FONT> 
                              来获得对端口 I/O 操作的权限。ioperm 为获取单独端口操作权限,而 iopl 为整个 I/O 
                              空间的操作权限。<FONT color=#660099> (x86 特有的)</FONT></P>
                              <P>(3)程序以 root 来调用 ioperm&nbsp;和 iopl,或是其父进程必须以 
                              root 获得端口操作权限。<FONT color=#660099>(x86 
                              特有的)</FONT></P>
                              <P><FONT color=#0000ff>若平台没有 ioperm 和 iopl 
                              系统调用,用户空间可以仍然通过使用 /dev/prot 设备文件访问 I/O 
                              端口。注意:这个文件的定义是体系相关的,并且I/O 端口必须先被注册。</FONT></P>
                              <P><FONT color=#0000ff 
                              size=3><STRONG>串操作</STRONG></FONT></P>
                              <P>除了一次传输一个数据的I/O操作,一些处理器实现了一次传输一个数据序列的特殊指令,序列中的数据单位可以是字节、字或双字,这是所谓的串操作指令。它们完成任务比一个 
                              C 语言循环更快。下列宏定义实现了串I/O,它们有的通过单个机器指令实现;但如果目标处理器没有进行串 
                              I/O 的指令,则通过执行一个紧凑的循环实现。 有的体系的原型如下:</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"><SPAN 
                                style="COLOR: #0000ff">void</SPAN> insb<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">void</SPAN> <SPAN 
                                style="COLOR: #0000cc">*</SPAN>addr<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">long</SPAN> <SPAN 
                                style="COLOR: #ff0000">count</SPAN><SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #0000ff">void</SPAN> outsb<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">void</SPAN> <SPAN 
                                style="COLOR: #0000cc">*</SPAN>addr<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">long</SPAN> <SPAN 
                                style="COLOR: #ff0000">count</SPAN><SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><BR><SPAN 
                                style="COLOR: #0000ff">void</SPAN> insw<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">void</SPAN> <SPAN 
                                style="COLOR: #0000cc">*</SPAN>addr<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">long</SPAN> <SPAN 
                                style="COLOR: #ff0000">count</SPAN><SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #0000ff">void</SPAN> outsw<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">void</SPAN> <SPAN 
                                style="COLOR: #0000cc">*</SPAN>addr<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">long</SPAN> <SPAN 
                                style="COLOR: #ff0000">count</SPAN><SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><BR><SPAN 
                                style="COLOR: #0000ff">void</SPAN> insl<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">void</SPAN> <SPAN 
                                style="COLOR: #0000cc">*</SPAN>addr<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">long</SPAN> <SPAN 
                                style="COLOR: #ff0000">count</SPAN><SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> <BR><SPAN 
                                style="COLOR: #0000ff">void</SPAN> outsl<SPAN 
                                style="COLOR: #0000cc">(</SPAN><SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> port<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">void</SPAN> <SPAN 
                                style="COLOR: #0000cc">*</SPAN>addr<SPAN 
                                style="COLOR: #0000cc">,</SPAN> <SPAN 
                                style="COLOR: #0000ff">unsigned</SPAN> <SPAN 
                                style="COLOR: #0000ff">long</SPAN> <SPAN 
                                style="COLOR: #ff0000">count</SPAN><SPAN 
                                style="COLOR: #0000cc">)</SPAN><SPAN 
                                style="COLOR: #0000cc">;</SPAN> 
                                </SPAN></CODE></P></TD></TR></TBODY></TABLE>
                              <P>使用时注意: 
                              它们直接将字节流从端口中读取或写入。当端口和主机系统有不同的字节序时,会导致不可预期的结果。 使用 
                              inw 读取端口应在必要时自行转换字节序,以匹配主机字节序。</P>
                              <P><FONT color=#0000ff 
                              size=3><STRONG>暂停式&nbsp;I/O</STRONG></FONT></P>
                              <P><FONT color=#000000>为了匹配低速外设的速度,有时若 I/O 
                              指令后面还紧跟着另一个类似的I/O指令,就必须在 I/O 
                              指令后面插入一个小延时。</FONT><FONT 
                              color=#000000>在这种情况下,可以使用暂停式的I/O函数代替通常的I/O函数,它们的名字以 
                              _p 结尾,如 inb_p、outb_p等等。 
                              这些函数定义被大部分体系支持,尽管它们常常被扩展为与非暂停式I/O 
                              同样的代码。因为如果体系使用一个合理的现代外设总线,就没有必要额外暂停。细节可参考平台的 asm 
                              子目录的 io.h 
                              文件。以下是include\asm-arm\io.h中的宏定义:</P></FONT>
                              <TABLE st

⌨️ 快捷键说明

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