From f745d0db8a5369fc8e2f5091150d7948ee22a1f4 Mon Sep 17 00:00:00 2001 From: Leonetienne Date: Sun, 7 Dec 2025 19:42:06 +0100 Subject: [PATCH] better error handling, mctor and cctor --- MotionCore/OSerialBus.cpp | 65 ++++++++++++++++++++++++++++++--------- MotionCore/OSerialBus.h | 24 +++++++++------ MotionCore/main.cpp | 7 ++++- 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/MotionCore/OSerialBus.cpp b/MotionCore/OSerialBus.cpp index c235eb7..09ef234 100755 --- a/MotionCore/OSerialBus.cpp +++ b/MotionCore/OSerialBus.cpp @@ -2,13 +2,14 @@ #include #ifdef WINDOWS -OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate): +OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate) noexcept: comPort(comPort), baudRate(baudRate) { - serialHandle = CreateFile(normalizePort(comPort).c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (!serialHandle) { - std::wcerr << L"Unable to open serial port file " << normalizePort(comPort) << L"!" << std::endl; + serialHandle = CreateFileW(normalizePort(comPort).c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (serialHandle == INVALID_HANDLE_VALUE) { + DWORD err = GetLastError(); + std::wcerr << L"Unable to open serial port file " << normalizePort(comPort) << L"! Error: " << (int)err << std::endl; return; } @@ -16,14 +17,28 @@ OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate): serialParams.DCBlength = sizeof(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; } 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)) { - 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; } @@ -35,24 +50,38 @@ OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate): timeouts.WriteTotalTimeoutMultiplier = 10; 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; } 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; } -bool OSerialBus::close() +bool OSerialBus::close() noexcept { + if (!isOpen()) { + return true; + } 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! const char* data = line.data(); @@ -75,7 +104,7 @@ bool OSerialBus::send(const std::string& line) return true; } -bool OSerialBus::sendl(const std::string& line) +bool OSerialBus::sendl(const std::string& line) noexcept { if (!send(line)) { return false; @@ -83,17 +112,25 @@ bool OSerialBus::sendl(const std::string& line) return send("\n"); } -int OSerialBus::getBaudRate() const +int OSerialBus::getBaudRate() const noexcept { return baudRate; } -const std::wstring& OSerialBus::getComPort() const +const std::wstring& OSerialBus::getComPort() const noexcept { 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 == L"\\\\.\\") { diff --git a/MotionCore/OSerialBus.h b/MotionCore/OSerialBus.h index fe20327..b42610f 100755 --- a/MotionCore/OSerialBus.h +++ b/MotionCore/OSerialBus.h @@ -6,20 +6,26 @@ class OSerialBus { #ifdef WINDOWS 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 close(); - bool send(const std::string& line); - bool sendl(const std::string& line); + bool isOpen() const noexcept; + bool close() noexcept; + bool send(const std::string& line) noexcept; + bool sendl(const std::string& line) noexcept; - int getBaudRate() const; - const std::wstring& getComPort() const; + int getBaudRate() const noexcept; + const std::wstring& getComPort() const noexcept; + + // Alias for send() + OSerialBus& operator<<(const std::string& in); 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; HANDLE serialHandle; bool open = false; diff --git a/MotionCore/main.cpp b/MotionCore/main.cpp index d836d4d..c3ec6bd 100755 --- a/MotionCore/main.cpp +++ b/MotionCore/main.cpp @@ -9,7 +9,12 @@ int main() std::cerr << "Serial bus is not open! Is the COM port busy?" << std::endl; 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();