From cd9c9647ec9de9a4dcd159b6eb08c6f1beaf283f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 15 Jun 2021 13:32:37 +0200 Subject: [PATCH] extended uart com if with canonical mode --- linux/gpio/LinuxLibgpioIF.h | 2 +- linux/spi/SpiComIF.h | 2 +- linux/uart/UartComIF.cpp | 78 ++++++++++++++++++++++--------------- linux/uart/UartComIF.h | 15 +++++-- linux/uart/UartCookie.cpp | 9 ++++- linux/uart/UartCookie.h | 29 ++++++++------ 6 files changed, 86 insertions(+), 49 deletions(-) diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 093e95a..00e1bdf 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -17,7 +17,7 @@ class GpioCookie; class LinuxLibgpioIF : public GpioIF, public SystemObject { public: - static const uint8_t gpioRetvalId = CLASS_ID::LINUX_LIBGPIO_IF; + static const uint8_t gpioRetvalId = CLASS_ID::HAL_GPIO; static constexpr ReturnValue_t UNKNOWN_GPIO_ID = HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 1); diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h index 60b250e..13f7603 100644 --- a/linux/spi/SpiComIF.h +++ b/linux/spi/SpiComIF.h @@ -22,7 +22,7 @@ class SpiCookie; */ class SpiComIF: public DeviceCommunicationIF, public SystemObject { public: - static constexpr uint8_t spiRetvalId = CLASS_ID::LINUX_SPI_COM_IF; + static constexpr uint8_t spiRetvalId = CLASS_ID::HAL_SPI; static constexpr ReturnValue_t OPENING_FILE_FAILED = HasReturnvaluesIF::makeReturnCode(spiRetvalId, 0); /* Full duplex (ioctl) transfer failure */ diff --git a/linux/uart/UartComIF.cpp b/linux/uart/UartComIF.cpp index 3f389df..95cc5a3 100644 --- a/linux/uart/UartComIF.cpp +++ b/linux/uart/UartComIF.cpp @@ -37,17 +37,17 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF * cookie) { return RETURN_FAILED; } size_t maxReplyLen = uartCookie->getMaxReplyLen(); - UartElements_t uartElements = {fileDescriptor, std::vector(maxReplyLen), 0}; + UartElements uartElements = {fileDescriptor, std::vector(maxReplyLen), 0}; auto status = uartDeviceMap.emplace(deviceFile, uartElements); if (status.second == false) { - sif::debug << "UartComIF::initializeInterface: Failed to insert device " << deviceFile - << "to UART device map" << std::endl; + sif::warning << "UartComIF::initializeInterface: Failed to insert device " << + deviceFile << "to UART device map" << std::endl; return RETURN_FAILED; } } else { - sif::debug << "UartComIF::initializeInterface: UART device " << deviceFile << " already in " - << "use" << std::endl; + sif::warning << "UartComIF::initializeInterface: UART device " << deviceFile << + " already in use" << std::endl; return RETURN_FAILED; } @@ -62,14 +62,14 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) { int fd = open(deviceFile.c_str(), O_RDWR); if (fd < 0) { - sif::debug << "UartComIF::configureUartPort: Failed to open uart " << deviceFile << "with" - << " error code " << errno << strerror(errno) << std::endl; + sif::warning << "UartComIF::configureUartPort: Failed to open uart " << deviceFile << + "with error code " << errno << strerror(errno) << std::endl; return fd; } /* Read in existing settings */ if(tcgetattr(fd, &options) != 0) { - sif::debug << "UartComIF::configureUartPort: Error " << errno << "from tcgetattr: " + sif::warning << "UartComIF::configureUartPort: Error " << errno << "from tcgetattr: " << strerror(errno) << std::endl; return fd; } @@ -87,8 +87,8 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) { /* Save option settings */ if (tcsetattr(fd, TCSANOW, &options) != 0) { - sif::debug << "UartComIF::configureUartPort: Failed to set options with error " << errno - << ": " << strerror(errno); + sif::warning << "UartComIF::configureUartPort: Failed to set options with error " << + errno << ": " << strerror(errno); return fd; } return fd; @@ -140,7 +140,7 @@ void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCook options->c_cflag |= CS8; break; default: - sif::debug << "UartComIF::setDatasizeOptions: Invalid size specified" << std::endl; + sif::warning << "UartComIF::setDatasizeOptions: Invalid size specified" << std::endl; break; } } @@ -150,8 +150,6 @@ void UartComIF::setFixedOptions(struct termios* options) { options->c_cflag &= ~CRTSCTS; /* Turn on READ & ignore ctrl lines (CLOCAL = 1) */ options->c_cflag |= CREAD | CLOCAL; - /* Disable canonical mode */ - options->c_lflag &= ~ICANON; /* Disable echo */ options->c_lflag &= ~ECHO; /* Disable erasure */ @@ -272,23 +270,23 @@ ReturnValue_t UartComIF::sendMessage(CookieIF *cookie, UartCookie* uartCookie = dynamic_cast(cookie); if(uartCookie == nullptr) { - sif::debug << "UartComIF::sendMessasge: Invalid Uart Cookie!" << std::endl; + sif::debug << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl; return NULLPOINTER; } deviceFile = uartCookie->getDeviceFile(); uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter == uartDeviceMap.end()) { - sif::debug << "UartComIF::sendMessage: Device file " << deviceFile << "not in uart map" - << std::endl; + sif::debug << "UartComIF::sendMessage: Device file " << deviceFile << + "not in UART map" << std::endl; return RETURN_FAILED; } fd = uartDeviceMapIter->second.fileDescriptor; if (write(fd, sendData, sendLen) != (int)sendLen) { - sif::error << "UartComIF::sendMessage: Failed to send data with error code " << errno - << ": Error description: " << strerror(errno) << std::endl; + sif::error << "UartComIF::sendMessage: Failed to send data with error code " << + errno << ": Error description: " << strerror(errno) << std::endl; return RETURN_FAILED; } @@ -299,9 +297,7 @@ ReturnValue_t UartComIF::getSendSuccess(CookieIF *cookie) { return RETURN_OK; } -ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, - size_t requestLen) { - +ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) { int fd = 0; std::string deviceFile; UartDeviceMapIter uartDeviceMapIter; @@ -317,6 +313,7 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, return NULLPOINTER; } + UartModes uartMode = uartCookie->getUartMode(); deviceFile = uartCookie->getDeviceFile(); uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter == uartDeviceMap.end()) { @@ -327,16 +324,24 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, fd = uartDeviceMapIter->second.fileDescriptor; bufferPtr = uartDeviceMapIter->second.replyBuffer.data(); - int bytesRead = read(fd, bufferPtr, requestLen); - if (bytesRead != static_cast(requestLen)) { - sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead - << " of " << requestLen << " bytes" << std::endl; - return RETURN_FAILED; - } - else { + if (uartMode == UartModes::CANONICAL) { + int bytesRead = read(fd, bufferPtr, uartCookie->getMaxReplyLen()); uartDeviceMapIter->second.replyLen = bytesRead; } - + else if (uartMode == UartModes::NON_CANONICAL) { + int bytesRead = read(fd, bufferPtr, requestLen); + if (bytesRead < 0) { + return RETURN_FAILED; + } + else if (bytesRead != static_cast(requestLen)) { + sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead << + " of " << requestLen << " bytes" << std::endl; + return RETURN_FAILED; + } + else { + uartDeviceMapIter->second.replyLen = bytesRead; + } + } return RETURN_OK; } @@ -355,8 +360,8 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie, deviceFile = uartCookie->getDeviceFile(); uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter == uartDeviceMap.end()) { - sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile - << " not in uart map" << std::endl; + sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile << + " not in uart map" << std::endl; return RETURN_FAILED; } @@ -368,3 +373,14 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie, return RETURN_OK; } + +void UartComIF::setUartMode(struct termios *options, UartCookie &uartCookie) { + UartModes uartMode = uartCookie.getUartMode(); + if(uartMode == UartModes::NON_CANONICAL) { + /* Disable canonical mode */ + options->c_lflag &= ~ICANON; + } + else if(uartMode == UartModes::CANONICAL) { + options->c_lflag |= ICANON; + } +} diff --git a/linux/uart/UartComIF.h b/linux/uart/UartComIF.h index 9dd854d..dc0a509 100644 --- a/linux/uart/UartComIF.h +++ b/linux/uart/UartComIF.h @@ -20,6 +20,13 @@ */ class UartComIF: public DeviceCommunicationIF, public SystemObject { public: + static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART; + + static constexpr ReturnValue_t UART_READ_FAILURE = + HasReturnvaluesIF::makeReturnCode(uartRetvalId, 1); + static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = + HasReturnvaluesIF::makeReturnCode(uartRetvalId, 2); + UartComIF(object_id_t objectId); virtual ~UartComIF(); @@ -37,14 +44,14 @@ private: using UartDeviceFile_t = std::string; - typedef struct UartElements { + struct UartElements { int fileDescriptor; std::vector replyBuffer; /** Number of bytes read will be written to this variable */ size_t replyLen; - } UartElements_t; + }; - using UartDeviceMap = std::unordered_map; + using UartDeviceMap = std::unordered_map; using UartDeviceMapIter = UartDeviceMap::iterator; /** @@ -89,6 +96,8 @@ private: * struct. */ void configureBaudrate(struct termios* options, UartCookie* uartCookie); + + void setUartMode(struct termios* options, UartCookie& uartCookie); }; #endif /* BSP_Q7S_COMIF_UARTCOMIF_H_ */ diff --git a/linux/uart/UartCookie.cpp b/linux/uart/UartCookie.cpp index b814938..d263c29 100644 --- a/linux/uart/UartCookie.cpp +++ b/linux/uart/UartCookie.cpp @@ -2,8 +2,9 @@ #include -UartCookie::UartCookie(std::string deviceFile, uint32_t baudrate, size_t maxReplyLen) : - deviceFile(deviceFile), baudrate(baudrate), maxReplyLen(maxReplyLen) { +UartCookie::UartCookie(std::string deviceFile, UartModes uartMode, uint32_t baudrate, + size_t maxReplyLen) : + deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate), maxReplyLen(maxReplyLen) { } UartCookie::~UartCookie() {} @@ -61,3 +62,7 @@ void UartCookie::setTwoStopBits() { void UartCookie::setOneStopBit() { stopBits = StopBits::ONE_STOP_BIT; } + +UartModes UartCookie::getUartMode() const { + return uartMode; +} diff --git a/linux/uart/UartCookie.h b/linux/uart/UartCookie.h index 5900471..406ee62 100644 --- a/linux/uart/UartCookie.h +++ b/linux/uart/UartCookie.h @@ -15,8 +15,13 @@ enum class StopBits { TWO_STOP_BITS }; +enum class UartModes { + CANONICAL, + NON_CANONICAL +}; + /** - * @brief Cookie for the UartComIF. There are many options available to configure the uart driver. + * @brief Cookie for the UartComIF. There are many options available to configure the UART driver. * The constructor only requests for common options like the baudrate. Other options can * be set by member functions. * @@ -27,19 +32,20 @@ public: /** * @brief Constructor for the uart cookie. - * @param deviceFile The device file specifying the uart to use. E.g. "/dev/ttyPS1". + * @param deviceFile The device file specifying the uart to use, e.g. "/dev/ttyPS1" + * @param uartMode Specify the UART mode. The canonical mode should be used if the + * messages are separated by a delimited character like '\n'. See the + * termios documentation for more information * @param baudrate The baudrate to use for input and output. Possible Baudrates are: 50, * 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, B19200, * 38400, 57600, 115200, 230400, 460800 - * @param maxReplyLen The maximum size an object using this cookie expects. - * - * @details Default configuration: No parity - * 8 databits (number of bits transfered with one uart frame) - * One stop bit - * - * + * @param maxReplyLen The maximum size an object using this cookie expects + * @details + * Default configuration: No parity + * 8 databits (number of bits transfered with one uart frame) + * One stop bit */ - UartCookie(std::string deviceFile, uint32_t baudrate, size_t maxReplyLen); + UartCookie(std::string deviceFile, UartModes uartMode, uint32_t baudrate, size_t maxReplyLen); virtual ~UartCookie(); @@ -49,6 +55,7 @@ public: Parity getParity() const; uint8_t getBitsPerWord() const; StopBits getStopBits() const; + UartModes getUartMode() const; /** * Functions two enable parity checking. @@ -67,10 +74,10 @@ public: void setTwoStopBits(); void setOneStopBit(); - private: std::string deviceFile; + const UartModes uartMode; uint32_t baudrate; size_t maxReplyLen = 0; Parity parity = Parity::NONE;