📄 dnw.cpp
字号:
CloseHandle(hFile);
//EB_Printf(TEXT("cs=%x\n"),cs);
threadResult=_beginthread( (void (*)(void *))TxFile,0x2000,(void *)0);
if(threadResult!=-1)
{
//Create the download progress dialogbox.
CreateDialog(_hInstance,MAKEINTRESOURCE(IDD_DIALOG1),hwnd,DownloadProgressProc); //modaless
//ShowWindow(_hDlgDownloadProgress,SW_SHOW);
//isn't needed because the dialog box already has WS_VISIBLE attribute.
}
else
{
EB_Printf(TEXT("[ERROR:Can't creat a thread. Memory is not sufficient]\n"));
}
//The dialog box will be closed at the end of TxFile().
//free(txBuf) & CloseHandle(hWrite) will be done in TxFile()
}
void MenuOptions(HWND hwnd)
{
int result;
//Create the download progress dialogbox.
result=DialogBox(_hInstance,MAKEINTRESOURCE(IDD_DIALOG2),_hwnd,OptionsProc); //modal
if(result==1 && isConnected==1)
{
MenuConnect(hwnd); //reconfig the serial port.
}
}
/*****************************
* *
* serial communication part *
* *
*****************************/
BOOL OpenComPort(int port)
//port=1,2,3,4
{
TCHAR *textCom[]={TEXT("COM1"),TEXT("COM2"),TEXT("COM3"),TEXT("COM4")};
DCB dcb;
COMMTIMEOUTS commTimeOuts;
//====================================================
osRead.Offset=0;
osRead.OffsetHigh=0;
osWrite.Offset=0;
osWrite.OffsetHigh=0;
osRead.hEvent = CreateEvent(NULL,TRUE/*bManualReset*/,FALSE,NULL);
//manual reset event object should be used.
//So, system can make the event objecte nonsignalled.
//osRead.hEvent & osWrite.hEvent may be used to check the completion of
// WriteFile() & ReadFile(). But, the DNW doesn't use this feature.
if(osRead.hEvent==NULL)
{
EB_Printf(TEXT("[ERROR:CreateEvent for osRead.]\n"));
return FALSE;
}
osWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
if(osWrite.hEvent==NULL)
{
EB_Printf(TEXT("[ERROR:CreateEvent for osWrite.]\n"));
return FALSE;
}
//====================================================
idComDev=CreateFile(textCom[port-1],
GENERIC_READ|GENERIC_WRITE,
0, //exclusive access
/*FILE_SHARE_READ|FILE_SHARE_WRITE,*/
NULL,
OPEN_EXISTING,
#if IS_OVERLAPPED_IO
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
#else
/*FILE_ATTRIBUTE_NORMAL,*/ 0,
#endif
NULL);
if(idComDev==INVALID_HANDLE_VALUE)
{
//EB_Printf(TEXT("[ERROR:CreateFile for opening COM port.]\n") );
return FALSE;
}
SetCommMask(idComDev,EV_RXCHAR);
SetupComm(idComDev,4096,4096);
PurgeComm(idComDev,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
commTimeOuts.ReadIntervalTimeout=0xffffffff;
commTimeOuts.ReadTotalTimeoutMultiplier=0;
commTimeOuts.ReadTotalTimeoutConstant=1000;
commTimeOuts.WriteTotalTimeoutMultiplier=0;
commTimeOuts.WriteTotalTimeoutConstant=1000;
SetCommTimeouts(idComDev,&commTimeOuts);
//====================================================
dcb.DCBlength=sizeof(DCB);
GetCommState(idComDev,&dcb);
dcb.fBinary=TRUE;
dcb.fParity=FALSE;
dcb.BaudRate=userBaudRate; //CBR_115200;
dcb.ByteSize=8;
dcb.Parity=0;
dcb.StopBits=0;
dcb.fDtrControl=DTR_CONTROL_DISABLE;
dcb.fRtsControl=RTS_CONTROL_DISABLE;
dcb.fOutxCtsFlow=0;
dcb.fOutxDsrFlow=0;
if(SetCommState(idComDev,&dcb)==TRUE)
{
isConnected=TRUE;
_beginthread( (void (*)(void *))DoRxTx,0x2000,(void *)0);
return TRUE;
}
else
{
isConnected=FALSE;
CloseHandle(idComDev);
return FALSE;
}
}
void CloseComPort(void)
{
if(isConnected)
{
isConnected=FALSE;
SetCommMask(idComDev,0);
//disable event notification and wait for thread to halt
EscapeCommFunction(idComDev,CLRDTR);
PurgeComm(idComDev,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
CloseHandle(idComDev);
CloseHandle(osRead.hEvent);
CloseHandle(osWrite.hEvent);
}
Sleep(100);
//wait until CloseComPort() effective.
//If not, OpenComPort()::CreateFile(...) will fail.
}
void DoRxTx(void *args)
{
OVERLAPPED os;
DWORD dwEvtMask;
int nLength;
BOOL fStat;
DWORD temp;
memset(&os,0,sizeof(OVERLAPPED));
os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
if(os.hEvent==NULL)
{
EB_Printf(TEXT("[ERROR:DoRxTx os.hEvent]\n"));
_endthread();
}
if(!SetCommMask(idComDev,EV_RXCHAR|EV_TXEMPTY|EV_ERR))
{
EB_Printf(TEXT("[ERROR:SetCommMask()]\n"));
CloseHandle(os.hEvent);
_endthread();
}
while(isConnected)
{
dwEvtMask=0;
#if IS_OVERLAPPED_IO
fStat=WaitCommEvent(idComDev,&dwEvtMask,&os);
//Apr.28.2003: fStat should be checked for the cpu time saving.
if(!fStat) //Apr.28.2003:GetOverlappedResult() is needed.
{
//By experiment. Only when there was no signalled event, the following was executed.
//EB_Printf(TEXT("\n[WaitCommEvent=false]\n") );
if(GetLastError()==ERROR_IO_PENDING)
{
GetOverlappedResult(idComDev,&os,&temp,TRUE);
}
else
{
EB_Printf(TEXT("[RXTX_THREAD_ERR]") );
}
}
#else
WaitCommEvent(idComDev,&dwEvtMask,NULL); //wait until any event is occurred.
#endif
if( (dwEvtMask & EV_TXEMPTY) == EV_TXEMPTY )
txEmpty=TRUE;
if((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
do //Apr.28.2003:The caveat on MSDN,"Serial Communications in Win32" recommends while();
{
if( nLength=ReadCommBlock(rxBuf,MAX_BLOCK_SIZE) )
{
if(nLength>=MAX_BLOCK_SIZE /*for debug*/)
{
EB_Printf(TEXT("\n\n\n\n\n\n\n[ERROR:nLength>4096]\n"));
}
else
{
rxBuf[nLength]='\0';
//OutputDebugString(rxBuf);
EB_Printf(rxBuf);
}
}
}while(nLength);
}
// Clear OVERRUN condition.
// If OVERRUN error is occurred,the tx/rx will be locked.
if(dwEvtMask & EV_ERR)
{
COMSTAT comStat;
DWORD dwErrorFlags;
ClearCommError(idComDev,&dwErrorFlags,&comStat);
//EB_Printf(TEXT("[DBG:EV_ERR=%x]\n"),dwErrorFlags);
}
}
CloseHandle(os.hEvent);
_endthread();
}
int ReadCommBlock(char *buf,int maxLen)
{
BOOL fReadStat;
COMSTAT comStat;
DWORD dwErrorFlags;
DWORD dwLength;
ClearCommError(idComDev,&dwErrorFlags,&comStat);
dwLength=min((DWORD)maxLen,comStat.cbInQue);
if(dwLength>0)
{
#if IS_OVERLAPPED_IO
fReadStat=ReadFile(idComDev,buf,dwLength,&dwLength,&osRead);
if(!fReadStat) //Apr.28.2003:GetOverlappedResult() may be needed.
{
//By experiment, fReadStat was always TRUE,of course, and the following was never executed.
//EB_Printf(TEXT("\n[RX_RD_WAIT]\n") );
if(GetLastError()==ERROR_IO_PENDING)
{
GetOverlappedResult(idComDev,&osRead,&dwLength,TRUE);
}
else
{
EB_Printf(TEXT("[RXERR]") );
}
}
#else
fReadStat=ReadFile(idComDev,buf,dwLength,&dwLength,NULL);
if(!fReadStat)
{
EB_Printf(TEXT("[RXERR]") );
}
#endif
}
return dwLength;
}
#define TX_SIZE 2048
//TX_SIZE must be less than 4096
void TxFile(void *args)
{
void *txBlk;
DWORD txBlkSize;
DWORD fWriteStat;
DWORD temp;
InitDownloadProgress();
while(txEmpty==FALSE);
while(1)
{
if((txBufSize-iTxBuf) > TX_SIZE)
txBlkSize=TX_SIZE;
else
txBlkSize=txBufSize-iTxBuf;
txBlk=(void *)(txBuf+iTxBuf);
txEmpty=FALSE;
#if IS_OVERLAPPED_IO
fWriteStat=WriteFile(idComDev,txBlk,txBlkSize,&temp,&osWrite);
if(!fWriteStat) //Apr.28.2003:GetOverlappedResult() may be needed.
{
if(GetLastError()==ERROR_IO_PENDING)
{
GetOverlappedResult(idComDev,&osWrite,&temp,TRUE);
//more efficient in order to save the cpu time
}
else
{
EB_Printf(TEXT("[TXERR]") );
}
}
else
{
//By experiment, never executed.
//EB_Printf(TEXT("\n[TX_NO_WR_WAIT]\n") );
}
#else
WriteFile(idComDev,txBlk,txBlkSize,&temp,NULL);
Sleep(TX_SIZE*1000/11520-10); //to save cpu time.
while(txEmpty==FALSE);
#endif
iTxBuf+=TX_SIZE;
DisplayDownloadProgress(iTxBuf*100/txBufSize);
if(downloadCanceled==1)break; //download is canceled by user.
if(iTxBuf>=txBufSize)break;
}
free((void *)txBuf);
CloseDownloadProgress();
_endthread();
}
void WriteCommBlock(char c)
{
void *txBlk;
DWORD txBlkSize;
static char _c;
DWORD temp;
_c=c;
while(txEmpty==FALSE);
txBlk=&_c;
txBlkSize=1;
//txEmpty=FALSE; why needed??? this line should be removed.
#if IS_OVERLAPPED_IO
WriteFile(idComDev,txBlk,txBlkSize,&temp,&osWrite);
#else
WriteFile(idComDev,txBlk,txBlkSize,&temp,NULL);
#endif
while(txEmpty==FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -