如何让ISA设备的驱动程序在PCI设备的Windows驱动程序下运行

时间:2011-05-31

    早的PC总线是IBM公司1981年在PC/XT 电脑采用的系统总线,它基于8bit的8088 处理器,被称为PC总线或者PC/XT总线。在1984年的时候,IBM 推出基于16-bit Intel 80286处理器的PC/AT 电脑,系统总线也相应地扩展为16bit,并被称呼为PC/AT 总线。而为了开发与IBM PC 兼容的外围设备,行业内便逐渐确立了以IBM PC 总线规范为基础的ISA(工业标准架构:Industry Standard Architecture )总线。   

    ISA总线又称AT总线,是在PC/AT微机上所配备的扩展系统总线。ISA 是8/16bit 的系统总线,传输速率仅为8MB/s ,但允许多个CPU 共享系统资源。由于兼容性好,它在上个世纪80年代是广泛采用的系统总线,不过它的弱点也是显而易见的,比如传输速率过低、CPU占用率高、占用硬件中断资源等。后来在PC‘98 规范中,就开始放弃了ISA 总线,而Intel 从i810 芯片组开始,也不再提供对ISA 接口的支持。

  随着科技的高速发展,相比PCI总线,ISA在速度以及功能上以及相形见绌。这时我们只需重新编写ISA设备的驱动程序就可使设备在Windows/Nt操作系统下正常工作。开发的驱动程序是Win32 Drivers Mode(WDM)类型,使用的开发工具是微软提供的Device Driver Kit(DDK)和Vc++6.0,在进行驱动程序的调试时使用Numega公司的SoftIce产品。

    (1)ISA总线与PCI总线的比较

    ISA总线
    ISA总线接口由于I/O速度较慢,随着上世纪90年代初PCI总线技术的出现,很快被淘汰了。目前在市面上基本上看不到有ISA总线类型的网卡。不过近期出现一种复古现象,就是在一些品牌的的i865系列芯片组主板中居然又提供了几条ISA插槽,真是令人费解!
普通的总线是ISA总线,即工业标准结构总线。16位ISA总线频率为8MHz左右。它的应用范围很广,几乎所有的主板都保留了ISA总线的扩展槽。

    PCI总线
    PCI是Intel公司开发的一套局部总线系统,它支持32位或64位的总线宽度,频率通常是33MHz。目前快的PCI2.0总线速度是66MHz。PCI总线允许十个接插件,同时它还支持即插即用。是目前主流的一种接口类型。因为它的I/O速度远比ISA总线型的卡快(ISA仅为33MB/s,而目前的PCI 2.2标准32位的PCI接口数据传输速度可达133MB/s),所以在这种总线技术出现后很快就替代了原来老式的ISA总线。PCI是Intel公司开发的一套局部总线系统,它支持32位或64位的总线宽度,频率通常是33MHz。目前快的PCI2.0总线速度是86MHz。
