摘要:本文首要针对现已研发好的ISA设备经过加上一个简略的PCI接口芯片便能正常作业在PCI形式下,完结由ISA扩展板到PCI扩展板的转化。这时咱们有必要从头编写设备的驱动程序才能使设备在Windows/Nt操作体系下正常作业。这儿首要给出Windows下的解决方案和程序实例。
关键词:ISA设备驱动程序 PCI设备驱动程序 IRQ PCI装备空间
跟着计算机和通讯技能的高速开展,ISA总线在速度、功用上现已成为体系的瓶颈,而功用更强壮的PCI总线成为首选。这时对现有的ISA设备稍加规划就可在PCI总线下作业就显得十分总要,但咱们有必要从头编写设备的驱动程序才能使设备在Windows/Nt操作体系下正常作业。
开发的驱动程序是Win32 Drivers Mode(WDM)类型,运用的开发工具是微软供给的Device Driver Kit(DDK)和Vc++6.0,在进行驱动程序的调试时运用Numega公司的SoftIce产品。
1 .ISA设备与PCI设备的Windows驱动程序的比较
(1).ISA设备与PCI设备驱动程序取得硬件资源途径不同
一个ISA设备驱动程序的资源是固定不变的,它是经过.inf文件的[logconfig]节来装备的。如下面的比如:
[Xxx.LogConfig]
IOConfig=220-22f
IRQConfig=6
.inf中此节阐明此硬件资源的I/O地址规模是220H到22FH,IRQ为6。
一个PCI设备驱动程序的资源是操作体系主动分配的,它是经过设备ID号和厂商ID号取得设备的物理方位:总线号、器材号和功用号,并使用它们寻址PCI装备空间,接着从装备空间取得硬件资源。其间包含:中止号、端口地址等。
(2).ISA设备与PCI设备驱动程序对中止处理不同
一个ISA设备驱动程序的中止形式可所以LevelSensitive也可所以Latched,并且中止向量是否与其它设备同享都可以。
可是一个PCI设备驱动程序的中止形式有必要是LevelSensitive,并且中止向量有必要是同享的。
(3).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_10b5DEV_9050
其设备ID号为9050H,厂商ID号为10B5H。
2 驱动程序的完结
经过上面的比较,咱们知道只要对原有的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->FlagsCM_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就可以。
实践证明以上办法是可行的。