Windows驱动程序中与硬件通信:串口访问及CreateFile适用性疑问
Windows驱动内访问串口的机制与常见误区
核心结论:驱动内不能直接调用用户态的CreateFile
CreateFile是Win32用户态API,内核态驱动无法直接调用。驱动与硬件/其他设备通信的机制和用户态完全不同,你的原有理解只适用于用户态程序,不适用于内核态驱动。
驱动内访问串口的两种典型场景
1. 你是串口硬件的驱动开发者(自己实现串口驱动)
如果驱动直接负责管理串口硬件,不需要通过其他驱动中转,核心方式是直接操作硬件资源:
- 首先通过
IoAssignResources等函数获取串口的IO端口/内存资源 - 用
MmMapIoSpace将硬件的IO地址映射到内核虚拟地址空间 - 直接读写映射后的地址来操作串口寄存器(比如数据寄存器、控制寄存器),完成收发数据
- 若要给用户态提供访问接口,可通过
IoCreateDevice创建设备对象,再用IoCreateSymbolicLink创建用户态可见的符号链接(比如\\DosDevices\\COMx),然后实现IRP_MJ_READ/IRP_MJ_WRITE等派遣函数,用户态通过CreateFile打开该符号链接后,读写请求会以IRP的形式传递到驱动,由驱动处理后和硬件交互。
2. 你需要访问系统已有的串口驱动(比如标准COM端口)
如果要和系统自带的串口驱动通信,内核态需要通过**IO请求包(IRP)**来交互:
- 先通过
IoGetDeviceObjectPointer获取目标串口设备对象的指针(设备路径类似\\Device\\Serial0,用户态的COM1是该设备的符号链接) - 构造
IRP_MJ_READ/IRP_MJ_WRITE类型的IRP,设置好读写缓冲区和参数后,通过IoCallDriver发送给目标驱动,完成数据收发 - 也可以使用内核态的
ZwCreateFile函数(用户态CreateFile的内核态对应函数)打开设备对象,再用ZwReadFile/ZwWriteFile操作,但需要注意内核态的对象属性、权限设置,以及缓冲区的内存处理(必须用非分页内存或者正确锁定分页内存)。
纠正你的理解误区
用户态程序确实需要通过CreateFile获取设备句柄来访问硬件,但内核态驱动的逻辑完全不同:
- 驱动不需要用户态那种句柄,而是直接操作设备对象或硬件资源
- 驱动与硬件的通信要么是直接访问硬件寄存器(当驱动拥有硬件控制权时),要么是通过IRP与其他驱动交互(当访问其他驱动管理的硬件时)
内容的提问来源于stack exchange,提问作者Statistik
相关产品推荐
相关产品推荐

