windows下虚拟串口驱动开发

现在介绍在windows XP下开发虚拟串口的方法。可以开发一个虚拟串口,将读写请求传递给USB驱动,这样就可以利用现成的串口调试工具向USB设备读取了。
1、DDK串口开发框架
DDK对串口驱动提供了专门接口。只要编写的驱动满足这些接口,并按照串口标准的命名方法,不管是真实的串口设备,还是虚拟设备,Windows操作系统都会认为
这个设备是一个标准的串口设备。用标准的串口调试工具都可以与这个设备进行通信
1、1 串口驱动的入口函数
本章的实例程序是在HelloWDM驱动的基础上修改而来,入口函数依然是DriverEntry,在DriverEntry函数中指定各种IRP的派遣函数,以及AddDevice 例程、卸载例程等。
[cpp] view plaincopy
1. /************************************************************************ 
2. * 函数名称:DriverEntry 
3. * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象 
4. * 参数列表: 
5.       pDriverObject:从I/O管理器中传进来的驱动对象 
6.       pRegistryPath:驱动程序在注册表的中的路径 
7. * 返回 值:返回初始化驱动状态 
8. *************************************************************************/ 
9. #pragma INITCODE  
10. extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, 
11.                                 IN PUNICODE_STRING pRegistryPath) 
12.
13.     KdPrint(("Enter DriverEntry\n")); 
14.  
15.     pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice; 
16.     pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp; 
17.     pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloWDMDispatchControlp; 
18.     pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloWDMCreate; 
19. 格兰杰检验    pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloWDMClose; 
20.     pDriverObject->MajorFunction[IRP_MJ_READ] = HelloWDMRead; 
户外广告登记管理规定21.     pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMWrite; 
22.     pDriverObject->DriverUnload = HelloWDMUnload; 
23.  
24.     KdPrint(("Leave DriverEntry\n")); 
25.     return榆林杀人案 STATUS_SUCCESS; 
26.

其中在AddDevice例程中,需要创建设备对象,这些都是和以前的HelloWDM驱动程序类似。在创建完设备对象后,需要将设备对象指定一个符号链接,该符号链接必须是
COM开头,并接一下数字,如本例就采用了COM7。因为COM1和COM2在有些计算机中有时会被占用,因此,当该设备对象在指定符号链接时,应该避免采用这些名称。
[cpp] view plaincopy
1. /************************************************************************ 
2. * 函数名称:HelloWDMAddDevice 
3. * 功能描述:添加新设备 
4. * 参数列表: 
5.       DriverObject:从I/O管理器中传进来的驱动对象 
6.       PhysicalDeviceObject:从I/O管理器中传进来的物理设备对象 
7. * 返回 值:返回添加新设备状态 
8. *************************************************************************/ 
9. #pragma PAGEDCODE 
10. NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject, 
11.                            IN PDEVICE_OBJECT PhysicalDeviceObject) 
12. {   
13.     PAGED_CODE(); 
14.     KdPrint(("Enter HelloWDMAddDevice\n")); 
15.  
16.     NTSTATUS status; 
17.     PDEVICE_OBJECT fdo; 
18.     UNICODE_STRING devName; 
19.     RtlInitUnicodeString(&devName,L"\\Device\\MyWDMDevice"); 
20.     status = IoCreateDevice( 
21.         DriverObject, 
22.         说出你的故事2011sizeof(DEVICE_EXTENSION), 
23.         &(UNICODE_STRING)devName, 
24.         FILE_DEVICE_UNKNOWN, 
25.         0, 
26.         FALSE, 
27.         &fdo); 
28.     if( !NT_SUCCESS(status)) 
29.         return status; 
30. 网络安全控制技术    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension; 
31.     pdx->fdo = fdo; 
32.     pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject); 
33.     UNICODE_STRING symLinkName; 
34.     RtlInitUnicodeString(&symLinkName,L"\\DosDevices\\COM7"); 
35.  
36.     pdx->ustrDeviceName = devName; 
37.     pdx->ustrSymLinkName = symLinkName; 
38.     status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName,&(UNICODE_STRING)devName); 
39.  
40.     if( !NT_SUCCESS(status)) 
41.     { 
42.         IoDeleteSymbolicLink(&pdx->ustrSymLinkName); 
43.         status = IoCreateSymbolicLink(&symLinkName,&devName); 
44.         if( !NT_SUCCESS(status)) 
45.         { 
46. 饶宗颐书画            return status; 
47.         } 
48.     } 
49.     // 设置为缓冲区设备 
50.     fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE; 
51.     fdo->Flags &= ~DO_DEVICE_INITIALIZING; 
52.  
53.     KdPrint(("Leave HelloWDMAddDevice\n")); 
54.     return STATUS_SUCCESS; 
55.


在创建完符号链接后,还不能保证应用程序能出这个虚拟的串口设备,还需要进一步修改注册表。具体位置是HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM,可以在这里加入新项目。本例的项目名是MyWDMDevice,类型为REG_SZ,内容是COM7。
在上述步骤后,即在AddDevice例程中创建COM7的符号链接,并且在注册表进行相应设置,系统会认为有这个串口驱动,用任何一个串口调试软件,都可以枚举到
该串口。
 
1、2  应用程序与串口驱动的通信
其实对于一个真实的串口驱动,或者这个介绍的虚拟串口驱动,都需要遵循一组接口。这组接口由微软事先定义好了,只要符合这组接口,
windows就会认为这是一个串口设备。这里所指的接口就是应用程序发的IO控制码和读写命令,因此对于串口驱动只要对这些IRP的派遣函数编写适当,就能实现一个串口驱动。
首先用IRPTrace看一下,需要对哪些IRP进行处理,笔者加载本章已经介绍的虚拟串口驱动,并用IRPTrace 拦截其IRP处理信息,在打开串口工具后,会发现IRPTrace立刻跟踪到若干个IO控制码,如下所示:
 
 
下面依次解释这些IO控制码,理解这些IO控制码,并处理好这些控制码,是编写串口驱动的核心。关于这些IO控制码在ntddser.件中,都有相应的定义,并且还有
相应的数据结构定义。
(1)IOCTL_SERIAL_SET_QUEUE_SIZE
这个控制码是应用程序向驱动请求设置串口驱动内部的缓冲区大小,它是向驱动传递SEA
RIAL_QUEUE_SIZE 数据结构来进行设置的,对于虚拟串口驱动来说,这是不需要
关心的。用IRPTrace可以看出,串口调试工具会向驱动发送的请求是0x400大小的缓冲区大小。

本文发布于:2024-09-25 12:30:38,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/233302.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:串口   驱动   设备   虚拟   对象   控制
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议