• <ins id='9zf3'></ins>

          <i id='9zf3'><div id='9zf3'><ins id='9zf3'></ins></div></i>

          <span id='9zf3'></span>

          <code id='9zf3'><strong id='9zf3'></strong></code>
        1. <tr id='9zf3'><strong id='9zf3'></strong><small id='9zf3'></small><button id='9zf3'></button><li id='9zf3'><noscript id='9zf3'><big id='9zf3'></big><dt id='9zf3'></dt></noscript></li></tr><ol id='9zf3'><table id='9zf3'><blockquote id='9zf3'><tbody id='9zf3'></tbody></blockquote></table></ol><u id='9zf3'></u><kbd id='9zf3'><kbd id='9zf3'></kbd></kbd>
        2. <fieldset id='9zf3'></fieldset>

          <i id='9zf3'></i>

            <acronym id='9zf3'><em id='9zf3'></em><td id='9zf3'><div id='9zf3'></div></td></acronym><address id='9zf3'><big id='9zf3'><big id='9zf3'></big><legend id='9zf3'></legend></big></address>
            <dl id='9zf3'></dl>

          1. Linux设备驱动程序--与硬件通信

            • 时间:
            • 浏览:2
            • 来源:124软件资讯网

              I/O 端口和 I/O 内存

                每种外设都是通过读写寄存器来举行控制  。

                在硬件层  ,内存区和 I/O 区域没有观点上的区别: 它们都是通过向在地址总线和控制总线发出电平信号来举行会见  ,再通过数据总线读写数据  。

                由于外设要与I\O总线匹配 ,而大部门盛行的 I/O 总线是基于小我私家盘算机模子(主要是 x86 家族:它为读和写 I/O 端口提供了自力的线路和特殊的 CPU 指令)  ,以是即便那些没有单独I/O 端口地址空间的处置惩罚器  ,在会见外设时也要模拟成读写I\O端口  。这一功效通常由外围芯片组(PC 中的南北桥)或 CPU 中的附加电路实现(嵌入式中的要领)  。

                Linux 在所有的盘算机平台上实现了 I/O 端口  。但不是所有的装备都将寄存器映射到

                I/O 端口 。虽然ISA装备普遍使用 I/O 端口  ,但大部门 PCI 装备则把寄存器映射到某个内存地址区  ,这种 I/O

                内存要领通常是首选的  。由于它无需使用特殊的处置惩罚器指令  ,CPU

                核会见内存更有用率 ,且编译器在会见内存时在寄存器分配和寻址模式的选择上有更多自由  。

                I/O 寄存器和通例内存

                在进入这部门学习的时间  ,首先要明白一个观点:side

                effect  ,书中译为边际效应 ,第二版译为副作用 。我以为不管它是怎么被翻译的  ,都不行能精准表达原作者的意思 ,以是我小我私家以为记着side

                effect就好  。下面来讲讲side effect的寄义  。我先贴出两个网上已有的两种说法(在这里谢谢两位高人的分享):

                第一种说法:

                3. side effect(译为边际效应或副作用):是指读取某个地址时可能导致该地址内容发生转变 ,好比  ,有些装备的中止状态寄存器只要一读取  ,便自动清零  。I/O寄存器的操作具有side effect ,因此  ,不能对其操作不能使用cpu缓存 。

                原文网址:

                http://qinbh.blog.sohu.com/62733495.html

                第二种说法:

                说一下我的明白:I/O端口与现实外部装备相关联  ,通过会见I/O端口控制外部装备  ,“边际效应”是指控制装备(读取或写入)生效 ,会见I/O口的

                主要目的就是边际效应  ,不像会见通俗的内存  ,只是在一个位置存储或读取一个数值 ,没有此外寄义了 。我是基于arm平台明白的  ,在《linux装备驱动程

                序》第二版中的说法是“副作用” ,不是“边际效应”  。

                原文网址:

                http://linux.chinaunix.net/bbs/viewthread.php?tid=890636&page=1#pid6312646

                联合以上两种说法和自己看《Linux装备驱动法式(第3版)》的明白  ,我小我私家以为可以这样诠释:

                side effect

                是指:会见I/O寄存器时  ,不仅仅会像会见通俗内存一样影响存储单元的值 ,更主要的是它可能改变CPU的I/O端口电平、输出时序或CPU对I/O端口电

                平的反映等等  ,从而实现CPU的控制功效  。CPU在电路中的意义就是实现其side effect  。

                I/O 寄存器和 RAM 的主要差别就是 I/O 寄存器操作有side effect, 而内存操作没有  。

                由于存储单元的会见速率对 CPU 性能至关主要  ,编译器会对源代码举行优化  ,主要是: 使用高速缓存生存数值 和 重新编排读/写指令顺序  。但对I/O 寄存器操作来说  ,这些优化可能造成致命错误 。因此  ,驱动法式必须确保在操作I/O 寄存器时  ,不使用高速缓存 ,且不能重新编排读/写指令顺序  。

                解决要领:

                硬件缓存问题:只要把底层硬件设置(自动地或者通过 Linux 初始化代码)成当会见 I/O 区域时(不管内存照旧端口)克制硬件缓存即可  。

                硬件指令重新排序问题:在硬件(或其他处置惩罚器)必须以一个特定顺序执行的操作之间设置内存屏障(memory barrier)  。

                Linux 提供以下宏来解决所有可能的排序问题:

                #include linux/kernel.h>

                void barrier(void)

                #include linux/compiler.h>

                # define barrier() __memory_barrier()

                #include asm/system.h>

                void rmb(void);

                void wmb(void);

                void mb(void);

                void read_barrier_depends(void);

                

                void smp_rmb(void);

                void smp_read_barrier_depends(void);

                void smp_wmb(void);

                void smp_mb(void);

                

                典型的应用:

                writel(dev->registers.addr, io_destination_address);

                writel(123456下一页