Use normal blocking file functions for Windows serial I/O.

This commit is contained in:
Jonathan Naylor 2017-03-13 19:35:29 +00:00
parent d2660376f3
commit 84f4418bde
2 changed files with 24 additions and 56 deletions

View file

@ -44,9 +44,7 @@ CSerialController::CSerialController(const std::string& device, SERIAL_SPEED spe
m_device(device), m_device(device),
m_speed(speed), m_speed(speed),
m_assertRTS(assertRTS), m_assertRTS(assertRTS),
m_handle(INVALID_HANDLE_VALUE), m_handle(INVALID_HANDLE_VALUE)
m_readOverlapped(),
m_writeOverlapped()
{ {
assert(!device.empty()); assert(!device.empty());
} }
@ -63,7 +61,7 @@ bool CSerialController::open()
std::string baseName = m_device.substr(4U); // Convert "\\.\COM10" to "COM10" std::string baseName = m_device.substr(4U); // Convert "\\.\COM10" to "COM10"
m_handle = ::CreateFileA(m_device.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); m_handle = ::CreateFileA(m_device.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (m_handle == INVALID_HANDLE_VALUE) { if (m_handle == INVALID_HANDLE_VALUE) {
LogError("Cannot open device - %s, err=%04lx", m_device.c_str(), ::GetLastError()); LogError("Cannot open device - %s, err=%04lx", m_device.c_str(), ::GetLastError());
return false; return false;
@ -131,12 +129,6 @@ bool CSerialController::open()
::ClearCommError(m_handle, &errCode, NULL); ::ClearCommError(m_handle, &errCode, NULL);
::memset(&m_readOverlapped, 0x00U, sizeof(OVERLAPPED));
::memset(&m_writeOverlapped, 0x00U, sizeof(OVERLAPPED));
m_readOverlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
m_writeOverlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
return true; return true;
} }
@ -170,38 +162,28 @@ int CSerialController::readNonblock(unsigned char* buffer, unsigned int length)
if (length == 0U) if (length == 0U)
return 0; return 0;
DWORD errors; DWORD errors;
COMSTAT status; COMSTAT status;
if (::ClearCommError(m_handle, &errors, &status) == 0) { if (::ClearCommError(m_handle, &errors, &status) == 0) {
LogError("Error from ClearCommError for %s, err=%04lx", m_device.c_str(), ::GetLastError()); LogError("Error from ClearCommError for %s, err=%04lx", m_device.c_str(), ::GetLastError());
return -1;
}
if (status.cbInQue == 0UL)
return 0;
DWORD readLength = status.cbInQue;
if (length < status.cbInQue)
readLength = length;
DWORD bytes = 0UL;
BOOL res = ::ReadFile(m_handle, buffer, readLength, &bytes, &m_readOverlapped);
if (res)
return int(bytes);
DWORD error = ::GetLastError();
if (error != ERROR_IO_PENDING) {
LogError("Error from ReadFile for %s: %04lx", m_device.c_str(), error);
return -1; return -1;
} }
DWORD ret = ::WaitForSingleObject(m_readOverlapped.hEvent, 100UL); if (status.cbInQue == 0UL)
if (ret != WAIT_OBJECT_0) { return 0;
LogError("Error from WaitForSIngleObject for %s: %04lx", m_device.c_str(), ret);
return -1;
}
return int(bytes); DWORD readLength = status.cbInQue;
if (length < readLength)
readLength = length;
DWORD bytes = 0UL;
BOOL ret = ::ReadFile(m_handle, buffer, readLength, &bytes, NULL);
if (!ret) {
LogError("Error from ReadFile for %s: %04lx", m_device.c_str(), ::GetLastError());
return -1;
}
return int(bytes);
} }
int CSerialController::write(const unsigned char* buffer, unsigned int length) int CSerialController::write(const unsigned char* buffer, unsigned int length)
@ -216,19 +198,10 @@ int CSerialController::write(const unsigned char* buffer, unsigned int length)
while (ptr < length) { while (ptr < length) {
DWORD bytes = 0UL; DWORD bytes = 0UL;
BOOL res = ::WriteFile(m_handle, buffer + ptr, length - ptr, &bytes, &m_writeOverlapped); BOOL ret = ::WriteFile(m_handle, buffer + ptr, length - ptr, &bytes, NULL);
if (!res) { if (!ret) {
DWORD error = ::GetLastError(); LogError("Error from WriteFile for %s: %04lx", m_device.c_str(), ::GetLastError());
if (error != ERROR_IO_PENDING) { return -1;
LogError("Error from WriteFile for %s: %04lx", m_device.c_str(), error);
return -1;
}
res = ::GetOverlappedResult(m_handle, &m_writeOverlapped, &bytes, TRUE);
if (!res) {
LogError("Error from GetOverlappedResult for %s: %04lx", m_device.c_str(), ::GetLastError());
return -1;
}
} }
ptr += bytes; ptr += bytes;
@ -243,9 +216,6 @@ void CSerialController::close()
::CloseHandle(m_handle); ::CloseHandle(m_handle);
m_handle = INVALID_HANDLE_VALUE; m_handle = INVALID_HANDLE_VALUE;
::CloseHandle(m_readOverlapped.hEvent);
::CloseHandle(m_writeOverlapped.hEvent);
} }
#else #else

View file

@ -59,8 +59,6 @@ private:
bool m_assertRTS; bool m_assertRTS;
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
HANDLE m_handle; HANDLE m_handle;
OVERLAPPED m_readOverlapped;
OVERLAPPED m_writeOverlapped;
#else #else
int m_fd; int m_fd;
#endif #endif