阅读:9146回复:34
请教如何做虚拟串口驱动?
我用driverstudio自动生成了一个驱动,什么也没有改动
我把inf文件里面的 class和classguid改成 Class=Ports ClassGUID={4d36e978-e325-11ce-bfc1-08002be10318} 然后在设备管理器里面看有我的驱动了,后面括号里面有com4。 哦,还有就是处理ioctl消息的地方,我没写,只是把返回值写成SUCCESS。请问各位高手,还有什么问题? 我没什么分。。谢谢大家了 [编辑 - 4/22/04 by hezhenwei] |
|
最新喜欢:yushui... |
沙发#
发布于:2004-04-21 11:25
论坛里有例子的,自己找找。。。
|
|
|
板凳#
发布于:2004-04-21 12:23
呵呵,只要在adddevice 里面用 pDevice->createlink(\"com4\")就可以了。哈哈。
现在用串口调试工具打开终于说ok了。 不过还不能进行读写,因为我还没有写:) 现在开始写写看。 我有个疑问,大家不要笑我。就是什么时候程序知道驱动有数据,该读了呢?是不是某个线路状态置1呢? |
|
地板#
发布于:2004-04-21 15:40
我用drivermoniter看
那个读串口的程序不停的在发送get_commstatus的消息。 我在程序里面处理了这个消息(把ddk serial例子里面对应的部分改了改) 就是把 pcommstatus error = 0 holdreasons =0 amountininqueue = 0; amountinoutqueue= 我的缓冲区大小。 eofreceived = true waitforimmediate = true 可是还是不行。driverMoniter里面根本看不到他调用read和write方法。 这是为什么? |
|
地下室#
发布于:2004-04-22 08:24
我看他们读串口是要先检查事件的发生。
那么驱动怎么通知应用程序发生了一些事件呢? 我看ddk上面有3个方法,应该用哪个呢? 是不是第三个 命名事件 ? 谢谢大家,给点提示吧,就算一两个提示性的单词也好, |
|
5楼#
发布于:2004-04-22 12:35
windows自带的超级终端和串口调试助手采用两种不同的机制。
超级终端采用查询的方式,串口调试助手和其他使用MSComm类的串口应用程序用的是事件通知的方式。 超级终端的方式: 不停的尝试读1个字节,读到为止 事件的方式:不主动读 先调用IOCTL_SERIAL_SET_WAIT_MASK设置一些标志 这个就相当于是设置硬件的哪些中断使能,哪些中断屏蔽掉 然后调用IOCTL_SERIAL_WAIT_ON_MASK发送一个IRP请求,这个IRP请求交给你处理。真正的串口就是当设定的MASK的事件发生的时候,中断处理程序就会完成这个IRP. 当IO管理器发现这个IRP返回了,它先IOCTL_GET_WAIT_MASK确认一下自己刚才设置了哪些标志,如果完成的IRP中SERIAL_EV_RXCHAR标志 被置位了,IO管理器就会IOCTL_GET_COMMSTATUS 注意!你这里出错了! pcommstatus error = 0 holdreasons =0 amountininqueue = 0; amountinoutqueue= 我的缓冲区大小。 eofreceived = true waitforimmediate = true AmountInInQueue中的数据应该是你接收到的字节数。你把这个设为00,IO管理器认为没有数据可以读,当然不会发Read请求了! 另外,你给的问题分数太少了,就没有人愿意回答你的问题了! [编辑 - 4/22/04 by lingzjl] |
|
|
6楼#
发布于:2004-04-22 12:38
WAIT_MASK各个bit的意义在 ddk/inc/ntddser.h中可以查到
|
|
|
7楼#
发布于:2004-04-22 12:43
哦,谢谢你啊。
我用DriverMoniter看,这个驱动收到的消息有这些: IOCTL_SERIAL_GET_BAUD_RATE GET LINE CONTROL GET CHARS GET HANDFLOW SET BAUD RATE CLR DTR SET LINE CONTROL SET CHARS SET HANDFLOW PURGE SET QUEUE SIZE SET TIMEOUTS 然后就是不停的收到 GET COMMSTATUS ,没看到有IOCTL_SERIAL_WAIT_ON_MASK这个消息阿。 我看了一下ddk帮助,是 set_wait_mask get_wait_mask wait_on_mask 这三个是吧。谢谢你啊。 我先把AmountInInQueue 改了试试看。 [编辑 - 4/22/04 by hezhenwei] |
|
8楼#
发布于:2004-04-22 13:09
还是不行。。。我把
AmountInInQueue和 AmountInOutQueue 都写成1,可是还是收不到东西。。。奇怪。。。 我再看看 |
|
9楼#
发布于:2004-04-22 13:45
发送哪个IOCTL每个程序并不是都相同。
如果没有发SET_WAIT_MASK,那么就是没有屏蔽了。 你收到READ请求了吗? 你怎么处理的? 另外,串口调试助手有一些小问题。 收到2个以下它不读,一次收到好几个它才读 [编辑 - 4/22/04 by lingzjl] [编辑 - 4/22/04 by lingzjl] |
|
|
10楼#
发布于:2004-04-22 13:53
read 过程中我先打印出来entering read
然后把缓冲区里面的一个字符写进那个buffer里面去。 用driverstudio自动成生的测试程序读写都是没问题的。 可是用一个串口调试工具就不行。 用drivermoniter看,里面没有打印出来entering read 。所以我想是程序没有调用read 我猜这个串口调试程序可能是不停的用getcommstatus读状态,发现有数据就调用read函数。。 可是我的serial_status 就是按照上面写的,怎么这个串口调试程序就是不调用read呢。。 |
|
11楼#
发布于:2004-04-22 13:58
case IOCTL_SERIAL_GET_COMMSTATUS:
.... SERIAL_STATUS* pCommStatus; pCommStatus = (SERIAL_STATUS*)I.IoctlBuffer(); pCommStatus->Error = 0; pCommStatus->holdreasons =0 pCommStatus->amountininqueue = 1; pCommStatus->amountinoutqueue= 1; pCommStatus->eofreceived = false pCommStatus->waitforimmediate = false; I.Information() = sizeof(SERIAL_STATUS); status = STATUS_SUCCESS; 我怀疑是不是这个里面那里写得不对了。。 |
|
12楼#
发布于:2004-04-22 14:59
你是说要改成2以上么?我来试试看。
|
|
13楼#
发布于:2004-04-22 15:16
我改了以后还是不行啊,他还是不调用read。奇怪。我改成10了
|
|
14楼#
发布于:2004-04-22 15:58
贴一段我的:
case IOCTL_SERIAL_GET_COMMSTATUS: { PSERIAL_STATUS S; //DebugPrint(\"-- IOCTL_SERIAL_GET_COMMSTATUS --\\n\"); /////////////////////////////////// if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_STATUS)) { status = STATUS_BUFFER_TOO_SMALL; break; } status = STATUS_SUCCESS; BytesTxd = sizeof(SERIAL_STATUS); S = (PSERIAL_STATUS)Irp->AssociatedIrp.SystemBuffer; S->Errors = 0; S->HoldReasons = 0; S->AmountInInQueue = 你收到的字节数; DebugPrint(\"comm:%d\\n\",S->AmountInInQueue); S->AmountInOutQueue = 0; S->EofReceived = FALSE; S->WaitForImmediate = FALSE; //DebugPrint(\"--EXIT IOCTL_SERIAL_GET_COMMSTATUS --\\n\"); break; } ///////////////////////////////////////// return CompleteIrp(Irp,status,BytesTxd); [编辑 - 4/22/04 by lingzjl] |
|
|
15楼#
发布于:2004-04-22 16:05
S = (PSERIAL_STATUS)Irp->AssociatedIrp.SystemBuffer;
我操作系统是windows 2000,不知道不同的操作系统有没有影响。 |
|
|
16楼#
发布于:2004-04-22 16:25
我也是2000.
我看来看去唯一的不同就是AmountInOutQueue 我写的是他和AmountInInQueue一样。 会不会有问题? 会不会不允许同时为非0? 我试试看 另外谢谢你帮我啊,我发表的时候只有1分,但是现在有30多分了,一会我全给你。 |
|
17楼#
发布于:2004-04-22 16:45
S = (PSERIAL_STATUS)Irp->AssociatedIrp.SystemBuffer;
这里不一样。 你的是pCommStatus = (SERIAL_STATUS*)I.IoctlBuffer(); |
|
|
18楼#
发布于:2004-04-23 08:26
呵呵,我看driverWorks的帮助,说
Irp.IoctlBuffer() 返回的就是Irp->AssociatedIrp.SystemBuffer的引用,所以我想这个没问题吧。 |
|
19楼#
发布于:2004-04-23 08:58
我昨天晚上自己写了个串口读写的工具,把winAPI所调用的ioctlcode对应关系看了一下。下面列出来大家参考
(下面对应的ioctlcode都省略了前面的IOCTL_SERIAL_) SetCommState get baud rate get line control get chars get handflow set baud rate clr rts clr dtr set line control set chars set handflow SetupComm set queue size SetCommTimeouts set timeouts FlushFileBuffers 调用 flushbuffers过程 PurgeComm purge SetCommMask set wait mask WaitCommEvent wait on mask transmitCommChar lsrmst_insert ClearCommError get commstatus GetCommConfig config size get baud rate get line control get chars get handflow SetCommConfig get baud rate get line control get chars get handflow set baud rate clr dtr set line control set chars set handflow ReadFile 调用read 好像还有23个,不过昨天晚上太困了,就没继续。 我看到只有ClearCommError发送了GET_COMMSTATUS的CODE,于是我自己调用ClearCommError察看返回的值。很奇怪 它的返回值也是20个字节的一个结构,可是和驱动写进去的不一样。 驱动写进去的应该是 SERIAL_STATUS 对吧,结构是 { LONG,LONG,LONG,LONG,BOOLEAN,BOOLEAN } 可是ClearCommError返回的是 COMMSTATUS结构 typedef struct _COMSTAT { DWORD fCtsHold : 1; // Tx waiting for CTS signal DWORD fDsrHold : 1; // Tx waiting for DSR signal DWORD fRlsdHold : 1; // Tx waiting for RLSD signal DWORD fXoffHold : 1; // Tx waiting, XOFF char received DWORD fXoffSent : 1; // Tx waiting, XOFF char sent DWORD fEof : 1; // EOF character sent DWORD fTxim : 1; // character waiting for Tx DWORD fReserved : 25; // reserved DWORD cbInQue; // bytes in input buffer DWORD cbOutQue; // bytes in output buffer } COMSTAT, *LPCOMSTAT; (摘自MSDN) 我将这个返回打印出来, cbInQue是10(就是我的驱动写进去的) fReserved 是 一个随机数, 其它都是0 那我想IOCTL_SERIAL_GET_COMMSTATUS 应该是正确返回了。 但是串口调试助手却不知什么原因不停的发送这个代码??? 还是不明白什么原因。 请高手多指教 [编辑 - 4/23/04 by hezhenwei] |
|
上一页
下一页