WP2K3
驱动牛犊
驱动牛犊
  • 注册日期2003-03-07
  • 最后登录2003-08-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1143回复:0

请高手指点,串口VxD为何发送不出数据

楼主#
更多 发布于:2003-03-07 18:03
用QuickVxD写了一串口驱动程序,但在有些机子上工作(机子较老),有些
机子上不工作,数据发不出去,操作系统是同一版本的温98,不知问题何在?
请高手指点!以下是源程序(EMail:wp2k3@163.com)
// LQVXDZJ.h - include file for VxD LQVXDZJ

#include <vtoolscp.h>

#define DEVICE_CLASS LqvxdzjDevice
#define LQVXDZJ_DeviceID UNDEFINED_DEVICE_ID
#define LQVXDZJ_Init_Order UNDEFINED_INIT_ORDER
#define LQVXDZJ_Major 1
#define LQVXDZJ_Minor 0
#define Maxchrcm1 32760
#define Maxchrcm2 32760
#define IRQ4 4 //COM1中断
#define IRQ3 3 //COM2中断

class MyInt0c:public VSharedHardwareInt
{
public:
MyInt0c():VSharedHardwareInt(IRQ4,0,0,0){}
virtual BOOL OnSharedHardwareInt(VMHANDLE);
};

class MyInt0b:public VSharedHardwareInt
{
public:
MyInt0b():VSharedHardwareInt(IRQ3,0,0,0){}
virtual BOOL OnSharedHardwareInt(VMHANDLE);
};

class LqvxdzjDevice : public VDevice
{
public:
virtual BOOL OnSysDynamicDeviceInit();
virtual BOOL OnSysDynamicDeviceExit();
virtual DWORD OnW32DeviceIoControl(PIOCTLPARAMS p);
MyInt0c *pMy0c;
MyInt0b *pMy0b;
};

class LqvxdzjVM : public VVirtualMachine
{
public:
LqvxdzjVM(VMHANDLE hVM);
};

class LqvxdzjThread : public VThread
{
public:
LqvxdzjThread(THREADHANDLE hThread);
};


// LQVXDZJ.cpp - main module for VxD LQVXDZJ
#define DEVICE_MAIN
#include \"lqvxdzj.h\"
Declare_Virtual_Device(LQVXDZJ)
#undef DEVICE_MAIN

#define Initcom 2111
#define Outcom1 2112
#define Getcom1 2113
#define Tstcom1 2114
#define Outcom2 2212
#define Getcom2 2213
#define Tstcom2 2214

int bps1h,bps1l,com1adr,cm1get,cm1rb,cm1re,
bps2h,bps2l,com2adr,cm2get,cm2rb,cm2re;
char bufcm1[Maxchrcm1+20],bufcm2[Maxchrcm2+20];

HANDLE apphwnd;
LqvxdzjVM::LqvxdzjVM(VMHANDLE hVM) : VVirtualMachine(hVM) {}
LqvxdzjThread::LqvxdzjThread(THREADHANDLE hThread) : VThread(hThread) {}

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);
com1adr=*pi; pi++; com2adr=*pi;
pMy0c=NULL; pMy0b=NULL;
if( (com1adr==0) || (com2adr==0) ) return false;
pMy0c=new MyInt0c();
if(pMy0c==NULL) return FALSE;
pMy0b=new MyInt0b();
if(pMy0b==NULL)
{
delete pMy0c;
pMy0c=NULL;
return FALSE;
}
if(!pMy0c->hook())
{
delete pMy0c;
delete pMy0b;
pMy0c=NULL; pMy0b=NULL;
return FALSE;
}
if(!pMy0b->hook())
{
pMy0c->unhook();
delete pMy0c;
delete pMy0b;
pMy0c=NULL; pMy0b=NULL;
return FALSE;
}

pMy0c->physicalUnmask(); //允许中断
pMy0b->physicalUnmask(); //允许中断
return TRUE;
}

BOOL LqvxdzjDevice::OnSysDynamicDeviceExit()
{
if(pMy0c!=NULL) pMy0c->physicalMask(); //不允许中断
if(pMy0b!=NULL) pMy0b->physicalMask(); //不允许中断
if(com1adr>0)
{
_outp(com1adr+1,0); //?F9 不用中断
_outp(com1adr+4,0); //?FC 不用中断
}
if(com2adr>0)
{
_outp(com2adr+1,0); //?F9 不用中断
_outp(com2adr+4,0); //?FC 不用中断
}
pMy0c->unhook(); pMy0b->unhook();
delete pMy0c; delete pMy0b;
pMy0c=NULL; pMy0b=NULL;
return TRUE;
}

bool MyInt0c::OnSharedHardwareInt(VMHANDLE hVM)
{
int i,j,k,l,crc;
WORD *pwd;
char *pchr;
cm1wktmout=Cm1WkOut; com1stm=Com1sOut;
i=bps1l | bps1h;
if( i!=0 && com1adr>0 )
{ i=_inp(com1adr+2); //?FA
_inp(com1adr+5); //?FD
_inp(com1adr+6); //?FE
i&=4;
if(i==0) goto c1exit;
i=_inp(com1adr);
bufcm1[cm1re]=(char)i;
cm1re++;
if(cm1re>Maxchrcm1) cm1re=cm1rb;
}
sendPhysicalEOI();
return false;
}
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;
}
void delay1()
{
int i;
for(i=0;i<1000;i++);
}
void watcmx(int cmadr)
{
int i,j;
for(i=0;i<0x4000;i++)
{
_inp(cmadr+6); //?FE
j=_inp(cmadr+5); //?FD 线状态REG
if((j&0x20)>0) break;
}
}
DWORD LqvxdzjDevice::OnW32DeviceIoControl(PIOCTLPARAMS p)
{
int i,j,k,l,*pti,crc;
WORD *pwd,*kbuf,*kbeg,*kend;
char *ptc;
switch(p->dioc_IOCtlCode)
{
case DIOC_OPEN:
case DIOC_CLOSEHANDLE:
break;
case Initcom: //初始化COM1,COM2
/*ring3给ring0的数据为:
int app HANDLE
int 串口1波特率因子
int 串口2波特率因子
(DW 串口1波特率因子)
(DW 串口2波特率因子)
*/
pti=(int *)p->dioc_InBuf;
apphwnd=(void *)(*pti); pti++; //主控制窗口句柄(HANDLE)
bps1l=bps1h=bps2l=bps2h=0;
i=*pti; pti++; //串口1波特率因子
j=*pti; pti++; //串口2波特率因子

bps1l=i&0xff; bps1h=(i>>8)&0xff;
bps2l=j&0xff; bps2h=(j>>8)&0xff;
if(i>0 & com1adr>0)
{
_outp(com1adr+3,0x80); //?FB,设置BPS
_outp(com1adr+1,bps1h); //?F9,BPS High
_outp(com1adr,bps1l); //?F8,BPS Low
_outp(com1adr+3,0x27); //?FB,无奇偶校验,8位数据,2位停止位
_outp(com1adr+4,0x0a); //?FC,允许中断方式工作
_outp(com1adr+2,7); //FIFO控制REG,复位输入及输出FIFO
_outp(com1adr+1,1); //?F9,允许COM1接收数据中断
}
com1stm=aanum1=tobuf1=cm1get=bufcm1[0]=bufcm1[1]=0;
cm1rb=cm1re=2;
if(j>0 & com2adr>0)
{
_outp(com2adr+3,0x80); //?FB,设置BPS
_outp(com2adr+1,bps2h); //?F9,BPS High
_outp(com2adr,bps2l); //?F8,BPS Low
_outp(com2adr+3,0x27); //?FB,无奇偶校验,8位数据,2位停止位
_outp(com2adr+4,0x0a); //?FC,允许中断方式工作
_outp(com2adr+2,7); //FIFO控制REG,复位输入及输出FIFO
_outp(com2adr+1,1); //?F9,允许COM2接收数据中断
}
aanum2=tobuf2=cm2get=bufcm2[0]=bufcm2[1]=0;
cm2rb=cm2re=2;
break;
case Outcom1: //从COM1发送数据
l=bps1l | bps1h;
if( l==0 || com1adr==0) break;

pwd=(WORD *)p->dioc_InBuf; //ring3给ring0的数据
l=*pwd; pwd++; ptc=(char *)pwd;
if(l>0)
{
for(i=crc=0;i<l;i++)
crc+=((*(ptc+i))&0xff);

i=(l+2)&0xff; j=((l+2)>>8)&0xff; //长度含2字节CRC

watcmx(com1adr);
_outp(com1adr,i); //发长度低位
delay1();
watcmx(com1adr);
_outp(com1adr,j); //发长度高位
delay1();

for(i=0;i<l;i++) //发送数据
{
watcmx(com1adr);
_outp(com1adr,(*(ptc+i))&0xff);
delay1();
}

i=crc&0xff; j=(crc>>8)&0xff; //发2字节CRC
watcmx(com1adr);
_outp(com1adr,i); //发CRC低位
delay1();
watcmx(com1adr);
_outp(com1adr,j); //发CRC高位
delay1();

watcmx(com1adr);
_outp(com1adr,0); //发2个无用字节
delay1();
watcmx(com1adr);
_outp(com1adr,0);
delay1();
}
break;
case Getcom1: //从COM1取接收数据
ptc=(char *)(bufcm1+cm1get);
pwd=(WORD *)ptc; l=*pwd;
pti=(int *)p->dioc_OutBuf; //ring0给ring3的数据
*pti=l;
if(l>0)
{
if(l>p->dioc_cbOutBuf) l=p->dioc_cbOutBuf;
ptc=(char *)p->dioc_OutBuf;
memcpy(ptc,(char *)(bufcm1+cm1get),l+2);
cm1get+=l+2;
}
if( (cm1get==cm1rb-2) && (cm1rb==cm1re) )
{
cm1get=bufcm1[0]=bufcm1[1]=0;
cm1rb=cm1re=2;
}
break;
case Tstcom1: //测试COM1是否有接收数据
ptc=(char *)(bufcm1+cm1get);
pwd=(WORD *)ptc; l=*pwd;
pti=(int *)p->dioc_OutBuf; //ring0给ring3的数据
*pti=l;
if(l>0)
{
if(l>p->dioc_cbOutBuf) l=p->dioc_cbOutBuf;
ptc=(char *)p->dioc_OutBuf;
memcpy(ptc,(char *)(bufcm1+cm1get),l+2);
}
break;

case Outcom2: //从COM2发送数据
l=bps2l | bps2h;
if(l==0 || com2adr==0) break;

pwd=(WORD *)p->dioc_InBuf; //ring3给ring0的数据
l=*pwd; pwd++; ptc=(char *)pwd;
if(l>0)
{
for(i=crc=0;i<l;i++)
crc+=((*(ptc+i))&0xff);

i=(l+2)&0xff; j=((l+2)>>8)&0xff; //长度含2字节CRC

watcmx(com2adr);
_outp(com2adr,i); //发长度低位
delay1();
watcmx(com2adr);
_outp(com2adr,j); //发长度高位
delay1();

for(i=0;i<l;i++) //发送数据
{
watcmx(com2adr);
_outp(com2adr,(*(ptc+i))&0xff);
delay1();
}

i=crc&0xff; j=(crc>>8)&0xff; //发2字节CRC
watcmx(com2adr);
_outp(com2adr,i); //发CRC低位
delay1();
watcmx(com2adr);
_outp(com2adr,j); //发CRC高位
delay1();

watcmx(com2adr);
_outp(com2adr,0); //发2个无用字节
delay1();
watcmx(com2adr);
_outp(com2adr,0);
delay1();
}
break;
case Getcom2: //从COM2取接收数据
ptc=(char *)(bufcm2+cm2get);
pwd=(WORD *)ptc; l=*pwd;
pti=(int *)p->dioc_OutBuf; //ring0给ring3的数据
*pti=l;
if(l>0)
{
if(l>p->dioc_cbOutBuf) l=p->dioc_cbOutBuf;
ptc=(char *)p->dioc_OutBuf;
memcpy(ptc,(char *)(bufcm2+cm2get),l+2);
cm2get+=l+2;
}
if( (cm2get==cm2rb-2) && (cm2rb==cm2re) )
{
cm2get=bufcm2[0]=bufcm2[1]=0;
cm2rb=cm2re=2;
}
break;
case Tstcom2: //测试COM2是否有接收数据
ptc=(char *)(bufcm2+cm2get);
pwd=(WORD *)ptc; l=*pwd;
pti=(int *)p->dioc_OutBuf; //ring0给ring3的数据
*pti=l;
if(l>0)
{
if(l>p->dioc_cbOutBuf) l=p->dioc_cbOutBuf;
ptc=(char *)p->dioc_OutBuf;
memcpy(ptc,(char *)(bufcm2+cm2get),l+2);
}
break;
}
return 0;
}

靠天靠地靠神仙 不如一切靠自己 自力更生,艰苦奋斗!
游客

返回顶部