| | | | | | | [文章信息] | | | 作者: | 翟洪涛授权 | | 时间: | 2004-02-26 | | 出处: | yesky | | 责任编辑: | 方舟 | |
| [文章导读] | | | 本文接上一章讲述了Windows 2000驱动程序设计所涉及的硬件基础 | |
| |
|
| | | |
|
|
|
|
|
天极IT资讯短信服务 电脑小技巧
|
介绍:细处着手,巧处用功。高手和菜鸟之间的差别就是:高手什么都知道,菜鸟知道一些。电脑小技巧收集最新奇招高招,让你轻松踏上高手之路。 | |
驱动程序必须和硬件相结合是无可争辩的事实,传统的,硬件设计者编写的测试代码是第一代的驱动程序,这些早期的驱动程序然后传递给硬件机制的软件工程师去开发全功能的驱动程序。
迟早,驱动程序开发工程师必须理解硬件和足够的术语,这一章概述一下大多数系统的硬件基础。
硬件基础
无论开发怎样的驱动程序,都必须清楚以下几点:
1. 怎样使用驱动程序的状态和控制寄存器?
2. 怎样使驱动程序产生一个中断?
3. 驱动程序怎样传输数据?
4. 是否驱动程序使用专用的存储器?
5. 怎样驱动程序宣布它的存在?
6. 驱动程序怎样通过软件进行配置?
下面将依次介绍。
设备寄存器
驱动程序通过读写和外设相关联的寄存器来和外设通讯。一般的,每个设备寄存器执行一个如下功能:
1. 命令: 仅占了几位去控制设备,如: 开始和结束一个数据的转换或者配置设备和简单的写。
2. 状态: 驱动程序去读这些寄存器来得到当前设备的状态。
3. 数据: 3. 数据: 这些寄存器被用来转换驱动程序与设备之间的数据。驱动程序写输出数据寄存器,读输入数据寄存器。
简单的设备仅有很少的相关联的寄存器,复杂的设备(如: 显示适配器)就会有很多的寄存器。寄存器的数量和用途最终被硬件设计者定义,生成硬件设计说明书。一般的,经验告诉我们那些保留的位不是不必关心的位,当读的时候要掩盖它们,写的时候要强制为零。
访问设备寄存器
在知道了硬件函数之后,还必须知道如下信息:
1. 设备的第一个寄存器地址。
2. 寄存器的相对地址。
通常情况下设备寄存器占用连续的地址空间。因此,访问其它的寄存器的时候必须知道第一个寄存器地址。不幸的,在不同的平台上,一个虚拟地址空间有不同的意义,因此,详细的讨论放到了第八章。一般的,CPU访问设备寄存器使用以下方法(如图2.1)的其中之一:
1. 使用CPU的特殊I/O指令。
2. 使用标准的存储器指令。
 图2.1 CPU访问I/O与存储器
地址空间编址方式
I/O地址空间与存储器空间的地址空间进行统一编址,这样读写指令相同,减少了指令数目,也就减少了CPU指令的长度,缺点是占用了存储器空间。
I/O地址空间与存储器空间的地址空间进行分开编址,读写指令采用特殊指令,如IN,OUT,虽然增加了CPU指令的长度,但是I/O地址空间是与存储器空间分离,不会占用存储器空间。
I/O空间寄存器
一些CPU的结构(尤其是80X86,采用分开编址模式)访问设备寄存器使用I/O机器指令,这些特殊的指令引起CPU针脚的特殊脉冲波形,因此I/O设备需要一个特殊的总线和地址空间,这些总线上的地址叫做端口,它是完全和内存空间分离的。在80X86结构中,I/O地址空间占16Bits,可寻址空间为64KB,汇编语言定义了读指令为IN,写指令为OUT。
当然,如第一章所述,驱动程序代码应具有设备无关性,因此IN与OUT指令应避免使用。代替的是使用一些HAL的宏,如表2.1所示。
 表2.1 访问I/O端口的HAL宏
