分类:
2010-03-19 13:42:06
驱动程序是为设备的硬件层编程服务的,但同样需要提供和应用程序进行通信的能力,从而最终达到应用程序控制设备的目的。本文主要讨
论应用程序与驱动程序的通信和驱动程序与应用程序的通信。
在Windows中,应用程序实现与WDM通信的过程是:应用程序先用CreateFile函数打开设备,然后用DeviceIoControl和
WDM进行通信,包括从WDM读数据和写数据给WDM两种情况,也可用ReadFile从WDM中读数据或用WriteFile写数据给WDM。当应用程
序退出时,用CloseHandle关闭设备。
以下是用DeviceIoControl写数据给WDM的源代码:
void Test_P9052_IOCTL_805_WriteBase3(void)以下是用DeviceIoControl从WDM中读数据的源代码:
{
ULONG nOutput; // Count written to bufOutput
// 传给驱动程序要写入的参数和数据
// 数组的第一个元素为写入的偏移地址,第二个元素为数据的个数,其它元素为写入的数据
ULONG bufInput[IOCTL_INBUF_SIZE+2];
ULONG offset; // 写入的偏移地址
ULONG num; // 写入的初始数据,以此来产生一个数组
printf("\n----------- ready for writing to Base3 -----------");
//获取写入的偏移地址
printf("\nPlease input the offset of the write operation(Hex):");
scanf("%x",&offset);
// //获取写入的数据个数
bufInput[0]=offset;
bufInput[1]=IOCTL_INBUF_SIZE;
//获取写入的数据
printf("\nPlease input the initial data to write(Hex):");
scanf("%x",&num);
for(ULONG j=0;j{
bufInput[2+j]=num;
num+=0x0;
}
//显示生成的数组
for(ULONG i=0;i{
printf("\nwrite data[%d]=%x",i,bufInput[i]);
}
// Call device IO Control interface in driver
if (!DeviceIoControl(hDevice,
P9052_IOCTL_805_WriteBase3,
bufInput,
(IOCTL_INBUF_SIZE+2)*4,//sizeof(bufInput),
NULL,//bufOutput,
0,//sizeof(bufOutput),
&nOutput,
NULL)
)
{
printf("\nERROR: DeviceIoControl returns %0x.", GetLastError());
Exit(1);
}
printf("\n\n");
}
void Test_P9052_IOCTL_804_ReadBase3(void)
{
ULONG bufOutput[IOCTL_OUTBUF_SIZE]; // 传出读取的数据缓冲区
ULONG nOutput; // 实际读取的数据个数
ULONG bufInput[2]; // 传入读取的参数
ULONG offset; // 要读取的偏移地址
printf("\n----------- ready for reading from Base3 -----------");
//获取读取的偏移地址:
printf("\nPlease input the offset of read operation(Hex):");
scanf("%x",&offset);
// //获取读取的数据个数:
// printf("\nPlease input the number of data to read(Dec):");
// scanf("%d",&number);
bufInput[0]=offset;
bufInput[1]=IOCTL_OUTBUF_SIZE;
// Call device IO Control interface (PCI9054_IOCTL_804_ReadBase3) in driver
if (!DeviceIoControl(hDevice,
P9052_IOCTL_804_ReadBase3,
bufInput,
2*4, // 字节
bufOutput,
IOCTL_OUTBUF_SIZE*4,//sizeof(bufOutput),
&nOutput,
NULL)
)
{
printf("\nERROR: DeviceIoControl returns %0x.", GetLastError());
Exit(1);
}
printf("\n------>>>>>> data read <<<<<<------");
for(ULONG i=0;i{
printf("\nread data[%d]=%x",i,bufOutput[i]);
}
printf("\n\n");
}
VOID P9052Device::Serial_P9052_IOCTL_804_ReadBase3_Handler(KIrp I)下图是运行时的界面:
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering P9052Device::Serial_P9052_IOCTL_804_ReadBase3_Handler, " << I << EOL;
KMemory Mem(I.Mdl());
// Use the memory object to create a pointer to the caller''s buffer
PULONG pOutBuffer = (PULONG) Mem.MapToSystemSpace(); //输出缓冲区指针,传出读取的数据
PULONG pInBuffer = (PULONG) I.IoctlBuffer(); //输入缓冲区指针
ULONG Offset; //读取的偏移地址
Offset = *pInBuffer;
ULONG count; //读取的数据个数
count = *(pInBuffer+1);
m_IoPortRange1_ForBase3.ind(Offset,pOutBuffer,count);
I.Information() = count;
I.Status() = status;
m_DriverManagedQueue.PnpNextIrp(I);
}
以下是通过IRP,驱动程序的写数据函数:
VOID P9052Device::Serial_P9052_IOCTL_805_WriteBase3_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering P9052Device::Serial_P9052_IOCTL_805_WriteBase3_Handler, " << I << EOL;
PULONG pInBuffer = (PULONG) I.IoctlBuffer(); //输入缓冲区指针
ULONG count; //从输入缓冲区要写入的数据个数
count=*(pInBuffer+1);
ULONG offset; //偏移地址
offset=*pInBuffer;
PULONG pBuffer = pInBuffer+2; //指向要写入的数据
m_IoPortRange1_ForBase3.outd(offset,pBuffer,count);
I.Information() = count;
I.Status() = status;
m_DriverManagedQueue.PnpNextIrp(I);
}
|
|||
|
chulia200020012010-04-17 03:24:49
获得设备路径问题 http://topic.csdn.net/u/20080108/14/8aef6a6f-e770-43d7-a941-282a2c400192.html
chulia200020012010-04-17 02:22:28
标题: 获取系统可用串口个数及串口名称 http://m.cnblogs.com/48109/1542828.html - ccjvl 2009-08-10 13:35 阅读:274 - 评论:0 | 添加评论 | 返回 ↓ 在 c#中可以很方便的实现: Code private void getPortName() { cmb_PortName.Items.Clear(); foreach (string s in SerialPort.GetPortNames()) { cmb_PortName.Items.Add(s); } } 下面为转载的其他网站的方法,代码使用C++编写: 第一个思路应该是用建立串口的方式来取得串口名,若建立失败,则此串口不存在 void GetComList() { CString strCom; int nCom = 0; int cou
chulia200020012010-04-17 02:21:05
如何获取PCI设备的配置和位置信息! http://blog.csdn.net/lew8311/archive/2007/01/09/1478055.aspx 概要 在作为目标设备驱动程序堆栈的一部分(充当函数或筛选器驱动程序)的驱动程序中,包含外围组件互连 (PCI) 设备的配置和位置信息(如 BusNumber、DeviceNumber 和 Function Number),本文介绍如何获取这些信息。 更多信息 < type="text/javascript">loadTOCNode(1, 'moreinformation'); 在 Windows NT 4.0 上,驱动程序通过扫描总线,并调用 HalGetBusData 和 HalGetBusDataByOffset 这两个 API 来获取此信息。在 Windows 2000 和更高版本的 Windows 操作系统中,控制硬件总线的则是它们各自的总线驱动程序,而不是 HAL。因此,在 Windows 2000 和更高版本的 Windows 操作系统中,过去用于提供总线相关信息的所有 Hal API 都已过时。
chulia200020012010-04-17 02:15:49
PCI设备Windows通用驱动程序设计 http://www.21ic.com/app/computer/200905/43004_3.htm 在设计和使用PCI设备时,经常要在PC机的软件中访问和控制硬件设备,但Windows操作系统(包括Windows 95/98、Windows NT、Windows 2000)为了保证系统的安全性、稳定性和可移植性,对应用程序访问硬件资源加以限制,这就要求设计设备驱动程序以实现PC机的软件对PCI设备的访问。 Windows下的驱动程序不仅仅包括物理设备的驱动程序,也包括为文件系统等非物理设备编写的虚拟设备驱动程序。为了简化问题,下面只讨论硬件物理设备的驱动程序。本文将以“通用高速PCI总线目标模块”[1]的驱动设计为例,探讨PCI设备的驱动程序设计方案。我们开发了一套通用的PCI设备驱动程序,它可以完成一般PCI设备驱动所需的功能,可以作为其它PCI设备驱动开发的框架。 1 驱动程序的模式和开发工具的选择 设备驱动程序是指管理某个外围设备的一段代码。驱动程序不会独立地存在,而是操作系统的一部分。通过设备驱动程序,多个进程可以