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>
#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"\\\\.\\") {
+15 -9
View File
@@ -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;
+6 -1
View File
@@ -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();