我有两个线程,一个调用WriteFile,另一个调用ReadFile,两个都在115200使用相同的串口。我反复发现的是,当我在写线程中添加更多顺序WriteFile调用时,是我有一个检查和失败次数增加,即数据损坏。如果我在写入线程中使用WriteFile调用之间添加延迟(使用CBaseDLIMessage :: CrossSleep(20)),则校验和错误会减少甚至完全消失(取决于休眠时间),但是在添加其他内容时会出现问题WriteFile方法。
WriteFile方法是否有可能以某种方式将数据写入共享缓冲区,共享缓冲区也用于读取(在驱动程序级别),随后会破坏我的读取数据?
我的串口设置代码如下所示:
CommHandle OpenSerialPort(int nId, long baud)
{
#if defined(USE_WINDOWS_SERIAL_PORT_LIB)
char szCOM[16];
/* COM waiting */
COMMTIMEOUTS g_cto =
{
MAXDWORD, /* ReadIntervalTimeOut */
0, /* ReadTotalTimeOutMultiplier */
0, /* ReadTotalTimeOutConstant */
0, /* WriteTotalTimeOutMultiplier */
0 /* WriteTotalTimeOutConstant */
};
/* COM configuration */
DCB g_dcb =
{
sizeof(DCB), /* DCBlength */
baud, /* BaudRate */
TRUE, /* fBinary */
FALSE, /* fParity */
FALSE, /* fOutxCtsFlow */
FALSE, /* fOutxDsrFlow */
DTR_CONTROL_DISABLE, /* fDtrControl */
FALSE, /* fDsrSensitivity */
FALSE, /* fTXContinueOnXoff */
FALSE, /* fOutX */
FALSE, /* fInX */
FALSE, /* fErrorChar */
FALSE, /* fNull */
RTS_CONTROL_DISABLE, /* fRtsControl */
FALSE, /* fAbortOnError */
0, /* fDummy2 */
0, /* wReserved */
0x100, /* XonLim */
0x100, /* XoffLim */
8, /* ByteSize */
NOPARITY, /* Parity */
ONESTOPBIT, /* StopBits */
0x11, /* XonChar */
0x13, /* XoffChar */
'?', /* ErrorChar */
0x1A, /* EofChar */
0x10 /* EvtChar */
};
//cout << "COM:::" << nId;
sprintf(szCOM, "\\\\.\\COM%d", nId);
HANDLE hCOM = CreateFile(szCOM, /* lpFileName */
GENERIC_READ|GENERIC_WRITE, /* dwDesiredAccess */
0, /* dwShareMode */
NULL, /* lpSecurityAttributes */
OPEN_EXISTING, /* dwCreationDisposition */
FILE_ATTRIBUTE_SYSTEM, /* dwFlagsAndAttributes */
NULL); /* hTemplateFile */
//std::cout << "COM: " << (int)nId << "\n";
if(hCOM == INVALID_HANDLE_VALUE)
{
//std::cout << "INVALID_HANDLE_VALUE \n" ;
DWORD err = GetLastError();
if (err == ERROR_FILE_NOT_FOUND)
{
std::cout << "Error: Failed to open COM[" << nId << "]\n";
}
else if(err == ERROR_INVALID_NAME)
{
std::cout << "\nError: \n%s 'filename, directory name, or volume label syntax is incorrect'\n"; //error code 0x7B
}
else
{
//cout << "\nHandle creation error code: %x\n" << err;
}
return 0;
}
else
{
std::cout << "COM[" << nId << "] OPEN. Baud: " << baud <<"\n";
}
// COM buffer size
SetupComm(hCOM, RX_SIZE, TX_SIZE);
// COM config
if(!SetCommTimeouts(hCOM, &g_cto) || !SetCommState(hCOM, &g_dcb))
{
CloseHandle(hCOM);
return 0;
}
// COM buffer purge
PurgeComm(hCOM, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
EscapeCommFunction(hCOM, SETDTR);
return hCOM;
#else
wxSerialPort *pwxSerialPort = new wxSerialPort();
char szPort[32];
sprintf(szPort,"com%d", nId);
if(pwxSerialPort->Open(szPort) < 0) {
return 0;
}
// set the baudrate
pwxSerialPort->SetBaudRate((wxBaud)baud);
return pwxSerialPort;
#endif
}
int CloseSerialPort(CommHandle hSerialPort)
{
#if defined(USE_WINDOWS_SERIAL_PORT_LIB)
CloseHandle(hSerialPort);
return 1;
#else
hSerialPort->Close();
delete hSerialPort;
return 1;
#endif
}
int WriteDataToSerialPort(CommHandle hSerialPort, void *pMsg, unsigned short messageLength, unsigned int *pBytesWritten)
{
*pBytesWritten = 0;
if(hSerialPort == 0)
{
//cout << "hSerialPort ====== 0";
return -1;
}
#if defined(USE_WINDOWS_SERIAL_PORT_LIB)
return WriteFile(hSerialPort, (char*)pMsg, messageLength, (DWORD*)pBytesWritten, NULL);
#else
*pBytesWritten = hSerialPort->Write((char*)pMsg, messageLength);
return 1;
#endif
}
int ReadDataFromSerialPort(CommHandle hSerialPort, void *pMsg, unsigned short messageLength, unsigned int *pBytesRead)
{
unsigned short i;
*pBytesRead = 0;
i = 0;
if(hSerialPort == 0)
{
return -1;
}
#if defined(USE_WINDOWS_SERIAL_PORT_LIB)
return ReadFile(hSerialPort, (char*)pMsg, messageLength, (DWORD*)pBytesRead, NULL);
#else
*pBytesRead = hSerialPort->Read((char*)pMsg, messageLength);
return 1;
#endif
}
答案 0 :(得分:0)
通过串口通讯速度很慢。
您应该使用WriteFileEx而不是WriteFile。
您可以指定在写入(传输)完成或失败时可以执行的例程。 如果在执行该例程后写入下一个数据,则可能不会发生数据溢出。