阅读:1143回复:0
请高手指点,串口VxD为何发送不出数据
用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; } |
|
|