hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:9146回复:34

请教如何做虚拟串口驱动?

楼主#
更多 发布于:2004-04-21 11:14
我用driverstudio自动生成了一个驱动,什么也没有改动
我把inf文件里面的
class和classguid改成

Class=Ports
ClassGUID={4d36e978-e325-11ce-bfc1-08002be10318}

然后在设备管理器里面看有我的驱动了,后面括号里面有com4。
哦,还有就是处理ioctl消息的地方,我没写,只是把返回值写成SUCCESS。请问各位高手,还有什么问题?

我没什么分。。谢谢大家了

[编辑 -  4/22/04 by  hezhenwei]

最新喜欢:

yushui213yushui...
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2004-04-21 11:25
论坛里有例子的,自己找找。。。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-04-21 12:23
呵呵,只要在adddevice 里面用 pDevice->createlink(\"com4\")就可以了。哈哈。
现在用串口调试工具打开终于说ok了。
不过还不能进行读写,因为我还没有写:)
现在开始写写看。
我有个疑问,大家不要笑我。就是什么时候程序知道驱动有数据,该读了呢?是不是某个线路状态置1呢?
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于: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方法。
这是为什么?
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-22 08:24
我看他们读串口是要先检查事件的发生。
那么驱动怎么通知应用程序发生了一些事件呢?
我看ddk上面有3个方法,应该用哪个呢?
是不是第三个 命名事件 ?
谢谢大家,给点提示吧,就算一两个提示性的单词也好,
lingzjl
驱动牛犊
驱动牛犊
  • 注册日期2001-10-06
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
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]
超级肥雀
lingzjl
驱动牛犊
驱动牛犊
  • 注册日期2001-10-06
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-04-22 12:38
WAIT_MASK各个bit的意义在 ddk/inc/ntddser.h中可以查到
超级肥雀
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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]
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-04-22 13:09
还是不行。。。我把
AmountInInQueue和
AmountInOutQueue
都写成1,可是还是收不到东西。。。奇怪。。。
我再看看
lingzjl
驱动牛犊
驱动牛犊
  • 注册日期2001-10-06
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-04-22 13:45
发送哪个IOCTL每个程序并不是都相同。
如果没有发SET_WAIT_MASK,那么就是没有屏蔽了。

你收到READ请求了吗?
你怎么处理的?
另外,串口调试助手有一些小问题。
收到2个以下它不读,一次收到好几个它才读

[编辑 -  4/22/04 by  lingzjl]

[编辑 -  4/22/04 by  lingzjl]
超级肥雀
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-04-22 13:53
read 过程中我先打印出来entering read
然后把缓冲区里面的一个字符写进那个buffer里面去。

用driverstudio自动成生的测试程序读写都是没问题的。

可是用一个串口调试工具就不行。
用drivermoniter看,里面没有打印出来entering read 。所以我想是程序没有调用read

我猜这个串口调试程序可能是不停的用getcommstatus读状态,发现有数据就调用read函数。。
可是我的serial_status 就是按照上面写的,怎么这个串口调试程序就是不调用read呢。。
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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;

我怀疑是不是这个里面那里写得不对了。。
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-04-22 14:59
你是说要改成2以上么?我来试试看。
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-04-22 15:16
我改了以后还是不行啊,他还是不调用read。奇怪。我改成10了
lingzjl
驱动牛犊
驱动牛犊
  • 注册日期2001-10-06
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
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]
超级肥雀
lingzjl
驱动牛犊
驱动牛犊
  • 注册日期2001-10-06
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-04-22 16:05
S = (PSERIAL_STATUS)Irp->AssociatedIrp.SystemBuffer;
我操作系统是windows 2000,不知道不同的操作系统有没有影响。
超级肥雀
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-04-22 16:25
我也是2000.
我看来看去唯一的不同就是AmountInOutQueue
我写的是他和AmountInInQueue一样。
会不会有问题?
会不会不允许同时为非0?
我试试看

另外谢谢你帮我啊,我发表的时候只有1分,但是现在有30多分了,一会我全给你。
lingzjl
驱动牛犊
驱动牛犊
  • 注册日期2001-10-06
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-04-22 16:45
S = (PSERIAL_STATUS)Irp->AssociatedIrp.SystemBuffer;
这里不一样。
你的是pCommStatus = (SERIAL_STATUS*)I.IoctlBuffer();

超级肥雀
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-04-23 08:26
呵呵,我看driverWorks的帮助,说
Irp.IoctlBuffer()
返回的就是Irp->AssociatedIrp.SystemBuffer的引用,所以我想这个没问题吧。
hezhenwei
驱动牛犊
驱动牛犊
  • 注册日期2003-04-16
  • 最后登录2004-05-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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]
上一页
游客

返回顶部