阅读:1769回复:12
串口VxD驱动程序,数据发不出去?无人能解吗?
用QuickVxD写了一串口驱动程序,但在有些机子上工作(机子较老),有些机子上不工作,数据发不出去,操作系统是同一版本的温98,不知问题何在?请高手指点!
|
|
|
沙发#
发布于:2003-03-09 21:16
bool LqvxdzjDevice::OnSysDynamicDeviceInit()
{ aanum1=tobuf1=cm1get=bufcm1[0]=bufcm1[1]= aanum2=tobuf2=cm2get=bufcm2[0]=bufcm2[1]=0; cm1rb=cm1re=cm2rb=cm2re=2; apphwnd=NULL; WORD *pi; int er,i; pi=(WORD *)(0x400+i); // i没有初值呀 bool MyInt0b::OnSharedHardwareInt(VMHANDLE hVM) { int i,j,k,l,crc; WORD *pwd; char *pchr; i=bps2l | bps2h; if( i!=0 && com2adr>0 ) { i=_inp(com2adr+2); //?FA _inp(com2adr+5); //?FD _inp(com2adr+6); //?FE i=_inp(com2adr); bufcm2[cm2re]=(char)i; cm2re++; if(cm2re>Maxchrcm2) cm2re=cm2rb; } sendPhysicalEOI(); return false; // 处理了怎么返回false? } |
|
板凳#
发布于:2003-03-10 11:27
感谢arthurtu,由于我将不重要的部分删了,因此造成变量没有初始化,其实语句:
pi=(WORD *)(0x400+i); 可看成: pi=(WORD *)0x400; 主要是从物理地址0x400处取出串口的地址 现在的问题是,只要我先运行DOS下的程序(见后) 而且不能退出,再调用VxD,运行就一切正常,一旦退出DOS程序,VxD就不工作了,为何? /* -------------------------- 仅运行,直到按Esc键 -------------------------- */ #include \"stdio.h\" #include \"stdlib.h\" #include \"conio.h\" #include \"dos.h\" #include \"io.h\" #include \"string.h\" /*===============================================*/ int i,j,k,m,n; main() { i=0x2f8; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; i=0x3f8; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; i=0x2f8; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; i=0x3f8; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; outportb(i,0); i++; k=0; while(k!=0x1b) k=bioskey(0)&0xff; exit(0); } |
|
|
地板#
发布于:2003-03-10 11:56
怎么可以到0X400取串口地址呢!0X400是DOS的系统参数区,WINDOWS下你的0X400是虚拟地址怎么能取到串口地址。
|
|
地下室#
发布于:2003-03-10 12:04
确实在WIN98下取到了地址,而且在0xa0000以下的地址都可直接操作,WINDOWS将640K以下的内容全部复制到了她的每一个VM中.
|
|
|
5楼#
发布于:2003-03-10 23:54
确实在WIN98下取到了地址,而且在0xa0000以下的地址都可直接操作,WINDOWS将640K以下的内容全部复制到了她的每一个VM中.
那只是在虚拟DOS下。 |
|
6楼#
发布于:2003-03-11 09:21
并非在虚拟DOS下,我是参考\"<<Win9x虚拟设备驱动程序编程指南>>清华大学出版社 杨强 李堂秋编著\"的书第28页\"COM2中断实例\",而且我从VxD中将我要用的数据都传道我的VC++程序中,跟踪观察,确实没错.现在的问题是:
好象IO口不允许操作,所以VxD中不能从串口输出数据,但温98下好象没有限制在VxD中对IO口操作,WDM下好象有,但98下如何在VxD中设置允许操作IO口,请指点. |
|
|
7楼#
发布于:2003-03-11 12:43
98下不存在“VxD中设置允许操作IO口”的问题,除非有其他VM占用,或者说有DOS程序占用。
|
|
8楼#
发布于:2003-03-11 14:00
现在的问题是,只要我先运行DOS下的程序,胡乱给串口写点数据,而且不能退出,再调用VxD,运行就一切正常,一旦退出DOS程序,VxD就不工作了,为何?
|
|
|
9楼#
发布于:2003-03-11 23:53
DOS下的0x400是段地址,实际地址是0x400*0x10+offset,而windows下实际地址是0x400+offset,一个16位,一个32位,怎么可能???
除非你的应用程序是DOS下的,和windows不沾边 |
|
10楼#
发布于:2003-03-12 00:36
0x400是地址(即DOS下的所谓偏移量,C语言中的指针),不是段地址,它的段选择符为0x30,写成DOS方式的话,它的地址是0030:00000400,当然,是16进制;它的内容与DOS下的0000:0400的内容是完全一样的.你要不信,可加载Windows的SoftICE,随便何时,用Ctrl+D进入ICE界面,
D 400看看,屏幕显示的内容(0030:00000400的内容)与DOS下的0000:0400的内容是完全一样的,你还怀疑吗?而且所有WINDOWS的程序,使用的是同一个VM,这个问题多人都讨论过. 我现在的问题是:在某些机子上,加载Windows的SoftICE后,用Ctrl+D进入ICE界面,键入I 3F8 系统返回FF,其实从3F8--3FF输入的值都是FF,而一旦进入DOS程序(不退出),再进入ICE界面,键入I 3F8 系统返回0,退出DOS程序后,进入ICE界面,键入I 3F8 系统又返回FF;当返回FF时,我的VxD就不能工作,而当返回0时,VxD就工作正常,害的我每次都得加载DOS程序;但有些机子没有上述现象.不知原因何在? |
|
|
11楼#
发布于:2003-03-12 09:14
又试过几台机子,发现不是我VxD的问题,要不为何连Windows的SoftICE都从串口发不出数据(不是都不行,有些机子可以,当然我的VxD也能正常工作)?!万般无奈,我只好在我的VC++程序(运行在Ring3层)中加入以下语句:
HANDLE hcm1; //加在.h文件中 //以下语句加在调用VxD语句之前 hcm1=CreateFile( \"COM1\",GENERIC_READ | GENERIC_WRITE,0,0, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0); //以下语句加在程序退出时 CloseHandle(hcm1); 中间的通讯全用我的VxD来完成,总算用这变通的方法搞定,谢谢大家! |
|
|
12楼#
发布于:2003-03-12 11:05
你是对的,算我没说
|
|