PCI 设备的许多参数,包括所用的中断号、端口地址的范围、l/O 方式、存储器的地址、存储器映射方式等,都可以从PCI 配置空间的各基址所对应的寻址空间中得到。读写配置空间可以调用BIOS 中断lAH ,也可以先向配置空间地址寄存器写入总线和设备号,在前面搜索PCI 器件时得到的寄存器号,再对配置空间数据寄存器进行读写。对设备驱动来说,最重要的是获得基址寄存器。不能认为PCI 器件资源总是设计设备时设置的初值,系统可能会根据硬件情况为PCI 设备分配新的资源。用C 语言描述如下
在WindowsNTj2000jXP 中,应用程序与驱动程序间的通信通过调用Win32 API 实现,应用程序用CreatFileC) 通过巳经定义的设备接口获取驱动程序的文件句柄,然后将文件句柄作为其他Win32 API 函数的一个参数,对驱动程序进行数据操作,应用程序可以通过API 函数DeviceloControl 来实现对设备的访问,获取信息,发送命令,交换数据等。在应用程序中,加入以下函数,即可实现访问驱动程序所定义的缓冲区的操作,从而实现了驱动程序与应用程序的通信问题。
HANOLE hOevice;
hDevice = CreateFile ("\ \ \ \. \ \Onepci" ,GENERIC_REAO I GENERIC_ WRITE ,
FIL E_ SHARE_REAO I FIL E_ SHARE_ WRITE , NULL , OPEN_EXIST2ING,
FIL E_ ATTRIBUTENORMAL,NULL) ;
//获得驱动程序的句柄;
ULONG Test_ONEPCLIOCTL_806(ULONG sel)
KS_MAILBOX_MESSAG E message;
message. MessageMailBox = 0;
message. MessageValue = sel;
ULONG nOutput; / / Count written to bufOutput
if (! OeviceloControl(hOevice , / /设备句柄
ONEPCI_IOCTL_806 , / /应用程序调用驱动程序的控制命令
&message , / /应用程序传递给驱动程序数据缓冲区指针
sizeof(message) , / /应用程序传递给驱动程序数据字节数
&message , / /驱动程序返回数据的缓冲区指针
sizeof(message) , / /驱动程序返回数据的缓冲区字节数
&nOutput,
NULL) )
printf( "ERROR: OeviceloControl returns %Ox. ", GetLastErrorO);
Exìt(1); }
return message. MessageValue; / /返回输出缓冲区中的数据
3 结语
设备驱动程序的开发与通常的应用程序开发有很大的不同,由于驱动程序直接访问硬件资源,它在调试开发过程中的错误常会导致系统死机,出现蓝屏。因此,驱动程序的调试需要专门的软件,不能直接使用VC 的编译环境,最好给系统备份,以免每次重装系统。NuMega 公司的Softice 是一个理想的调试工具。
使用OriverWorks 可以快速产生一个驱动程序,然后只需在里面作一些小的改动就可以使用了。因此利用OriverWorks 开发PCI 设备驱动程序可以大大缩短开发周期,提高开发效率,是开发PCI 硬件设备驱动程序的良好工具。
文中编写的Onepci 驱动程序应用于PCI 数据采集卡,能够实现驱动程序的安装,并与应用程序通信,实现了实时要求及所要求的接口,驱动程序运行良好,实现了预期设想的目标。