目前主流的PCI规范有PCI2.0、PCI2.1和PCI2.2三种,PC机上用的32位PCI网卡,三种接口规范的卡外观基本上差不多(主板上的PCI插槽也一样)。服务器上用的64位PCI网卡外观就与32位的有较大差别,主要体现在金手指的长度较长。

  (2)ISA设备和PCI设备的Windows驱动程序的不同点

  ①ISA设备与PCI设备驱动程序获得硬件资源途径不同

  一个ISA设备驱动程序的资源是固定不变的,它是通过。inf文件的[logconfig]节来配置的。如下面的例子:

  [Xxx.LogConfig]

  IOConfig=220-22f

  IRQConfig=6

  .inf中此节说明此硬件资源的I/O地址范围是220H到22FH,IRQ为6。一个PCI设备驱动程序的资源是操作系统自动分配的,它是通过设备ID号和厂商ID号获得设备的物理位置:总线号、器件号和功能号,并利用它们寻址PCI配置空间,接着从配置空间获得硬件资源,其中包括:中断号、端口地址等。

  ②ISA设备与PCI设备驱动程序对中断处理的不同

  一个ISA设备驱动程序的中断模式可以是LevelSensitive也可以是Latched,而且中断向量是否与其它设备共享都可以。但是一个PCI设备驱动程序的中断模式必须是LevelSensitive,而且中断向量必须是共享的。

  ③ISA设备与PCI设备驱动程序安装时需要编写的。inf文件不同

  对于ISA设备,在安装时。inf文件必须有[logconfig]节,而对于PCI设备,在安装时。inf文件必须有[Manufacturer]节,来指明设备ID号和厂商ID号,以便使硬件获取系统资源。如:

  [Manufacturer]

  %PLX% = PLX.Mfg

  [PLX.Mfg]

  "PCI 9052RDK-860 Board" =DDInstall_9052,PCI\VEN_10b5&DEV_9050

  其设备ID号为9050H,厂商ID号为10B5H。

  (三)驱动程序的实现

  通过上面的比较,我们知道只要对原有的ISA设备的驱动程序的获取资源部分作一定的改变,并在安装时对inf文件进行必要的修改就可以完成PCI模式的驱动程序。

  以下示例仅供参考。

  NTSTATUS StartDevice(PDEVICE_OBJECT fdo,

  PCM_PARTIAL_RESOURCE_LIST ResourceListRaw,

  PCM_PARTIAL_RESOURCE_LIST ResourceListTranslated)

  {

  U32 i;

  NTSTATUS status;

  KIRQL irql; // interrupt level

  KINTERRUPT_MODE mode; // interrupt mode

  KAFFINITY affinity; // processor affinity for interrupt

  PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

  PCI_COMMON_CONFIG pciRegs;

  PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceRaw;

  PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceTranslated;

  ResourceRaw = ResourceListRaw->PartialDescriptors;

  ResourceTranslated = ResourceListTranslated->PartialDescriptors;

  // Read PCI Config Register

  PciConfigRegisterBufferRead(

  fdo,

  &pciRegs,

  0,

  sizeof(pciRegs)

  );

  for (i = 0; i < ResourceListTranslated->Count;++i,++ResourceTranslated++ResourceRaw)

  {

  switch (ResourceTranslated->Type)

  {

  case CmResourceTypePort:

  dx->PortStartAddress = ResourceTranslated->u.Port.Start;

  dx->PortLength = ResourceTranslated->u.Port.Length;

  dx->PortNeedsMapping = (ResourceTranslated->Flags&CM_RESOURCE_PORT_IO)==0;

  break;

  case CmResourceTypeInterrupt:

  dx->InterruptIrql = (KIRQL)ResourceTranslated->u.Interrupt.Level;

  dx->InterruptVector = ResourceTranslated->u.Interrupt.Vector; dx->

  InterruptAffinity = ResourceTranslated->u.Interrupt.Affinity;

  dx->InterruptMode = LevelSensitive;

  dx->InterruptConnected = false;

  break;

  case CmResourceTypeNull:

  case CmResourceTypeDma:

  case CmResourceTypeDeviceSpecific:

  case CmResourceTypeBusNumber:

  // NonArbitrated & ConfigData are currently #defined as the same number

  case CmResourceTypeConfigData:

  case CmResourceTypeDevicePrivate:

  case CmResourceTypePcCardConfig:

  case CmResourceTypeMfCardConfig:

  //加入自己的代码

  break;

  default:

  break;

  }

  }

  /* Device has been completely initialized and is ready to run. */

  // Get the Vendor and Device ID

  status = PciConfigRegisterBufferRead(

  fdo,

  &i,

  0,

  sizeof(U32)

  );

  if (!NT_SUCCESS(status))

  {

  dx->Device.VendorId = 0xFFFF;

  dx->Device.DeviceId = 0xFFFF;

  }

  else

  {

  // Record the Vendor and Device ID */

  dx->Device.VendorId = i & 0x0000FFFF;

  dx->Device.DeviceId = i 》 16;

  }

  // Get the bus number and the slot number

  status = GetBusSlotNumber(

  dx->pPhysicalDeviceObject,

  dx

  );

  if (!NT_SUCCESS(status))

  {

  return status;

  }

  return STATUS_SUCCESS;

  }

  共享中断向量只需将IoConnectInterrupt函数的第九个参数值置为TRUE就可以。

  实践证明以上方法是可行的。

  共享中断向量只需将IoConnectInterrupt函数的第九个参数值置为TRUE就可以。

  实践证明以上方法是可行的。




 



  
上一篇:电子工程的嵌入式软件可靠性设计
下一篇:概要设计WBT系统结构

免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

相关技术资料