mirror of
https://github.com/wjwwood/serial.git
synced 2026-01-22 19:54:57 +08:00
Merge 02654f03eb1a2342d3fdd513bd2c95108434be42 into 69e0372cf0d3796e84ce9a09aff1d74496f68720
This commit is contained in:
commit
d64df04f11
@ -198,6 +198,7 @@ private:
|
|||||||
HANDLE read_mutex;
|
HANDLE read_mutex;
|
||||||
// Mutex used to lock the write functions
|
// Mutex used to lock the write functions
|
||||||
HANDLE write_mutex;
|
HANDLE write_mutex;
|
||||||
|
OVERLAPPED overlapped_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,8 @@ Serial::SerialImpl::SerialImpl (const string &port, unsigned long baudrate,
|
|||||||
open ();
|
open ();
|
||||||
read_mutex = CreateMutex(NULL, false, NULL);
|
read_mutex = CreateMutex(NULL, false, NULL);
|
||||||
write_mutex = CreateMutex(NULL, false, NULL);
|
write_mutex = CreateMutex(NULL, false, NULL);
|
||||||
|
memset(&overlapped_, 0x00, sizeof(overlapped_));
|
||||||
|
overlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial::SerialImpl::~SerialImpl ()
|
Serial::SerialImpl::~SerialImpl ()
|
||||||
@ -50,6 +52,7 @@ Serial::SerialImpl::~SerialImpl ()
|
|||||||
this->close();
|
this->close();
|
||||||
CloseHandle(read_mutex);
|
CloseHandle(read_mutex);
|
||||||
CloseHandle(write_mutex);
|
CloseHandle(write_mutex);
|
||||||
|
CloseHandle(overlapped_.hEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -70,7 +73,7 @@ Serial::SerialImpl::open ()
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (fd_ == INVALID_HANDLE_VALUE) {
|
if (fd_ == INVALID_HANDLE_VALUE) {
|
||||||
@ -279,6 +282,8 @@ Serial::SerialImpl::close ()
|
|||||||
{
|
{
|
||||||
if (is_open_ == true) {
|
if (is_open_ == true) {
|
||||||
if (fd_ != INVALID_HANDLE_VALUE) {
|
if (fd_ != INVALID_HANDLE_VALUE) {
|
||||||
|
SetCommMask(fd_, 0);
|
||||||
|
ResetEvent(overlapped_.hEvent);
|
||||||
int ret;
|
int ret;
|
||||||
ret = CloseHandle(fd_);
|
ret = CloseHandle(fd_);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@ -315,16 +320,60 @@ Serial::SerialImpl::available ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Serial::SerialImpl::waitReadable (uint32_t /*timeout*/)
|
Serial::SerialImpl::waitReadable (uint32_t timeout)
|
||||||
{
|
{
|
||||||
THROW (IOException, "waitReadable is not implemented on Windows.");
|
COMSTAT cs;
|
||||||
|
DWORD error;
|
||||||
|
DWORD old_msk, msk, length;
|
||||||
|
|
||||||
|
if (!isOpen()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetCommMask(fd_, &old_msk)) {
|
||||||
|
stringstream ss;
|
||||||
|
ss << "Error while get mask of the serial port: " << GetLastError();
|
||||||
|
THROW(IOException, ss.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
msk = 0;
|
||||||
|
SetCommMask(fd_, EV_RXCHAR | EV_ERR);
|
||||||
|
if (!WaitCommEvent(fd_, &msk, &overlapped_)) {
|
||||||
|
if (GetLastError() == ERROR_IO_PENDING) {
|
||||||
|
if (WaitForSingleObject(overlapped_.hEvent, (DWORD)timeout) == WAIT_TIMEOUT) {
|
||||||
|
SetCommMask(fd_, old_msk);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetOverlappedResult(fd_, &overlapped_, &length, TRUE);
|
||||||
|
::ResetEvent(overlapped_.hEvent);
|
||||||
|
} else {
|
||||||
|
ClearCommError(fd_, &error, &cs);
|
||||||
|
SetCommMask(fd_, old_msk);
|
||||||
|
return cs.cbInQue > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCommMask(fd_, old_msk);
|
||||||
|
if (msk & EV_ERR) {
|
||||||
|
ClearCommError(fd_, &error, &cs);
|
||||||
|
return cs.cbInQue > 0;
|
||||||
|
}
|
||||||
|
if (msk & EV_RXCHAR) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::waitByteTimes (size_t /*count*/)
|
Serial::SerialImpl::waitByteTimes (size_t count)
|
||||||
{
|
{
|
||||||
THROW (IOException, "waitByteTimes is not implemented on Windows.");
|
DWORD wait_time = timeout_.inter_byte_timeout * count;
|
||||||
|
HANDLE wait_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
ResetEvent(wait_event);
|
||||||
|
WaitForSingleObject(wait_event, wait_time);
|
||||||
|
CloseHandle(wait_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
@ -334,11 +383,13 @@ Serial::SerialImpl::read (uint8_t *buf, size_t size)
|
|||||||
throw PortNotOpenedException ("Serial::read");
|
throw PortNotOpenedException ("Serial::read");
|
||||||
}
|
}
|
||||||
DWORD bytes_read;
|
DWORD bytes_read;
|
||||||
if (!ReadFile(fd_, buf, static_cast<DWORD>(size), &bytes_read, NULL)) {
|
overlapped_.Offset = 0;
|
||||||
stringstream ss;
|
overlapped_.OffsetHigh = 0;
|
||||||
ss << "Error while reading from the serial port: " << GetLastError();
|
if (!ReadFile(fd_, buf, static_cast<DWORD>(size), NULL, &overlapped_)) {
|
||||||
THROW (IOException, ss.str().c_str());
|
WaitForSingleObject(overlapped_.hEvent, timeout_.read_timeout_constant);
|
||||||
}
|
}
|
||||||
|
GetOverlappedResult(fd_, &overlapped_, &bytes_read, TRUE);
|
||||||
|
::ResetEvent(overlapped_.hEvent);
|
||||||
return (size_t) (bytes_read);
|
return (size_t) (bytes_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,11 +400,13 @@ Serial::SerialImpl::write (const uint8_t *data, size_t length)
|
|||||||
throw PortNotOpenedException ("Serial::write");
|
throw PortNotOpenedException ("Serial::write");
|
||||||
}
|
}
|
||||||
DWORD bytes_written;
|
DWORD bytes_written;
|
||||||
if (!WriteFile(fd_, data, static_cast<DWORD>(length), &bytes_written, NULL)) {
|
overlapped_.Offset = 0;
|
||||||
stringstream ss;
|
overlapped_.OffsetHigh = 0;
|
||||||
ss << "Error while writing to the serial port: " << GetLastError();
|
if (!WriteFile(fd_, data, static_cast<DWORD>(length), NULL, &overlapped_)) {
|
||||||
THROW (IOException, ss.str().c_str());
|
WaitForSingleObject(overlapped_.hEvent, timeout_.write_timeout_constant);
|
||||||
}
|
}
|
||||||
|
GetOverlappedResult(fd_, &overlapped_, &bytes_written, TRUE);
|
||||||
|
::ResetEvent(overlapped_.hEvent);
|
||||||
return (size_t) (bytes_written);
|
return (size_t) (bytes_written);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +427,17 @@ Serial::SerialImpl::setTimeout (serial::Timeout &timeout)
|
|||||||
{
|
{
|
||||||
timeout_ = timeout;
|
timeout_ = timeout;
|
||||||
if (is_open_) {
|
if (is_open_) {
|
||||||
reconfigurePort ();
|
//reconfigurePort ();
|
||||||
|
// Setup timeouts
|
||||||
|
COMMTIMEOUTS timeouts = { 0 };
|
||||||
|
timeouts.ReadIntervalTimeout = timeout_.inter_byte_timeout;
|
||||||
|
timeouts.ReadTotalTimeoutConstant = timeout_.read_timeout_constant;
|
||||||
|
timeouts.ReadTotalTimeoutMultiplier = timeout_.read_timeout_multiplier;
|
||||||
|
timeouts.WriteTotalTimeoutConstant = timeout_.write_timeout_constant;
|
||||||
|
timeouts.WriteTotalTimeoutMultiplier = timeout_.write_timeout_multiplier;
|
||||||
|
if (!SetCommTimeouts(fd_, &timeouts)) {
|
||||||
|
THROW(IOException, "Error setting timeouts.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user