From dff0a10c8d3b33cabd334c1566cd5abfd0ddb8e4 Mon Sep 17 00:00:00 2001 From: Peter M. Groen Date: Tue, 24 May 2022 23:22:53 +0200 Subject: [PATCH] Implementation of a serial port library. --- .dep.inc | 5 +++++ .gitignore | 2 ++ Exception.hpp | 30 ++++++++++++++++++++++++++++++ Makefile | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SerialPort.cpp | 677 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SerialPort.hpp | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.cpp | 36 ++++++++++++++++++++++++++++++++++++ nbproject/Makefile-Debug.mk | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nbproject/Makefile-Release.mk | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nbproject/Makefile-impl.mk | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nbproject/Makefile-variables.mk | 35 +++++++++++++++++++++++++++++++++++ nbproject/Package-Debug.bash | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nbproject/Package-Release.bash | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nbproject/configurations.xml | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nbproject/private/Makefile-variables.mk | 7 +++++++ nbproject/private/c_standard_headers_indexer.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nbproject/private/configurations.xml | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nbproject/private/cpp_standard_headers_indexer.cpp | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nbproject/private/launcher.properties | 42 ++++++++++++++++++++++++++++++++++++++++++ nbproject/private/private.xml | 15 +++++++++++++++ nbproject/project.properties | 1 + nbproject/project.xml | 28 ++++++++++++++++++++++++++++ 22 files changed, 2060 insertions(+), 0 deletions(-) create mode 100644 .dep.inc create mode 100644 .gitignore create mode 100644 Exception.hpp create mode 100644 Makefile create mode 100644 SerialPort.cpp create mode 100644 SerialPort.hpp create mode 100644 main.cpp create mode 100644 nbproject/Makefile-Debug.mk create mode 100644 nbproject/Makefile-Release.mk create mode 100644 nbproject/Makefile-impl.mk create mode 100644 nbproject/Makefile-variables.mk create mode 100644 nbproject/Package-Debug.bash create mode 100644 nbproject/Package-Release.bash create mode 100644 nbproject/configurations.xml create mode 100644 nbproject/private/Makefile-variables.mk create mode 100644 nbproject/private/c_standard_headers_indexer.c create mode 100644 nbproject/private/configurations.xml create mode 100644 nbproject/private/cpp_standard_headers_indexer.cpp create mode 100644 nbproject/private/launcher.properties create mode 100644 nbproject/private/private.xml create mode 100644 nbproject/project.properties create mode 100644 nbproject/project.xml diff --git a/.dep.inc b/.dep.inc new file mode 100644 index 0000000..38ba445 --- /dev/null +++ b/.dep.inc @@ -0,0 +1,5 @@ +# This code depends on make tool being used +DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES} ${TESTOBJECTFILES})) +ifneq (${DEPFILES},) +include ${DEPFILES} +endif diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..95832e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/build/ +/dist/ \ No newline at end of file diff --git a/Exception.hpp b/Exception.hpp new file mode 100644 index 0000000..1126843 --- /dev/null +++ b/Exception.hpp @@ -0,0 +1,30 @@ +#pragma once + +// System includes +#include +#include +#include +#include + + +class Exception : public std::runtime_error +{ +public: + Exception(const char *file, int line, const std::string &arg) + : std::runtime_error(arg) + { + msg_ = std::string(file) + ":" + std::to_string(line) + ": " + arg; + } + + ~Exception() throw() {} + + const char *what() const throw() override + { + return msg_.c_str(); + } + +private: + std::string msg_; +}; + +#define THROW_EXCEPT(arg) throw Exception(__FILE__, __LINE__, arg); diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..05de621 --- /dev/null +++ b/Makefile @@ -0,0 +1,128 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_PLATFORM_${CONF} platform name (current configuration) +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin + + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# build tests +build-tests: .build-tests-post + +.build-tests-pre: +# Add your pre 'build-tests' code here... + +.build-tests-post: .build-tests-impl +# Add your post 'build-tests' code here... + + +# run tests +test: .test-post + +.test-pre: build-tests +# Add your pre 'test' code here... + +.test-post: .test-impl +# Add your post 'test' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/SerialPort.cpp b/SerialPort.cpp new file mode 100644 index 0000000..3abbd6c --- /dev/null +++ b/SerialPort.cpp @@ -0,0 +1,677 @@ +// System includes +#include +#include +#include // Standard input/output definitions +#include // String function definitions +#include // UNIX standard function definitions +#include // File control definitions +#include // Error number definitions +// #include // POSIX terminal control definitions (struct termios) +#include // For throwing std::system_error +#include // Used for TCGETS2, which is required for custom baud rates +#include +// #include // Terminal control definitions (struct termios) +#include +#include +#include +#include + +// User includes +#include "Exception.hpp" +#include "SerialPort.hpp" + +#define BOTHER 0010000 + +SerialPort::SerialPort() +{ + echo_ = false; + timeout_ms_ = defaultTimeout_ms_; + baudRateType_ = BaudRateType::STANDARD; + baudRateStandard_ = defaultBaudRate_; + readBufferSize_B_ = defaultReadBufferSize_B_; + readBuffer_.reserve(readBufferSize_B_); + state_ = State::CLOSED; +} + +SerialPort::SerialPort(const std::string& device, BaudRate baudRate) + : SerialPort() +{ + device_ = device; + baudRateType_ = BaudRateType::STANDARD; + baudRateStandard_ = baudRate; +} + +SerialPort::SerialPort(const std::string& device, speed_t baudRate) + : SerialPort() +{ + device_ = device; + baudRateType_ = BaudRateType::CUSTOM; + baudRateCustom_ = baudRate; +} + +SerialPort::SerialPort( + const std::string& device, + BaudRate baudRate, + NumDataBits numDataBits, + Parity parity, + NumStopBits numStopBits) + : SerialPort() +{ + device_ = device; + baudRateType_ = BaudRateType::STANDARD; + baudRateStandard_ = baudRate; + numDataBits_ = numDataBits; + parity_ = parity; + numStopBits_ = numStopBits; +} + +SerialPort::~SerialPort() +{ + try + { + Close(); + } + catch(...) + { + // We can't do anything about this! + // But we don't want to throw within destructor, so swallow + } +} + +void SerialPort::SetDevice(const std::string& device) +{ + device_ = device; + if(state_ == State::OPEN) + ConfigureTermios(); +} + +void SerialPort::SetBaudRate(BaudRate baudRate) +{ + baudRateType_ = BaudRateType::STANDARD; + baudRateStandard_ = baudRate; + if(state_ == State::OPEN) + ConfigureTermios(); +} + +void SerialPort::SetBaudRate(speed_t baudRate) +{ + baudRateType_ = BaudRateType::CUSTOM; + baudRateCustom_ = baudRate; + if(state_ == State::OPEN) + ConfigureTermios(); +} + +void SerialPort::SetNumDataBits(NumDataBits numDataBits) +{ + numDataBits_ = numDataBits; + if(state_ == State::OPEN) + ConfigureTermios(); +} + +void SerialPort::SetParity(Parity parity) +{ + parity_ = parity; + if(state_ == State::OPEN) + ConfigureTermios(); +} + +void SerialPort::SetNumStopBits(NumStopBits numStopBits) +{ + numStopBits_ = numStopBits; + if(state_ == State::OPEN) + ConfigureTermios(); +} + +void SerialPort::Open() +{ + if(device_.empty()) + { + THROW_EXCEPT("Attempted to open file when file path has not been assigned to."); + } + + // Attempt to open file + //this->fileDesc = open(this->filePath, O_RDWR | O_NOCTTY | O_NDELAY); + + // O_RDONLY for read-only, O_WRONLY for write only, O_RDWR for both read/write access + // 3rd, optional parameter is mode_t mode + fileDesc_ = open(device_.c_str(), O_RDWR); + + // Check status + if(fileDesc_ == -1) + { + THROW_EXCEPT("Could not open device " + device_ + ". Is the device name correct and do you have read/write permission?"); + } + + ConfigureTermios(); + + // std::cout << "COM port opened successfully." << std::endl; + state_ = State::OPEN; +} + +void SerialPort::SetEcho(bool value) +{ + echo_ = value; + ConfigureTermios(); +} + +void SerialPort::ConfigureTermios() +{ + // std::cout << "Configuring COM port \"" << device_ << "\"." << std::endl; + //================== CONFIGURE ==================// + + // termios tty = GetTermios(); + termios2 tty = GetTermios2(); + + //================= (.c_cflag) ===============// + + // Set num. data bits + // See https://man7.org/linux/man-pages/man3/tcflush.3.html + tty.c_cflag &= ~CSIZE; // CSIZE is a mask for the number of bits per character + switch(numDataBits_) + { + case NumDataBits::FIVE: + tty.c_cflag |= CS5; + break; + case NumDataBits::SIX: + tty.c_cflag |= CS6; + break; + case NumDataBits::SEVEN: + tty.c_cflag |= CS7; + break; + case NumDataBits::EIGHT: + tty.c_cflag |= CS8; + break; + default: + THROW_EXCEPT("numDataBits_ value not supported!"); + } + + // Set parity + // See https://man7.org/linux/man-pages/man3/tcflush.3.html + switch(parity_) + { + case Parity::NONE: + tty.c_cflag &= ~PARENB; + break; + case Parity::EVEN: + tty.c_cflag |= PARENB; + tty.c_cflag &= ~PARODD; // Clearing PARODD makes the parity even + break; + case Parity::ODD: + tty.c_cflag |= PARENB; + tty.c_cflag |= PARODD; + break; + default: + THROW_EXCEPT("parity_ value not supported!"); + + } + + // Set num. stop bits + switch(numStopBits_) + { + case NumStopBits::ONE: + tty.c_cflag &= ~CSTOPB; + break; + case NumStopBits::TWO: + tty.c_cflag |= CSTOPB; + break; + default: + THROW_EXCEPT("numStopBits_ value not supported!"); + } + + tty.c_cflag &= ~CRTSCTS; // Disable hadrware flow control (RTS/CTS) + tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1) + + +//===================== BAUD RATE =================// + + // We used to use cfsetispeed() and cfsetospeed() with the B... macros, but this didn't allow + // us to set custom baud rates. So now to support both standard and custom baud rates lets + // just make everything "custom". This giant switch statement could be replaced with a map/lookup + // in the future + if (baudRateType_ == BaudRateType::STANDARD) + { + tty.c_cflag &= ~CBAUD; + tty.c_cflag |= CBAUDEX; + switch(baudRateStandard_) + { + case BaudRate::B_0: + // cfsetispeed(&tty, B0); + // cfsetospeed(&tty, B0); + tty.c_ispeed = 0; + tty.c_ospeed = 0; + break; + case BaudRate::B_50: + // cfsetispeed(&tty, B50); + // cfsetospeed(&tty, B50); + tty.c_ispeed = 50; + tty.c_ospeed = 50; + break; + case BaudRate::B_75: + // cfsetispeed(&tty, B75); + // cfsetospeed(&tty, B75); + tty.c_ispeed = 75; + tty.c_ospeed = 75; + break; + case BaudRate::B_110: + // cfsetispeed(&tty, B110); + // cfsetospeed(&tty, B110); + tty.c_ispeed = 110; + tty.c_ospeed = 110; + break; + case BaudRate::B_134: + // cfsetispeed(&tty, B134); + // cfsetospeed(&tty, B134); + tty.c_ispeed = 134; + tty.c_ospeed = 134; + break; + case BaudRate::B_150: + // cfsetispeed(&tty, B150); + // cfsetospeed(&tty, B150); + tty.c_ispeed = 150; + tty.c_ospeed = 150; + break; + case BaudRate::B_200: + // cfsetispeed(&tty, B200); + // cfsetospeed(&tty, B200); + tty.c_ispeed = 200; + tty.c_ospeed = 200; + break; + case BaudRate::B_300: + // cfsetispeed(&tty, B300); + // cfsetospeed(&tty, B300); + tty.c_ispeed = 300; + tty.c_ospeed = 300; + break; + case BaudRate::B_600: + // cfsetispeed(&tty, B600); + // cfsetospeed(&tty, B600); + tty.c_ispeed = 600; + tty.c_ospeed = 600; + break; + case BaudRate::B_1200: + // cfsetispeed(&tty, B1200); + // cfsetospeed(&tty, B1200); + tty.c_ispeed = 1200; + tty.c_ospeed = 1200; + break; + case BaudRate::B_1800: + // cfsetispeed(&tty, B1800); + // cfsetospeed(&tty, B1800); + tty.c_ispeed = 1800; + tty.c_ospeed = 1800; + break; + case BaudRate::B_2400: + // cfsetispeed(&tty, B2400); + // cfsetospeed(&tty, B2400); + tty.c_ispeed = 2400; + tty.c_ospeed = 2400; + break; + case BaudRate::B_4800: + // cfsetispeed(&tty, B4800); + // cfsetospeed(&tty, B4800); + tty.c_ispeed = 4800; + tty.c_ospeed = 4800; + break; + case BaudRate::B_9600: + // cfsetispeed(&tty, B9600); + // cfsetospeed(&tty, B9600); + tty.c_ispeed = 9600; + tty.c_ospeed = 9600; + break; + case BaudRate::B_19200: + // cfsetispeed(&tty, B19200); + // cfsetospeed(&tty, B19200); + tty.c_ispeed = 19200; + tty.c_ospeed = 19200; + break; + case BaudRate::B_38400: + // cfsetispeed(&tty, B38400); + // cfsetospeed(&tty, B38400); + tty.c_ispeed = 38400; + tty.c_ospeed = 38400; + break; + case BaudRate::B_57600: + // cfsetispeed(&tty, B57600); + // cfsetospeed(&tty, B57600); + tty.c_ispeed = 57600; + tty.c_ospeed = 57600; + break; + case BaudRate::B_115200: + // cfsetispeed(&tty, B115200); + // cfsetospeed(&tty, B115200); + tty.c_ispeed = 115200; + tty.c_ospeed = 115200; + break; + case BaudRate::B_230400: + // cfsetispeed(&tty, B230400); + // cfsetospeed(&tty, B230400); + tty.c_ispeed = 230400; + tty.c_ospeed = 230400; + break; + case BaudRate::B_460800: + // cfsetispeed(&tty, B460800); + // cfsetospeed(&tty, B460800); + tty.c_ispeed = 460800; + tty.c_ospeed = 460800; + break; + default: + throw std::runtime_error(std::string() + "baudRate passed to " + __PRETTY_FUNCTION__ + " unrecognized."); + } + } + // This does no different than STANDARD atm, but let's keep + // them separate for now.... + else if (baudRateType_ == BaudRateType::CUSTOM) + { + tty.c_cflag &= ~CBAUD; + tty.c_cflag |= CBAUDEX; + // tty.c_cflag |= BOTHER; + tty.c_ispeed = baudRateCustom_; + tty.c_ospeed = baudRateCustom_; + + + // #include + // // configure port to use custom speed instead of 38400 + // struct serial_struct ss; + // ioctl(fileDesc_, TIOCGSERIAL, &ss); + // ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST; + // ss.custom_divisor = (ss.baud_base + (baudRateCustom_ / 2)) / baudRateCustom_; + // int closestSpeed = ss.baud_base / ss.custom_divisor; + + // if (closestSpeed < baudRateCustom_ * 98 / 100 || closestSpeed > baudRateCustom_ * 102 / 100) { + // printf("Cannot set serial port speed to %d. Closest possible is %d\n", baudRateCustom_, closestSpeed); + // } + + // ioctl(fileDesc_, TIOCSSERIAL, &ss); + + // cfsetispeed(&tty, B38400); + // cfsetospeed(&tty, B38400); + } + else + { + // Should never get here, bug in this libraries code! + assert(false); + } + + //===================== (.c_oflag) =================// + + tty.c_oflag = 0; // No remapping, no delays + tty.c_oflag &= ~OPOST; // Make raw + + //================= CONTROL CHARACTERS (.c_cc[]) ==================// + + // c_cc[VTIME] sets the inter-character timer, in units of 0.1s. + // Only meaningful when port is set to non-canonical mode + // VMIN = 0, VTIME = 0: No blocking, return immediately with what is available + // VMIN > 0, VTIME = 0: read() waits for VMIN bytes, could block indefinitely + // VMIN = 0, VTIME > 0: Block until any amount of data is available, OR timeout occurs + // VMIN > 0, VTIME > 0: Block until either VMIN characters have been received, or VTIME + // after first character has elapsed + // c_cc[WMIN] sets the number of characters to block (wait) for when read() is called. + // Set to 0 if you don't want read to block. Only meaningful when port set to non-canonical mode + + if(timeout_ms_ == -1) + { + // Always wait for at least one byte, this could + // block indefinitely + tty.c_cc[VTIME] = 0; + tty.c_cc[VMIN] = 1; + } + else if(timeout_ms_ == 0) + { + // Setting both to 0 will give a non-blocking read + tty.c_cc[VTIME] = 0; + tty.c_cc[VMIN] = 0; + } + else if(timeout_ms_ > 0) + { + tty.c_cc[VTIME] = (cc_t)(timeout_ms_/100); // 0.5 seconds read timeout + tty.c_cc[VMIN] = 0; + } + + //======================== (.c_iflag) ====================// + + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); + + //=========================== LOCAL MODES (c_lflag) =======================// + + // Canonical input is when read waits for EOL or EOF characters before returning. In non-canonical mode, the rate at which + // read() returns is instead controlled by c_cc[VMIN] and c_cc[VTIME] + tty.c_lflag &= ~ICANON; // Turn off canonical input, which is suitable for pass-through + // Configure echo depending on echo_ boolean + if(echo_) + { + tty.c_lflag |= ECHO; + } + else + { + tty.c_lflag &= ~(ECHO); + } + tty.c_lflag &= ~ECHOE; // Turn off echo erase (echo erase only relevant if canonical input is active) + tty.c_lflag &= ~ECHONL; // + tty.c_lflag &= ~ISIG; // Disables recognition of INTR (interrupt), QUIT and SUSP (suspend) characters + + + // Try and use raw function call + //cfmakeraw(&tty); + + // this->SetTermios(tty); + this->SetTermios2(tty); + + /* + // Flush port, then apply attributes + tcflush(this->fileDesc, TCIFLUSH); + + if(tcsetattr(this->fileDesc, TCSANOW, &tty) != 0) + { + // Error occurred + this->sp->PrintError(SmartPrint::Ss() << "Could not apply terminal attributes for \"" << this->filePath << "\" - " << strerror(errno)); + return; + }*/ +} + +void SerialPort::Write(const std::string& data) +{ + + if(state_ != State::OPEN) + THROW_EXCEPT(std::string() + __PRETTY_FUNCTION__ + " called but state != OPEN. Please call Open() first."); + + if(fileDesc_ < 0) + { + THROW_EXCEPT(std::string() + __PRETTY_FUNCTION__ + " called but file descriptor < 0, indicating file has not been opened."); + } + + int writeResult = write(fileDesc_, data.c_str(), data.size()); + + // Check status + if (writeResult == -1) + { + throw std::system_error(EFAULT, std::system_category()); + } +} + +void SerialPort::WriteBinary( const std::vector& data ) +{ + + if(state_ != State::OPEN) + THROW_EXCEPT(std::string() + __PRETTY_FUNCTION__ + " called but state != OPEN. Please call Open() first."); + + if(fileDesc_ < 0) + { + THROW_EXCEPT(std::string() + __PRETTY_FUNCTION__ + " called but file descriptor < 0, indicating file has not been opened."); + } + + int writeResult = write(fileDesc_, data.data(), data.size()); + + // Check status + if (writeResult == -1) + { + throw std::system_error(EFAULT, std::system_category()); + } + } + +void SerialPort::Read(std::string& data) +{ + data.clear(); + + if(fileDesc_ == 0) + { + //this->sp->PrintError(SmartPrint::Ss() << "Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); + //return false; + THROW_EXCEPT("Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); + } + + // Allocate memory for read buffer + // char buf [256]; + // memset (&buf, '\0', sizeof buf); + + // Read from file + // We provide the underlying raw array from the readBuffer_ vector to this C api. + // This will work because we do not delete/resize the vector while this method + // is called + ssize_t n = read( fileDesc_, &readBuffer_[0], readBufferSize_B_ ); + + // Error Handling + if( n < 0 ) + { + // Read was unsuccessful + throw std::system_error(EFAULT, std::system_category()); + } + + if( n > 0 ) + { + // buf[n] = '\0'; + // printf("%s\r\n", buf); + // data.append(buf); + data = std::string( &readBuffer_[0], n ); + //std::cout << *str << " and size of string =" << str->size() << "\r\n"; + } +} + +void SerialPort::ReadBinary(std::vector& data) +{ + data.clear(); + + if( fileDesc_ == 0 ) + { + THROW_EXCEPT("Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); + } + + // Read from file + // We provide the underlying raw array from the readBuffer_ vector to this C api. + // This will work because we do not delete/resize the vector while this method + // is called + ssize_t n = read(fileDesc_, &readBuffer_[0], readBufferSize_B_); + + // Error Handling + if( n < 0 ) + { + // Read was unsuccessful + throw std::system_error(EFAULT, std::system_category()); + } + + if( n > 0 ) + { + copy(readBuffer_.begin(), readBuffer_.begin() + n, back_inserter(data)); + } +} + + // termios SerialPort::GetTermios() { +// if(fileDesc_ == -1) +// throw std::runtime_error("GetTermios() called but file descriptor was not valid."); + + // struct termios tty; + // memset(&tty, 0, sizeof(tty)); + + // // Get current settings (will be stored in termios structure) + // if(tcgetattr(fileDesc_, &tty) != 0) + // { + // // Error occurred + // std::cout << "Could not get terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl; + // throw std::system_error(EFAULT, std::system_category()); + // //return false; + // } + + // return tty; + // } + + // void SerialPort::SetTermios(termios myTermios) + // { + // // Flush port, then apply attributes + // tcflush(fileDesc_, TCIFLUSH); + + // if(tcsetattr(fileDesc_, TCSANOW, &myTermios) != 0) + // { + // // Error occurred + // std::cout << "Could not apply terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl; + // throw std::system_error(EFAULT, std::system_category()); + + // } + + // // Successful! + // } + +termios2 SerialPort::GetTermios2() +{ + struct termios2 term2; + + ioctl(fileDesc_, TCGETS2, &term2); + + return term2; + + // term2.c_cflag &= ~CBAUD; /* Remove current BAUD rate */ + // term2.c_cflag |= BOTHER; /* Allow custom BAUD rate using int input */ + // term2.c_ispeed = speed; /* Set the input BAUD rate */ + // term2.c_ospeed = speed; /* Set the output BAUD rate */ + + // ioctl(fd, TCSETS2, &term2); +} + +void SerialPort::SetTermios2(termios2 tty) +{ + ioctl(fileDesc_, TCSETS2, &tty); +} + +void SerialPort::Close() +{ + if(fileDesc_ != -1) + { + auto retVal = close(fileDesc_); + if(retVal != 0) + THROW_EXCEPT("Tried to close serial port " + device_ + ", but close() failed."); + + fileDesc_ = -1; + } + + state_ = State::CLOSED; +} + +void SerialPort::SetTimeout(int32_t timeout_ms) +{ + if(timeout_ms < -1) + THROW_EXCEPT(std::string() + "timeout_ms provided to " + __PRETTY_FUNCTION__ + " was < -1, which is invalid."); + + if(timeout_ms > 25500) + THROW_EXCEPT(std::string() + "timeout_ms provided to " + __PRETTY_FUNCTION__ + " was > 25500, which is invalid."); + + if(state_ == State::OPEN) + THROW_EXCEPT(std::string() + __PRETTY_FUNCTION__ + " called while state == OPEN."); + + timeout_ms_ = timeout_ms; +} + +int32_t SerialPort::Available() +{ + if(state_ != State::OPEN) + THROW_EXCEPT(std::string() + __PRETTY_FUNCTION__ + " called but state != OPEN. Please call Open() first."); + + int32_t ret = 0; + ioctl(fileDesc_, FIONREAD, &ret); + return ret; + +} + +State SerialPort::GetState() +{ + return state_; +} diff --git a/SerialPort.hpp b/SerialPort.hpp new file mode 100644 index 0000000..f5cf8a1 --- /dev/null +++ b/SerialPort.hpp @@ -0,0 +1,223 @@ +#pragma once + +// System headers +#include +#include // For file I/O (reading/writing to COM port) +#include +// #include // POSIX terminal control definitions (struct termios) +// #include // Terminal control definitions (struct termios) +#include +#include +#include + +// User headers +#include "Exception.hpp" + +/// \brief Represents the baud rate "types" that can be used with the serial port. STANDARD represents all +/// the standard baud rates as provided by UNIX, CUSTOM represents a baud rate defined by an arbitray integer. +enum class BaudRateType +{ + STANDARD, + CUSTOM, +}; + +/// \brief Strongly-typed enumeration of baud rates for use with the SerialPort class +/// \details Specifies all the same baud rates as UNIX, as well as B_CUSTOM to specify your +/// own. See https://linux.die.net/man/3/cfsetispeed for list of supported UNIX baud rates. +enum class BaudRate +{ + B_0, + B_50, + B_75, + B_110, + B_134, + B_150, + B_200, + B_300, + B_600, + B_1200, + B_1800, + B_2400, + B_4800, + B_9600, + B_19200, + B_38400, + B_57600, + B_115200, + B_230400, + B_460800, + B_CUSTOM, // Placeholder +}; + +/// \brief Enumeration of all the valid num. of data bits. Must align with the options +/// provided in termbits.h, i.e. CS5, CS6, CS7 and CS8. +enum class NumDataBits +{ + FIVE, + SIX, + SEVEN, + EIGHT, +}; + +enum class Parity +{ + NONE, + EVEN, + ODD, +}; + +enum class NumStopBits +{ + ONE, + TWO, +}; + +/// \brief Represents the state of the serial port. +enum class State +{ + CLOSED, + OPEN, +}; + +/// \brief SerialPort object is used to perform rx/tx serial communication. +class SerialPort +{ +public: + /// \brief Default constructor. You must specify at least the device before calling Open(). + SerialPort(); + + /// \brief Constructor that sets up serial port with the basic (required) parameters. + SerialPort(const std::string &device, BaudRate baudRate); + + /// \brief Constructor that sets up serial port and allows the user to specify all the common parameters. + SerialPort(const std::string &device, BaudRate baudRate, NumDataBits numDataBits, Parity parity, NumStopBits numStopBits); + + /// \brief Constructor that sets up serial port with the basic parameters, and a custom baud rate. + SerialPort(const std::string &device, speed_t baudRate); + + /// \brief Destructor. Closes serial port if still open. + virtual ~SerialPort(); + + /// \brief Sets the device to use for serial port communications. + /// \details Method can be called when serial port is in any state. + void SetDevice(const std::string &device); + + /// \brief Call this to set a standard baud rate. + void SetBaudRate(BaudRate baudRate); + + /// \brief Call this to set a custom baud rate. + void SetBaudRate(speed_t baudRate); + + /// \brief Call this to set the num. of data bits. + void SetNumDataBits(NumDataBits numDataBits); + + /// \brief Call this to set the parity. + void SetParity(Parity parity); + + void SetNumStopBits(NumStopBits numStopBits); + + /// \brief Sets the read timeout (in milliseconds)/blocking mode. + /// \details Only call when state != OPEN. This method manupulates VMIN and VTIME. + /// \param timeout_ms Set to -1 to infinite timeout, 0 to return immediately with any data (non + /// blocking, or >0 to wait for data for a specified number of milliseconds). Timeout will + /// be rounded to the nearest 100ms (a Linux API restriction). Maximum value limited to + /// 25500ms (another Linux API restriction). + void SetTimeout(int32_t timeout_ms); + + /// \brief Enables/disables echo. + /// \param value Pass in true to enable echo, false to disable echo. + void SetEcho(bool value); + + /// \brief Opens the COM port for use. + /// \throws CppLinuxSerial::Exception if device cannot be opened. + /// \note Must call this before you can configure the COM port. + void Open(); + + /// \brief Closes the COM port. + void Close(); + + /// \brief Sends a text message over the com port. + /// \param data The data that will be written to the COM port. + /// \throws CppLinuxSerial::Exception if state != OPEN. + void Write(const std::string& data); + + /// \brief Sends a binary message over the com port. + /// \param data The data that will be written to the COM port. + /// \throws CppLinuxSerial::Exception if state != OPEN. + void WriteBinary(const std::vector& data); + + /// \brief Use to read text from the COM port. + /// \param data The object the read characters from the COM port will be saved to. + /// \param wait_ms The amount of time to wait for data. Set to 0 for non-blocking mode. Set to -1 + /// to wait indefinitely for new data. + /// \throws CppLinuxSerial::Exception if state != OPEN. + void Read(std::string& data); + + /// \brief Use to read binary data from the COM port. + /// \param data The object the read uint8_t bytes from the COM port will be saved to. + /// \param wait_ms The amount of time to wait for data. Set to 0 for non-blocking mode. Set to -1 + /// to wait indefinitely for new data. + /// \throws CppLinuxSerial::Exception if state != OPEN. + void ReadBinary(std::vector& data); + + /// \brief Use to get number of bytes available in receive buffer. + /// \returns The number of bytes available in the receive buffer (ready to be read). + /// \throws CppLinuxSerial::Exception if state != OPEN. + int32_t Available(); + + /// \brief Use to get the state of the serial port + /// \returns The state of the serial port + State GetState(); + +private: + + /// \brief Configures the tty device as a serial port. + /// \warning Device must be open (valid file descriptor) when this is called. + void ConfigureTermios(); + + // void SetTermios(termios myTermios); + + /// \brief Returns a populated termios2 structure for the serial port pointed to by the file descriptor. + termios2 GetTermios2(); + + /// \brief Assigns the provided tty settings to the serial port pointed to by the file descriptor. + void SetTermios2(termios2 tty); + + /// \brief Keeps track of the serial port's state. + State state_; + + /// \brief The file path to the serial port device (e.g. "/dev/ttyUSB0"). + std::string device_; + + /// \brief The type of baud rate that the user has specified. + BaudRateType baudRateType_; + + /// \brief The current baud rate if baudRateType_ == STANDARD. + BaudRate baudRateStandard_; + + /// \brief The current baud rate if baudRateType_ == CUSTOM. + speed_t baudRateCustom_; + + /// \brief The num. of data bits. Defaults to 8 (most common). + NumDataBits numDataBits_ = NumDataBits::EIGHT; + + /// \brief The parity. Defaults to none (most common). + Parity parity_ = Parity::NONE; + + /// \brief The num. of stop bits. Defaults to 1 (most common). + NumStopBits numStopBits_ = NumStopBits::ONE; + + /// \brief The file descriptor for the open file. This gets written to when Open() is called. + int fileDesc_; + + bool echo_; + + int32_t timeout_ms_; + + std::vector readBuffer_; + unsigned char readBufferSize_B_; + + static constexpr BaudRate defaultBaudRate_ = BaudRate::B_57600; + static constexpr int32_t defaultTimeout_ms_ = -1; + static constexpr unsigned char defaultReadBufferSize_B_ = 255; +}; diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..cde43ad --- /dev/null +++ b/main.cpp @@ -0,0 +1,36 @@ +#include "SerialPort.hpp" + +#include +#include +#include + +int main(int argc, char** argv) +{ + SerialPort oPort; + + oPort.SetDevice( "/dev/ttyUSB0" ); + oPort.SetNumDataBits(NumDataBits::EIGHT); + oPort.SetParity(Parity::NONE); + oPort.SetNumStopBits(NumStopBits::ONE); + oPort.SetBaudRate( BaudRate::B_2400 ); + + oPort.Open(); + + // Create data package. + std::vector data_binair; + std::string data_string; + + for( uint8_t nCount = 0; nCount < 255; nCount++ ) + { + data_binair.push_back( nCount ); + data_string += std::to_string(nCount); + } + while( 1 ) + { + oPort.WriteBinary( data_binair ); + oPort.Write( data_string ); + } + + return 0; +} + diff --git a/nbproject/Makefile-Debug.mk b/nbproject/Makefile-Debug.mk new file mode 100644 index 0000000..0035b84 --- /dev/null +++ b/nbproject/Makefile-Debug.mk @@ -0,0 +1,89 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=GNU-Linux +CND_DLIB_EXT=so +CND_CONF=Debug +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/SerialPort.o \ + ${OBJECTDIR}/main.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-m64 +CXXFLAGS=-m64 + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS= + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/serialport + +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/serialport: ${OBJECTFILES} + ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/serialport ${OBJECTFILES} ${LDLIBSOPTIONS} + +${OBJECTDIR}/SerialPort.o: SerialPort.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/SerialPort.o SerialPort.cpp + +${OBJECTDIR}/main.o: main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/nbproject/Makefile-Release.mk b/nbproject/Makefile-Release.mk new file mode 100644 index 0000000..72bd10b --- /dev/null +++ b/nbproject/Makefile-Release.mk @@ -0,0 +1,89 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=GNU-Linux +CND_DLIB_EXT=so +CND_CONF=Release +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/SerialPort.o \ + ${OBJECTDIR}/main.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS= +CXXFLAGS= + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS= + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/serialport + +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/serialport: ${OBJECTFILES} + ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/serialport ${OBJECTFILES} ${LDLIBSOPTIONS} + +${OBJECTDIR}/SerialPort.o: SerialPort.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/SerialPort.o SerialPort.cpp + +${OBJECTDIR}/main.o: main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/nbproject/Makefile-impl.mk b/nbproject/Makefile-impl.mk new file mode 100644 index 0000000..b1cfa30 --- /dev/null +++ b/nbproject/Makefile-impl.mk @@ -0,0 +1,133 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a pre- and a post- target defined where you can add customization code. +# +# This makefile implements macros and targets common to all configurations. +# +# NOCDDL + + +# Building and Cleaning subprojects are done by default, but can be controlled with the SUB +# macro. If SUB=no, subprojects will not be built or cleaned. The following macro +# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf +# and .clean-reqprojects-conf unless SUB has the value 'no' +SUB_no=NO +SUBPROJECTS=${SUB_${SUB}} +BUILD_SUBPROJECTS_=.build-subprojects +BUILD_SUBPROJECTS_NO= +BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} +CLEAN_SUBPROJECTS_=.clean-subprojects +CLEAN_SUBPROJECTS_NO= +CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} + + +# Project Name +PROJECTNAME=serialport + +# Active Configuration +DEFAULTCONF=Debug +CONF=${DEFAULTCONF} + +# All Configurations +ALLCONFS=Debug Release + + +# build +.build-impl: .build-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf + + +# clean +.clean-impl: .clean-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf + + +# clobber +.clobber-impl: .clobber-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \ + done + +# all +.all-impl: .all-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \ + done + +# build tests +.build-tests-impl: .build-impl .build-tests-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf + +# run tests +.test-impl: .build-tests-impl .test-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf + +# dependency checking support +.depcheck-impl: + @echo "# This code depends on make tool being used" >.dep.inc + @if [ -n "${MAKE_VERSION}" ]; then \ + echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES} \$${TESTOBJECTFILES}))" >>.dep.inc; \ + echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ + echo "include \$${DEPFILES}" >>.dep.inc; \ + echo "endif" >>.dep.inc; \ + else \ + echo ".KEEP_STATE:" >>.dep.inc; \ + echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ + fi + +# configuration validation +.validate-impl: + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + echo ""; \ + echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \ + echo "See 'make help' for details."; \ + echo "Current directory: " `pwd`; \ + echo ""; \ + fi + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + exit 1; \ + fi + + +# help +.help-impl: .help-pre + @echo "This makefile supports the following configurations:" + @echo " ${ALLCONFS}" + @echo "" + @echo "and the following targets:" + @echo " build (default target)" + @echo " clean" + @echo " clobber" + @echo " all" + @echo " help" + @echo "" + @echo "Makefile Usage:" + @echo " make [CONF=] [SUB=no] build" + @echo " make [CONF=] [SUB=no] clean" + @echo " make [SUB=no] clobber" + @echo " make [SUB=no] all" + @echo " make help" + @echo "" + @echo "Target 'build' will build a specific configuration and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no'," + @echo " also clean subprojects." + @echo "Target 'clobber' will remove all built files from all configurations and," + @echo " unless 'SUB=no', also from subprojects." + @echo "Target 'all' will will build all configurations and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'help' prints this message." + @echo "" + diff --git a/nbproject/Makefile-variables.mk b/nbproject/Makefile-variables.mk new file mode 100644 index 0000000..576098b --- /dev/null +++ b/nbproject/Makefile-variables.mk @@ -0,0 +1,35 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +CND_BASEDIR=`pwd` +CND_BUILDDIR=build +CND_DISTDIR=dist +# Debug configuration +CND_PLATFORM_Debug=GNU-Linux +CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux +CND_ARTIFACT_NAME_Debug=serialport +CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux/serialport +CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux/package +CND_PACKAGE_NAME_Debug=serialport.tar +CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/serialport.tar +# Release configuration +CND_PLATFORM_Release=GNU-Linux +CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux +CND_ARTIFACT_NAME_Release=serialport +CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux/serialport +CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux/package +CND_PACKAGE_NAME_Release=serialport.tar +CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux/package/serialport.tar +# +# include compiler specific variables +# +# dmake command +ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \ + (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk) +# +# gmake command +.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)) +# +include nbproject/private/Makefile-variables.mk diff --git a/nbproject/Package-Debug.bash b/nbproject/Package-Debug.bash new file mode 100644 index 0000000..8c12d40 --- /dev/null +++ b/nbproject/Package-Debug.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux +CND_CONF=Debug +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/serialport +OUTPUT_BASENAME=serialport +PACKAGE_TOP_DIR=serialport/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/serialport/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/serialport.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/serialport.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/nbproject/Package-Release.bash b/nbproject/Package-Release.bash new file mode 100644 index 0000000..2c7d8a7 --- /dev/null +++ b/nbproject/Package-Release.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux +CND_CONF=Release +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/serialport +OUTPUT_BASENAME=serialport +PACKAGE_TOP_DIR=serialport/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/serialport/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/serialport.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/serialport.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml new file mode 100644 index 0000000..ccbd549 --- /dev/null +++ b/nbproject/configurations.xml @@ -0,0 +1,86 @@ + + + + + Exception.hpp + SerialPort.hpp + + + + + SerialPort.cpp + main.cpp + + + + + Makefile + + + Makefile + + + + default + true + false + + + + 2 + 11 + + + + + + + + + + + + + + default + true + false + + + + 5 + + + 5 + 11 + + + 5 + + + 5 + + + + + + + + + + + + + diff --git a/nbproject/private/Makefile-variables.mk b/nbproject/private/Makefile-variables.mk new file mode 100644 index 0000000..a64183e --- /dev/null +++ b/nbproject/private/Makefile-variables.mk @@ -0,0 +1,7 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +# Debug configuration +# Release configuration diff --git a/nbproject/private/c_standard_headers_indexer.c b/nbproject/private/c_standard_headers_indexer.c new file mode 100644 index 0000000..c2548d2 --- /dev/null +++ b/nbproject/private/c_standard_headers_indexer.c @@ -0,0 +1,75 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + */ + +// List of standard headers was taken in http://en.cppreference.com/w/c/header + +#include // Conditionally compiled macro that compares its argument to zero +#include // Functions to determine the type contained in character data +#include // Macros reporting error conditions +#include // Limits of float types +#include // Sizes of basic types +#include // Localization utilities +#include // Common mathematics functions +#include // Nonlocal jumps +#include // Signal handling +#include // Variable arguments +#include // Common macro definitions +#include // Input/output +#include // String handling +#include // General utilities: memory management, program utilities, string conversions, random numbers +#include // Time/date utilities +#include // (since C95) Alternative operator spellings +#include // (since C95) Extended multibyte and wide character utilities +#include // (since C95) Wide character classification and mapping utilities +#ifdef _STDC_C99 +#include // (since C99) Complex number arithmetic +#include // (since C99) Floating-point environment +#include // (since C99) Format conversion of integer types +#include // (since C99) Boolean type +#include // (since C99) Fixed-width integer types +#include // (since C99) Type-generic math (macros wrapping math.h and complex.h) +#endif +#ifdef _STDC_C11 +#include // (since C11) alignas and alignof convenience macros +#include // (since C11) Atomic types +#include // (since C11) noreturn convenience macros +#include // (since C11) Thread library +#include // (since C11) UTF-16 and UTF-32 character utilities +#endif diff --git a/nbproject/private/configurations.xml b/nbproject/private/configurations.xml new file mode 100644 index 0000000..30b54f8 --- /dev/null +++ b/nbproject/private/configurations.xml @@ -0,0 +1,72 @@ + + + Makefile + + + + localhost + 2 + + + + + + + + + + + + + + + gdb + + + + "${OUTPUT_PATH}" + + "${OUTPUT_PATH}" + + true + 0 + 0 + + + + + + + localhost + 2 + + + + + + + + + + + + + + + gdb + + + + "${OUTPUT_PATH}" + + "${OUTPUT_PATH}" + + true + 0 + 0 + + + + + + diff --git a/nbproject/private/cpp_standard_headers_indexer.cpp b/nbproject/private/cpp_standard_headers_indexer.cpp new file mode 100644 index 0000000..04f6fa6 --- /dev/null +++ b/nbproject/private/cpp_standard_headers_indexer.cpp @@ -0,0 +1,135 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + */ + +// List of standard headers was taken in http://en.cppreference.com/w/cpp/header + +#include // General purpose utilities: program control, dynamic memory allocation, random numbers, sort and search +#include // Functions and macro constants for signal management +#include // Macro (and function) that saves (and jumps) to an execution context +#include // Handling of variable length argument lists +#include // Runtime type information utilities +#include // std::bitset class template +#include // Function objects, designed for use with the standard algorithms +#include // Various utility components +#include // C-style time/date utilites +#include // typedefs for types such as size_t, NULL and others +#include // Low-level memory management utilities +#include // Higher level memory management utilities +#include // limits of integral types +#include // limits of float types +#include // standardized way to query properties of arithmetic types +#include // Exception handling utilities +#include // Standard exception objects +#include // Conditionally compiled macro that compares its argument to zero +#include // Macro containing the last error number +#include // functions to determine the type contained in character data +#include // functions for determining the type of wide character data +#include // various narrow character string handling functions +#include // various wide and multibyte string handling functions +#include // std::basic_string class template +#include // std::vector container +#include // std::deque container +#include // std::list container +#include // std::set and std::multiset associative containers +#include // std::map and std::multimap associative containers +#include // std::stack container adaptor +#include // std::queue and std::priority_queue container adaptors +#include // Algorithms that operate on containers +#include // Container iterators +#include // Common mathematics functions +#include // Complex number type +#include // Class for representing and manipulating arrays of values +#include // Numeric operations on values in containers +#include // forward declarations of all classes in the input/output library +#include // std::ios_base class, std::basic_ios class template and several typedefs +#include // std::basic_istream class template and several typedefs +#include // std::basic_ostream, std::basic_iostream class templates and several typedefs +#include // several standard stream objects +#include // std::basic_fstream, std::basic_ifstream, std::basic_ofstream class templates and several typedefs +#include // std::basic_stringstream, std::basic_istringstream, std::basic_ostringstream class templates and several typedefs +#include // std::strstream, std::istrstream, std::ostrstream(deprecated) +#include // Helper functions to control the format or input and output +#include // std::basic_streambuf class template +#include // C-style input-output functions +#include // Localization utilities +#include // C localization utilities +#include // empty header. The macros that appear in iso646.h in C are keywords in C++ +#if __cplusplus >= 201103L +#include // (since C++11) std::type_index +#include // (since C++11) Compile-time type information +#include // (since C++11) C++ time utilites +#include // (since C++11) std::initializer_list class template +#include // (since C++11) std::tuple class template +#include // (since C++11) Nested allocator class +#include // (since C++11) fixed-size types and limits of other types +#include // (since C++11) formatting macros , intmax_t and uintmax_t math and conversions +#include // (since C++11) defines std::error_code, a platform-dependent error code +#include // (since C++11) C-style Unicode character conversion functions +#include // (since C++11) std::array container +#include // (since C++11) std::forward_list container +#include // (since C++11) std::unordered_set and std::unordered_multiset unordered associative containers +#include // (since C++11) std::unordered_map and std::unordered_multimap unordered associative containers +#include // (since C++11) Random number generators and distributions +#include // (since C++11) Compile-time rational arithmetic +#include // (since C++11) Floating-point environment access functions +#include // (since C++11) Unicode conversion facilities +#include // (since C++11) Classes, algorithms and iterators to support regular expression processing +#include // (since C++11) Atomic operations library +#include // (since C++11)(deprecated in C++17) simply includes the header +#include // (since C++11)(deprecated in C++17) simply includes the headers (until C++17) (since C++17) and : the overloads equivalent to the contents of the C header tgmath.h are already provided by those headers +#include // (since C++11)(deprecated in C++17) defines one compatibility macro constant +#include // (since C++11)(deprecated in C++17) defines one compatibility macro constant +#include // (since C++11) std::thread class and supporting functions +#include // (since C++11) mutual exclusion primitives +#include // (since C++11) primitives for asynchronous computations +#include // (since C++11) thread waiting conditions +#endif +#if __cplusplus >= 201300L +#include // (since C++14) shared mutual exclusion primitives +#endif +#if __cplusplus >= 201500L +#include // (since C++17) std::any class template +#include // (since C++17) std::optional class template +#include // (since C++17) std::variant class template +#include // (since C++17) Polymorphic allocators and memory resources +#include // (since C++17) std::basic_string_view class template +#include // (since C++17) Predefined execution policies for parallel versions of the algorithms +#include // (since C++17) std::path class and supporting functions +#endif diff --git a/nbproject/private/launcher.properties b/nbproject/private/launcher.properties new file mode 100644 index 0000000..3edc2d8 --- /dev/null +++ b/nbproject/private/launcher.properties @@ -0,0 +1,42 @@ +# Launchers File syntax: +# +# [Must-have property line] +# launcher1.runCommand= +# [Optional extra properties] +# launcher1.displayName= +# launcher1.hide= +# launcher1.buildCommand= +# launcher1.runDir= +# launcher1.runInOwnTab= +# launcher1.symbolFiles= +# launcher1.env.= +# (If this value is quoted with ` it is handled as a native command which execution result will become the value) +# [Common launcher properties] +# common.runDir= +# (This value is overwritten by a launcher specific runDir value if the latter exists) +# common.env.= +# (Environment variables from common launcher are merged with launcher specific variables) +# common.symbolFiles= +# (This value is overwritten by a launcher specific symbolFiles value if the latter exists) +# +# In runDir, symbolFiles and env fields you can use these macroses: +# ${PROJECT_DIR} - project directory absolute path +# ${OUTPUT_PATH} - linker output path (relative to project directory path) +# ${OUTPUT_BASENAME}- linker output filename +# ${TESTDIR} - test files directory (relative to project directory path) +# ${OBJECTDIR} - object files directory (relative to project directory path) +# ${CND_DISTDIR} - distribution directory (relative to project directory path) +# ${CND_BUILDDIR} - build directory (relative to project directory path) +# ${CND_PLATFORM} - platform name +# ${CND_CONF} - configuration name +# ${CND_DLIB_EXT} - dynamic library extension +# +# All the project launchers must be listed in the file! +# +# launcher1.runCommand=... +# launcher2.runCommand=... +# ... +# common.runDir=... +# common.env.KEY=VALUE + +# launcher1.runCommand= \ No newline at end of file diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 0000000..29fbbc9 --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,15 @@ + + + + 1 + 0 + + + + + file:/home/pgroen/projects/serialport/Exception.hpp + file:/home/pgroen/projects/serialport/SerialPort.cpp + file:/home/pgroen/projects/serialport/main.cpp + + + diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..bd89f3e --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1 @@ +#Tue May 24 23:09:12 CEST 2022 diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..b6058c4 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,28 @@ + + + org.netbeans.modules.cnd.makeproject + + + SerPortTest + + cpp + hpp + UTF-8 + + + + + Debug + 1 + + + Release + 1 + + + + false + + + + -- libgit2 0.21.4