better error handling, mctor and cctor
This commit is contained in:
+51
-14
@@ -2,13 +2,14 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate):
|
OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate) noexcept:
|
||||||
comPort(comPort),
|
comPort(comPort),
|
||||||
baudRate(baudRate)
|
baudRate(baudRate)
|
||||||
{
|
{
|
||||||
serialHandle = CreateFile(normalizePort(comPort).c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
serialHandle = CreateFileW(normalizePort(comPort).c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
if (!serialHandle) {
|
if (serialHandle == INVALID_HANDLE_VALUE) {
|
||||||
std::wcerr << L"Unable to open serial port file " << normalizePort(comPort) << L"!" << std::endl;
|
DWORD err = GetLastError();
|
||||||
|
std::wcerr << L"Unable to open serial port file " << normalizePort(comPort) << L"! Error: " << (int)err << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,14 +17,28 @@ OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate):
|
|||||||
serialParams.DCBlength = sizeof(serialParams);
|
serialParams.DCBlength = sizeof(serialParams);
|
||||||
|
|
||||||
if (!GetCommState(serialHandle, &serialParams)) {
|
if (!GetCommState(serialHandle, &serialParams)) {
|
||||||
std::wcerr << L"Unable to get comm state of port " << normalizePort(comPort) << L"! Is the port busy?" << std::endl;
|
DWORD err = GetLastError();
|
||||||
|
std::wcerr << L"Unable to get comm state of port " << normalizePort(comPort) << L"! Is the port busy? Error: " << (int)err << std::endl;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
serialParams.BaudRate = baudRate;
|
serialParams.BaudRate = baudRate;
|
||||||
|
serialParams.ByteSize = 8;
|
||||||
|
serialParams.Parity = NOPARITY;
|
||||||
|
serialParams.StopBits = ONESTOPBIT;
|
||||||
|
serialParams.fParity = FALSE;
|
||||||
|
serialParams.fBinary = TRUE;
|
||||||
|
serialParams.fOutxCtsFlow = FALSE;
|
||||||
|
serialParams.fOutxDsrFlow = FALSE;
|
||||||
|
serialParams.fOutX = FALSE;
|
||||||
|
serialParams.fInX = FALSE;
|
||||||
|
serialParams.fRtsControl = RTS_CONTROL_DISABLE;
|
||||||
|
serialParams.fDtrControl = DTR_CONTROL_DISABLE;
|
||||||
|
|
||||||
if (!SetCommState(serialHandle, &serialParams)) {
|
if (!SetCommState(serialHandle, &serialParams)) {
|
||||||
std::wcerr << L"Unable to set comm state of port " << normalizePort(comPort) << L"! Is the port busy?" << std::endl;
|
DWORD err = GetLastError();
|
||||||
|
std::wcerr << L"Unable to set comm state of port " << normalizePort(comPort) << L"! Is the port busy? Error: " << (int)err << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,24 +50,38 @@ OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate):
|
|||||||
timeouts.WriteTotalTimeoutMultiplier = 10;
|
timeouts.WriteTotalTimeoutMultiplier = 10;
|
||||||
|
|
||||||
if (!SetCommTimeouts(serialHandle, &timeouts)) {
|
if (!SetCommTimeouts(serialHandle, &timeouts)) {
|
||||||
std::wcerr << L"Unable to set comm timeouts of port " << normalizePort(comPort) << L"! Is the port busy?" << std::endl;
|
DWORD err = GetLastError();
|
||||||
|
std::wcerr << L"Unable to set comm timeouts of port " << normalizePort(comPort) << L"! Is the port busy? Error: " << (int)err << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
open = true;
|
open = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSerialBus::isOpen() const
|
OSerialBus::OSerialBus(OSerialBus&& other) noexcept:
|
||||||
|
comPort(other.comPort),
|
||||||
|
baudRate(other.baudRate),
|
||||||
|
serialHandle(other.serialHandle),
|
||||||
|
open(other.open)
|
||||||
|
{
|
||||||
|
other.serialHandle = INVALID_HANDLE_VALUE;
|
||||||
|
other.open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSerialBus::isOpen() const noexcept
|
||||||
{
|
{
|
||||||
return open;
|
return open;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSerialBus::close()
|
bool OSerialBus::close() noexcept
|
||||||
{
|
{
|
||||||
|
if (!isOpen()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return CloseHandle(serialHandle);
|
return CloseHandle(serialHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSerialBus::send(const std::string& line)
|
bool OSerialBus::send(const std::string& line) noexcept
|
||||||
{
|
{
|
||||||
// Important: this relies on chartype of line being 1 byte long!
|
// Important: this relies on chartype of line being 1 byte long!
|
||||||
const char* data = line.data();
|
const char* data = line.data();
|
||||||
@@ -75,7 +104,7 @@ bool OSerialBus::send(const std::string& line)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSerialBus::sendl(const std::string& line)
|
bool OSerialBus::sendl(const std::string& line) noexcept
|
||||||
{
|
{
|
||||||
if (!send(line)) {
|
if (!send(line)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -83,17 +112,25 @@ bool OSerialBus::sendl(const std::string& line)
|
|||||||
return send("\n");
|
return send("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int OSerialBus::getBaudRate() const
|
int OSerialBus::getBaudRate() const noexcept
|
||||||
{
|
{
|
||||||
return baudRate;
|
return baudRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::wstring& OSerialBus::getComPort() const
|
const std::wstring& OSerialBus::getComPort() const noexcept
|
||||||
{
|
{
|
||||||
return comPort;
|
return comPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring OSerialBus::normalizePort(const std::wstring& port)
|
OSerialBus& OSerialBus::operator<<(const std::string& in)
|
||||||
|
{
|
||||||
|
if (!send(in)) {
|
||||||
|
throw std::runtime_error("Failed to write to COM port!");
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring OSerialBus::normalizePort(const std::wstring& port) noexcept
|
||||||
{
|
{
|
||||||
// If port string already includes prefix, return as-is
|
// If port string already includes prefix, return as-is
|
||||||
if (port == L"\\\\.\\") {
|
if (port == L"\\\\.\\") {
|
||||||
|
|||||||
+15
-9
@@ -6,20 +6,26 @@ class OSerialBus
|
|||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
public:
|
public:
|
||||||
OSerialBus(const std::wstring& comPort, int baudRate = 9600);
|
OSerialBus(const std::wstring& comPort, int baudRate = 9600) noexcept;
|
||||||
|
OSerialBus(const OSerialBus& other) = delete;
|
||||||
|
OSerialBus(OSerialBus&& other) noexcept;
|
||||||
|
OSerialBus& operator=(const OSerialBus& other) = delete;
|
||||||
|
|
||||||
bool isOpen() const;
|
bool isOpen() const noexcept;
|
||||||
bool close();
|
bool close() noexcept;
|
||||||
bool send(const std::string& line);
|
bool send(const std::string& line) noexcept;
|
||||||
bool sendl(const std::string& line);
|
bool sendl(const std::string& line) noexcept;
|
||||||
|
|
||||||
int getBaudRate() const;
|
int getBaudRate() const noexcept;
|
||||||
const std::wstring& getComPort() const;
|
const std::wstring& getComPort() const noexcept;
|
||||||
|
|
||||||
|
// Alias for send()
|
||||||
|
OSerialBus& operator<<(const std::string& in);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::wstring normalizePort(const std::wstring& port);
|
static std::wstring normalizePort(const std::wstring& port) noexcept;
|
||||||
|
|
||||||
const std::wstring& comPort;
|
const std::wstring comPort;
|
||||||
const int baudRate = 0;
|
const int baudRate = 0;
|
||||||
HANDLE serialHandle;
|
HANDLE serialHandle;
|
||||||
bool open = false;
|
bool open = false;
|
||||||
|
|||||||
+6
-1
@@ -9,7 +9,12 @@ int main()
|
|||||||
std::cerr << "Serial bus is not open! Is the COM port busy?" << std::endl;
|
std::cerr << "Serial bus is not open! Is the COM port busy?" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bus.sendl("MA 1 120");
|
|
||||||
|
if (!bus.send("MA 1 60\n")) {
|
||||||
|
std::cerr << "Could not send command!" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bus.close();
|
bus.close();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user