better error handling, mctor and cctor

This commit is contained in:
Leonetienne
2025-12-07 19:42:06 +01:00
parent 635a07e2bf
commit f745d0db8a
3 changed files with 72 additions and 24 deletions
+51 -14
View File
@@ -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
View File
@@ -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
View File
@@ -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();