存储器映像寄存器
不是所有的CPU的结构使用分开的I/O地址空间(统一编址)。同样的,可以设计硬件设备寄存器地址接口在存储器空间,甚至CPU支持分开的I/O地址空间。在一些情况下,设备(例如: 显示适配器)会接触这两种地址空间。
设备通常在存储器空间中暴露出大量的数据缓冲区,这样可以使用高级语言(例如: C)快速和方便的访问它们,HAL提供了一些宏去访问存储器映像的设备寄存器,罗列在表2.2中,因为这些宏与I/O地址空间宏是不同的,所以一个设备必须支持两种不同的平台。
 表2.2 访问存储器映像的设备寄存器的HAL宏
设备中断
因为设备执行硬件操作与CPU操作是异步的,所以设备发出一个中断信号给CPU是必须的。不同的CPU的中断机制是不同的,但是,当设备需要请求中断服务的时候,总是设备发送信号给CPU的一个或者几个针脚,在跳到执行设备驱动程序的中断服务程序之前,CPU存储现在的CPU状态和上下文。
设备在以下情况下产生中断:
1. 完成了一个操作,准备好另外一个操作的时候。
2. 当设备的缓冲区或者先进先出将要空(输出时)或者将要满(输入时)时。这些中断让驱动程序去重新填充设备的缓冲区,或者清空设备的缓冲区去保证设备操作不会暂停。
3. 设备执行操作时遭遇到一个错误的时候。
不产生中断的设备将严重的降低系统的执行性能,因为在WIN2000中,CPU分配时间给系统中正在运行线程,不允许设备占用宝贵的消息循环去等待一个设备完成操作。以后的章节会介绍一些用于没有中断的设备的技术。
中断优先权
可能好几个设备在同一时刻申请中断,这时就需要一个机制去决定那一个设备首先接受服务。应该给最重要的设备或者必须分配最小的等待时间的设备分配最大的优先权,如果一个设备可以等待,就分配一个第一点的优先权,一个配置选项分配优先权给设备。这个优先权可以在设备初始化时由软件设定。
当一个低优先权的设备中断时,高优先权的设备还可以中断,在这种情况下,CPU有两个中断,且第二个中断的优先权高于第一个。相反的,高优先权的中断正在接受中断服务时,这时请求的低优先权中断被拖延,直到高优先权的中断服务完成和销毁。
中断向量
一些设备或者CPU结构允许中断自动的调用软件定义的函数作为中断的服务。必须提供一个公用的中断服务给所有的中断,这个公用的中断服务程序根据中断设备从一个中断设备表中选择一个真正的中断服务程序,因为系统每秒产生上百个中断,所以这种中断向量非常有效率.
中断信号发送机制
当设备产生中断时有两个基本的策略,它们是下降边沿触发和锁闭中断。产生下降边沿触发中断的设备通过在硬件线路上产生1到0的跳变来发出它们需要服务的信号,一旦跳变发出,设备可能释放这条硬件线路,恢复逻辑1状态。换句话说,设备产生一个脉冲,CPU的责任是感知这个脉冲。
锁闭中断屏蔽掉虚假的中断,因为中断线路的噪声有时像一个中断脉冲,更糟的是,两个设备尝试同时共享一条中断线路,这时CPU认为只有一个设备产生了中断,这样这两个设备需要的服务将永远丢失。
丢失中断的典型的例子是老式的串行口,传统的,COM1与COM3共享一个X86中断,IR04。结果,两个端口不能同时用作中断驱动的程序。如果尝试在COM1使用鼠标,在COM3口使用MODEM,会常常导致鼠标或者MODEM无反应,它们时常等待中断产生。
在电压触发的信号机制中不会产生这种情况,设备将保持中断线路一定的电压水平直到它的服务开始,CPU可以在任何时候侦测中断信号,因此,两个或者更多的设备可以共享一个中断,当多个中断同时产生,较高的中断优先权的设备得到服务,其它的设备继续保持电压水平直到得到服务。
|
|
|
|
|
|
|
|