Merge pull request 'refactoring of serial drivers for linux' (#705) from eive/fsfw:mueller/refactor_serial_linux into development

Reviewed-on: fsfw/fsfw#705
This commit is contained in:
Steffen Gaisser 2022-11-14 14:39:41 +01:00
commit 93fda71989
11 changed files with 347 additions and 333 deletions

View File

@ -122,6 +122,7 @@ if(UNIX)
option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add Linux peripheral drivers" option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add Linux peripheral drivers"
OFF) OFF)
option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Attempt to add Linux GPIOD drivers" OFF) option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Attempt to add Linux GPIOD drivers" OFF)
option(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS "Add serial drivers" ON)
endif() endif()
# Optional sources # Optional sources

View File

@ -5,11 +5,14 @@ endif()
target_sources(${LIB_FSFW_NAME} PRIVATE UnixFileGuard.cpp CommandExecutor.cpp target_sources(${LIB_FSFW_NAME} PRIVATE UnixFileGuard.cpp CommandExecutor.cpp
utility.cpp) utility.cpp)
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
add_subdirectory(gpio)
endif()
if(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS)
add_subdirectory(serial)
endif()
if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS) if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
add_subdirectory(gpio)
endif()
add_subdirectory(uart)
# Adding those does not really make sense on Apple systems which are generally # Adding those does not really make sense on Apple systems which are generally
# host systems. It won't even compile as the headers are missing # host systems. It won't even compile as the headers are missing
if(NOT APPLE) if(NOT APPLE)

View File

@ -0,0 +1,2 @@
target_sources(${LIB_FSFW_NAME} PUBLIC SerialComIF.cpp SerialCookie.cpp
helper.cpp)

View File

@ -1,4 +1,4 @@
#include "UartComIF.h" #include "SerialComIF.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -11,19 +11,18 @@
#include "fsfw/serviceinterface.h" #include "fsfw/serviceinterface.h"
#include "fsfw_hal/linux/utility.h" #include "fsfw_hal/linux/utility.h"
UartComIF::UartComIF(object_id_t objectId) : SystemObject(objectId) {} SerialComIF::SerialComIF(object_id_t objectId) : SystemObject(objectId) {}
UartComIF::~UartComIF() {} SerialComIF::~SerialComIF() {}
ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) { ReturnValue_t SerialComIF::initializeInterface(CookieIF* cookie) {
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter;
if (cookie == nullptr) { if (cookie == nullptr) {
return NULLPOINTER; return NULLPOINTER;
} }
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie); SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
if (uartCookie == nullptr) { if (uartCookie == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "UartComIF::initializeInterface: Invalid UART Cookie!" << std::endl; sif::error << "UartComIF::initializeInterface: Invalid UART Cookie!" << std::endl;
@ -33,7 +32,7 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter == uartDeviceMap.end()) { if (uartDeviceMapIter == uartDeviceMap.end()) {
int fileDescriptor = configureUartPort(uartCookie); int fileDescriptor = configureUartPort(uartCookie);
if (fileDescriptor < 0) { if (fileDescriptor < 0) {
@ -60,7 +59,7 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
return returnvalue::OK; return returnvalue::OK;
} }
int UartComIF::configureUartPort(UartCookie* uartCookie) { int SerialComIF::configureUartPort(SerialCookie* uartCookie) {
struct termios options = {}; struct termios options = {};
std::string deviceFile = uartCookie->getDeviceFile(); std::string deviceFile = uartCookie->getDeviceFile();
@ -89,11 +88,11 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
return fd; return fd;
} }
setParityOptions(&options, uartCookie); uart::setParity(options, uartCookie->getParity());
setStopBitOptions(&options, uartCookie); setStopBitOptions(&options, uartCookie);
setDatasizeOptions(&options, uartCookie); setDatasizeOptions(&options, uartCookie);
setFixedOptions(&options); setFixedOptions(&options);
setUartMode(&options, *uartCookie); uart::setMode(options, uartCookie->getUartMode());
if (uartCookie->getInputShouldBeFlushed()) { if (uartCookie->getInputShouldBeFlushed()) {
tcflush(fd, TCIFLUSH); tcflush(fd, TCIFLUSH);
} }
@ -102,7 +101,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
options.c_cc[VTIME] = 0; options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0; options.c_cc[VMIN] = 0;
configureBaudrate(&options, uartCookie); uart::setBaudrate(options, uartCookie->getBaudrate());
/* Save option settings */ /* Save option settings */
if (tcsetattr(fd, TCSANOW, &options) != 0) { if (tcsetattr(fd, TCSANOW, &options) != 0) {
@ -115,24 +114,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
return fd; return fd;
} }
void UartComIF::setParityOptions(struct termios* options, UartCookie* uartCookie) { void SerialComIF::setStopBitOptions(struct termios* options, SerialCookie* uartCookie) {
/* Clear parity bit */
options->c_cflag &= ~PARENB;
switch (uartCookie->getParity()) {
case Parity::EVEN:
options->c_cflag |= PARENB;
options->c_cflag &= ~PARODD;
break;
case Parity::ODD:
options->c_cflag |= PARENB;
options->c_cflag |= PARODD;
break;
default:
break;
}
}
void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCookie) {
/* Clear stop field. Sets stop bit to one bit */ /* Clear stop field. Sets stop bit to one bit */
options->c_cflag &= ~CSTOPB; options->c_cflag &= ~CSTOPB;
switch (uartCookie->getStopBits()) { switch (uartCookie->getStopBits()) {
@ -144,7 +126,7 @@ void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCooki
} }
} }
void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCookie) { void SerialComIF::setDatasizeOptions(struct termios* options, SerialCookie* uartCookie) {
/* Clear size bits */ /* Clear size bits */
options->c_cflag &= ~CSIZE; options->c_cflag &= ~CSIZE;
switch (uartCookie->getBitsPerWord()) { switch (uartCookie->getBitsPerWord()) {
@ -168,7 +150,7 @@ void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCook
} }
} }
void UartComIF::setFixedOptions(struct termios* options) { void SerialComIF::setFixedOptions(struct termios* options) {
/* Disable RTS/CTS hardware flow control */ /* Disable RTS/CTS hardware flow control */
options->c_cflag &= ~CRTSCTS; options->c_cflag &= ~CRTSCTS;
/* Turn on READ & ignore ctrl lines (CLOCAL = 1) */ /* Turn on READ & ignore ctrl lines (CLOCAL = 1) */
@ -191,142 +173,9 @@ void UartComIF::setFixedOptions(struct termios* options) {
options->c_oflag &= ~ONLCR; options->c_oflag &= ~ONLCR;
} }
void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCookie) { ReturnValue_t SerialComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
switch (uartCookie->getBaudrate()) {
case UartBaudRate::RATE_50:
cfsetispeed(options, B50);
cfsetospeed(options, B50);
break;
case UartBaudRate::RATE_75:
cfsetispeed(options, B75);
cfsetospeed(options, B75);
break;
case UartBaudRate::RATE_110:
cfsetispeed(options, B110);
cfsetospeed(options, B110);
break;
case UartBaudRate::RATE_134:
cfsetispeed(options, B134);
cfsetospeed(options, B134);
break;
case UartBaudRate::RATE_150:
cfsetispeed(options, B150);
cfsetospeed(options, B150);
break;
case UartBaudRate::RATE_200:
cfsetispeed(options, B200);
cfsetospeed(options, B200);
break;
case UartBaudRate::RATE_300:
cfsetispeed(options, B300);
cfsetospeed(options, B300);
break;
case UartBaudRate::RATE_600:
cfsetispeed(options, B600);
cfsetospeed(options, B600);
break;
case UartBaudRate::RATE_1200:
cfsetispeed(options, B1200);
cfsetospeed(options, B1200);
break;
case UartBaudRate::RATE_1800:
cfsetispeed(options, B1800);
cfsetospeed(options, B1800);
break;
case UartBaudRate::RATE_2400:
cfsetispeed(options, B2400);
cfsetospeed(options, B2400);
break;
case UartBaudRate::RATE_4800:
cfsetispeed(options, B4800);
cfsetospeed(options, B4800);
break;
case UartBaudRate::RATE_9600:
cfsetispeed(options, B9600);
cfsetospeed(options, B9600);
break;
case UartBaudRate::RATE_19200:
cfsetispeed(options, B19200);
cfsetospeed(options, B19200);
break;
case UartBaudRate::RATE_38400:
cfsetispeed(options, B38400);
cfsetospeed(options, B38400);
break;
case UartBaudRate::RATE_57600:
cfsetispeed(options, B57600);
cfsetospeed(options, B57600);
break;
case UartBaudRate::RATE_115200:
cfsetispeed(options, B115200);
cfsetospeed(options, B115200);
break;
case UartBaudRate::RATE_230400:
cfsetispeed(options, B230400);
cfsetospeed(options, B230400);
break;
#ifndef __APPLE__
case UartBaudRate::RATE_460800:
cfsetispeed(options, B460800);
cfsetospeed(options, B460800);
break;
case UartBaudRate::RATE_500000:
cfsetispeed(options, B500000);
cfsetospeed(options, B500000);
break;
case UartBaudRate::RATE_576000:
cfsetispeed(options, B576000);
cfsetospeed(options, B576000);
break;
case UartBaudRate::RATE_921600:
cfsetispeed(options, B921600);
cfsetospeed(options, B921600);
break;
case UartBaudRate::RATE_1000000:
cfsetispeed(options, B1000000);
cfsetospeed(options, B1000000);
break;
case UartBaudRate::RATE_1152000:
cfsetispeed(options, B1152000);
cfsetospeed(options, B1152000);
break;
case UartBaudRate::RATE_1500000:
cfsetispeed(options, B1500000);
cfsetospeed(options, B1500000);
break;
case UartBaudRate::RATE_2000000:
cfsetispeed(options, B2000000);
cfsetospeed(options, B2000000);
break;
case UartBaudRate::RATE_2500000:
cfsetispeed(options, B2500000);
cfsetospeed(options, B2500000);
break;
case UartBaudRate::RATE_3000000:
cfsetispeed(options, B3000000);
cfsetospeed(options, B3000000);
break;
case UartBaudRate::RATE_3500000:
cfsetispeed(options, B3500000);
cfsetospeed(options, B3500000);
break;
case UartBaudRate::RATE_4000000:
cfsetispeed(options, B4000000);
cfsetospeed(options, B4000000);
break;
#endif // ! __APPLE__
default:
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
#endif
break;
}
}
ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
int fd = 0; int fd = 0;
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter;
if (sendLen == 0) { if (sendLen == 0) {
return returnvalue::OK; return returnvalue::OK;
@ -339,7 +188,7 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData,
return returnvalue::FAILED; return returnvalue::FAILED;
} }
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie); SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
if (uartCookie == nullptr) { if (uartCookie == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl; sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl;
@ -348,7 +197,7 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData,
} }
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter == uartDeviceMap.end()) { if (uartDeviceMapIter == uartDeviceMap.end()) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "UartComIF::sendMessage: Device file " << deviceFile << "not in UART map" sif::debug << "UartComIF::sendMessage: Device file " << deviceFile << "not in UART map"
@ -370,13 +219,12 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData,
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t UartComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; } ReturnValue_t SerialComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; }
ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) { ReturnValue_t SerialComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter;
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie); SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
if (uartCookie == nullptr) { if (uartCookie == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "UartComIF::requestReceiveMessage: Invalid Uart Cookie!" << std::endl; sif::debug << "UartComIF::requestReceiveMessage: Invalid Uart Cookie!" << std::endl;
@ -386,7 +234,7 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestL
UartModes uartMode = uartCookie->getUartMode(); UartModes uartMode = uartCookie->getUartMode();
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartMode == UartModes::NON_CANONICAL and requestLen == 0) { if (uartMode == UartModes::NON_CANONICAL and requestLen == 0) {
return returnvalue::OK; return returnvalue::OK;
@ -409,8 +257,8 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestL
} }
} }
ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter, ReturnValue_t SerialComIF::handleCanonicalRead(SerialCookie& uartCookie,
size_t requestLen) { UartDeviceMap::iterator& iter, size_t requestLen) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
uint8_t maxReadCycles = uartCookie.getReadCycles(); uint8_t maxReadCycles = uartCookie.getReadCycles();
uint8_t currentReadCycles = 0; uint8_t currentReadCycles = 0;
@ -467,8 +315,9 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM
return result; return result;
} }
ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter, ReturnValue_t SerialComIF::handleNoncanonicalRead(SerialCookie& uartCookie,
size_t requestLen) { UartDeviceMap::iterator& iter,
size_t requestLen) {
int fd = iter->second.fileDescriptor; int fd = iter->second.fileDescriptor;
auto bufferPtr = iter->second.replyBuffer.data(); auto bufferPtr = iter->second.replyBuffer.data();
// Size check to prevent buffer overflow // Size check to prevent buffer overflow
@ -501,11 +350,10 @@ ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie, UartDevi
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) { ReturnValue_t SerialComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) {
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter;
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie); SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
if (uartCookie == nullptr) { if (uartCookie == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl; sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl;
@ -514,7 +362,7 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
} }
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter == uartDeviceMap.end()) { if (uartDeviceMapIter == uartDeviceMap.end()) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile << " not in uart map" sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile << " not in uart map"
@ -532,10 +380,9 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) { ReturnValue_t SerialComIF::flushUartRxBuffer(CookieIF* cookie) {
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
if (uartCookie == nullptr) { if (uartCookie == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::flushUartRxBuffer: Invalid uart cookie!" << std::endl; sif::warning << "UartComIF::flushUartRxBuffer: Invalid uart cookie!" << std::endl;
@ -543,7 +390,7 @@ ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) {
return NULLPOINTER; return NULLPOINTER;
} }
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter != uartDeviceMap.end()) { if (uartDeviceMapIter != uartDeviceMap.end()) {
int fd = uartDeviceMapIter->second.fileDescriptor; int fd = uartDeviceMapIter->second.fileDescriptor;
tcflush(fd, TCIFLUSH); tcflush(fd, TCIFLUSH);
@ -552,10 +399,9 @@ ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) { ReturnValue_t SerialComIF::flushUartTxBuffer(CookieIF* cookie) {
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
if (uartCookie == nullptr) { if (uartCookie == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::flushUartTxBuffer: Invalid uart cookie!" << std::endl; sif::warning << "UartComIF::flushUartTxBuffer: Invalid uart cookie!" << std::endl;
@ -563,7 +409,7 @@ ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) {
return NULLPOINTER; return NULLPOINTER;
} }
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter != uartDeviceMap.end()) { if (uartDeviceMapIter != uartDeviceMap.end()) {
int fd = uartDeviceMapIter->second.fileDescriptor; int fd = uartDeviceMapIter->second.fileDescriptor;
tcflush(fd, TCOFLUSH); tcflush(fd, TCOFLUSH);
@ -572,10 +418,9 @@ ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) { ReturnValue_t SerialComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; SerialCookie* uartCookie = dynamic_cast<SerialCookie*>(cookie);
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
if (uartCookie == nullptr) { if (uartCookie == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::flushUartTxAndRxBuf: Invalid uart cookie!" << std::endl; sif::warning << "UartComIF::flushUartTxAndRxBuf: Invalid uart cookie!" << std::endl;
@ -583,7 +428,7 @@ ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
return NULLPOINTER; return NULLPOINTER;
} }
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); auto uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter != uartDeviceMap.end()) { if (uartDeviceMapIter != uartDeviceMap.end()) {
int fd = uartDeviceMapIter->second.fileDescriptor; int fd = uartDeviceMapIter->second.fileDescriptor;
tcflush(fd, TCIOFLUSH); tcflush(fd, TCIOFLUSH);
@ -591,13 +436,3 @@ ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) {
} }
return returnvalue::FAILED; return returnvalue::FAILED;
} }
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;
}
}

View File

@ -3,12 +3,12 @@
#include <fsfw/devicehandlers/DeviceCommunicationIF.h> #include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <fsfw/objectmanager/SystemObject.h> #include <fsfw/objectmanager/SystemObject.h>
#include <fsfw_hal/linux/serial/SerialCookie.h>
#include <fsfw_hal/linux/serial/helper.h>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "UartCookie.h"
/** /**
* @brief This is the communication interface to access serial ports on linux based operating * @brief This is the communication interface to access serial ports on linux based operating
* systems. * systems.
@ -18,7 +18,7 @@
* *
* @author J. Meier * @author J. Meier
*/ */
class UartComIF : public DeviceCommunicationIF, public SystemObject { class SerialComIF : public DeviceCommunicationIF, public SystemObject {
public: public:
static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART; static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART;
@ -26,9 +26,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = returnvalue::makeCode(uartRetvalId, 2); static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = returnvalue::makeCode(uartRetvalId, 2);
static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL = returnvalue::makeCode(uartRetvalId, 3); static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL = returnvalue::makeCode(uartRetvalId, 3);
UartComIF(object_id_t objectId); SerialComIF(object_id_t objectId);
virtual ~UartComIF(); virtual ~SerialComIF();
ReturnValue_t initializeInterface(CookieIF* cookie) override; ReturnValue_t initializeInterface(CookieIF* cookie) override;
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override; ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
@ -62,7 +62,6 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
}; };
using UartDeviceMap = std::unordered_map<UartDeviceFile_t, UartElements>; using UartDeviceMap = std::unordered_map<UartDeviceFile_t, UartElements>;
using UartDeviceMapIter = UartDeviceMap::iterator;
/** /**
* The uart devie map stores informations of initialized uart ports. * The uart devie map stores informations of initialized uart ports.
@ -76,20 +75,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
* uart device file, baudrate, parity, stopbits etc. * uart device file, baudrate, parity, stopbits etc.
* @return The file descriptor of the configured uart. * @return The file descriptor of the configured uart.
*/ */
int configureUartPort(UartCookie* uartCookie); int configureUartPort(SerialCookie* uartCookie);
/** void setStopBitOptions(struct termios* options, SerialCookie* uartCookie);
* @brief This function adds the parity settings to the termios options struct.
*
* @param options Pointer to termios options struct which will be modified to enable or disable
* parity checking.
* @param uartCookie Pointer to uart cookie containing the information about the desired
* parity settings.
*
*/
void setParityOptions(struct termios* options, UartCookie* uartCookie);
void setStopBitOptions(struct termios* options, UartCookie* uartCookie);
/** /**
* @brief This function sets options which are not configurable by the uartCookie. * @brief This function sets options which are not configurable by the uartCookie.
@ -99,19 +87,11 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject {
/** /**
* @brief With this function the datasize settings are added to the termios options struct. * @brief With this function the datasize settings are added to the termios options struct.
*/ */
void setDatasizeOptions(struct termios* options, UartCookie* uartCookie); void setDatasizeOptions(struct termios* options, SerialCookie* uartCookie);
/** ReturnValue_t handleCanonicalRead(SerialCookie& uartCookie, UartDeviceMap::iterator& iter,
* @brief This functions adds the baudrate specified in the uartCookie to the termios options
* struct.
*/
void configureBaudrate(struct termios* options, UartCookie* uartCookie);
void setUartMode(struct termios* options, UartCookie& uartCookie);
ReturnValue_t handleCanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
size_t requestLen); size_t requestLen);
ReturnValue_t handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter, ReturnValue_t handleNoncanonicalRead(SerialCookie& uartCookie, UartDeviceMap::iterator& iter,
size_t requestLen); size_t requestLen);
}; };

View File

@ -0,0 +1,51 @@
#include "SerialCookie.h"
#include <fsfw/serviceinterface.h>
SerialCookie::SerialCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
size_t maxReplyLen, UartModes uartMode)
: handlerId(handlerId),
deviceFile(deviceFile),
uartMode(uartMode),
baudrate(baudrate),
maxReplyLen(maxReplyLen) {}
SerialCookie::~SerialCookie() {}
UartBaudRate SerialCookie::getBaudrate() const { return baudrate; }
size_t SerialCookie::getMaxReplyLen() const { return maxReplyLen; }
std::string SerialCookie::getDeviceFile() const { return deviceFile; }
void SerialCookie::setParityOdd() { parity = Parity::ODD; }
void SerialCookie::setParityEven() { parity = Parity::EVEN; }
Parity SerialCookie::getParity() const { return parity; }
void SerialCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; }
BitsPerWord SerialCookie::getBitsPerWord() const { return bitsPerWord; }
StopBits SerialCookie::getStopBits() const { return stopBits; }
void SerialCookie::setTwoStopBits() { stopBits = StopBits::TWO_STOP_BITS; }
void SerialCookie::setOneStopBit() { stopBits = StopBits::ONE_STOP_BIT; }
UartModes SerialCookie::getUartMode() const { return uartMode; }
void SerialCookie::setReadCycles(uint8_t readCycles) { this->readCycles = readCycles; }
void SerialCookie::setToFlushInput(bool enable) { this->flushInput = enable; }
uint8_t SerialCookie::getReadCycles() const { return readCycles; }
bool SerialCookie::getInputShouldBeFlushed() { return this->flushInput; }
object_id_t SerialCookie::getHandlerId() const { return this->handlerId; }
void SerialCookie::setNoFixedSizeReply() { replySizeFixed = false; }
bool SerialCookie::isReplySizeFixed() { return replySizeFixed; }

View File

@ -3,50 +3,10 @@
#include <fsfw/devicehandlers/CookieIF.h> #include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw/objectmanager/SystemObjectIF.h> #include <fsfw/objectmanager/SystemObjectIF.h>
#include <fsfw_hal/linux/serial/helper.h>
#include <string> #include <string>
enum class Parity { NONE, EVEN, ODD };
enum class StopBits { ONE_STOP_BIT, TWO_STOP_BITS };
enum class UartModes { CANONICAL, NON_CANONICAL };
enum class BitsPerWord { BITS_5, BITS_6, BITS_7, BITS_8 };
enum class UartBaudRate {
RATE_50,
RATE_75,
RATE_110,
RATE_134,
RATE_150,
RATE_200,
RATE_300,
RATE_600,
RATE_1200,
RATE_1800,
RATE_2400,
RATE_4800,
RATE_9600,
RATE_19200,
RATE_38400,
RATE_57600,
RATE_115200,
RATE_230400,
RATE_460800,
RATE_500000,
RATE_576000,
RATE_921600,
RATE_1000000,
RATE_1152000,
RATE_1500000,
RATE_2000000,
RATE_2500000,
RATE_3000000,
RATE_3500000,
RATE_4000000
};
/** /**
* @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 * The constructor only requests for common options like the baudrate. Other options can
@ -54,7 +14,7 @@ enum class UartBaudRate {
* *
* @author J. Meier * @author J. Meier
*/ */
class UartCookie : public CookieIF { class SerialCookie : public CookieIF {
public: public:
/** /**
* @brief Constructor for the uart cookie. * @brief Constructor for the uart cookie.
@ -69,10 +29,10 @@ class UartCookie : public CookieIF {
* 8 databits (number of bits transfered with one uart frame) * 8 databits (number of bits transfered with one uart frame)
* One stop bit * One stop bit
*/ */
UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, SerialCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate,
UartBaudRate baudrate, size_t maxReplyLen); size_t maxReplyLen, UartModes uartMode = UartModes::NON_CANONICAL);
virtual ~UartCookie(); virtual ~SerialCookie();
UartBaudRate getBaudrate() const; UartBaudRate getBaudrate() const;
size_t getMaxReplyLen() const; size_t getMaxReplyLen() const;

View File

@ -0,0 +1,163 @@
#include <fsfw_hal/linux/serial/helper.h>
#include <sys/ioctl.h>
#include "fsfw/serviceinterface.h"
void uart::setMode(struct termios& options, UartModes mode) {
if (mode == UartModes::NON_CANONICAL) {
/* Disable canonical mode */
options.c_lflag &= ~ICANON;
} else if (mode == UartModes::CANONICAL) {
options.c_lflag |= ICANON;
}
}
void uart::setBaudrate(struct termios& options, UartBaudRate baud) {
switch (baud) {
case UartBaudRate::RATE_50:
cfsetspeed(&options, B50);
break;
case UartBaudRate::RATE_75:
cfsetspeed(&options, B75);
break;
case UartBaudRate::RATE_110:
cfsetspeed(&options, B110);
break;
case UartBaudRate::RATE_134:
cfsetspeed(&options, B134);
break;
case UartBaudRate::RATE_150:
cfsetspeed(&options, B150);
break;
case UartBaudRate::RATE_200:
cfsetspeed(&options, B200);
break;
case UartBaudRate::RATE_300:
cfsetspeed(&options, B300);
break;
case UartBaudRate::RATE_600:
cfsetspeed(&options, B600);
break;
case UartBaudRate::RATE_1200:
cfsetspeed(&options, B1200);
break;
case UartBaudRate::RATE_1800:
cfsetspeed(&options, B1800);
break;
case UartBaudRate::RATE_2400:
cfsetspeed(&options, B2400);
break;
case UartBaudRate::RATE_4800:
cfsetspeed(&options, B4800);
break;
case UartBaudRate::RATE_9600:
cfsetspeed(&options, B9600);
break;
case UartBaudRate::RATE_19200:
cfsetspeed(&options, B19200);
break;
case UartBaudRate::RATE_38400:
cfsetspeed(&options, B38400);
break;
case UartBaudRate::RATE_57600:
cfsetspeed(&options, B57600);
break;
case UartBaudRate::RATE_115200:
cfsetspeed(&options, B115200);
break;
case UartBaudRate::RATE_230400:
cfsetspeed(&options, B230400);
break;
#ifndef __APPLE__
case UartBaudRate::RATE_460800:
cfsetspeed(&options, B460800);
break;
case UartBaudRate::RATE_500000:
cfsetspeed(&options, B500000);
break;
case UartBaudRate::RATE_576000:
cfsetspeed(&options, B576000);
break;
case UartBaudRate::RATE_921600:
cfsetspeed(&options, B921600);
break;
case UartBaudRate::RATE_1000000:
cfsetspeed(&options, B1000000);
break;
case UartBaudRate::RATE_1152000:
cfsetspeed(&options, B1152000);
break;
case UartBaudRate::RATE_1500000:
cfsetspeed(&options, B1500000);
break;
case UartBaudRate::RATE_2000000:
cfsetspeed(&options, B2000000);
break;
case UartBaudRate::RATE_2500000:
cfsetspeed(&options, B2500000);
break;
case UartBaudRate::RATE_3000000:
cfsetspeed(&options, B3000000);
break;
case UartBaudRate::RATE_3500000:
cfsetspeed(&options, B3500000);
break;
case UartBaudRate::RATE_4000000:
cfsetspeed(&options, B4000000);
break;
#endif // ! __APPLE__
default:
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
#endif
break;
}
}
void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) {
options.c_cflag &= ~CSIZE; // Clear all the size bits
if (bits == BitsPerWord::BITS_5) {
options.c_cflag |= CS5;
} else if (bits == BitsPerWord::BITS_6) {
options.c_cflag |= CS6;
} else if (bits == BitsPerWord::BITS_7) {
options.c_cflag |= CS7;
} else if (bits == BitsPerWord::BITS_8) {
options.c_cflag |= CS8;
}
}
void uart::enableRead(struct termios& options) { options.c_cflag |= CREAD; }
void uart::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; }
void uart::setParity(struct termios& options, Parity parity) {
/* Clear parity bit */
options.c_cflag &= ~PARENB;
switch (parity) {
case Parity::EVEN:
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
break;
case Parity::ODD:
options.c_cflag |= PARENB;
options.c_cflag |= PARODD;
break;
default:
break;
}
}
int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) {
return ioctl(serialPort, TIOCGICOUNT, &icounter);
}
void uart::setStopbits(struct termios& options, StopBits bits) {
if (bits == StopBits::TWO_STOP_BITS) {
// Use two stop bits
options.c_cflag |= CSTOPB;
} else {
// Clear stop field, only one stop bit used in communication
options.c_cflag &= ~CSTOPB;
}
}

View File

@ -0,0 +1,71 @@
#ifndef FSFW_HAL_LINUX_UART_HELPER_H_
#define FSFW_HAL_LINUX_UART_HELPER_H_
#include <linux/serial.h>
#include <termios.h>
enum class Parity { NONE, EVEN, ODD };
enum class StopBits { ONE_STOP_BIT, TWO_STOP_BITS };
enum class UartModes { CANONICAL, NON_CANONICAL };
enum class BitsPerWord { BITS_5, BITS_6, BITS_7, BITS_8 };
enum class UartBaudRate {
RATE_50,
RATE_75,
RATE_110,
RATE_134,
RATE_150,
RATE_200,
RATE_300,
RATE_600,
RATE_1200,
RATE_1800,
RATE_2400,
RATE_4800,
RATE_9600,
RATE_19200,
RATE_38400,
RATE_57600,
RATE_115200,
RATE_230400,
RATE_460800,
RATE_500000,
RATE_576000,
RATE_921600,
RATE_1000000,
RATE_1152000,
RATE_1500000,
RATE_2000000,
RATE_2500000,
RATE_3000000,
RATE_3500000,
RATE_4000000
};
namespace uart {
void setMode(struct termios& options, UartModes mode);
/**
* @brief This functions adds the baudrate specified in the uartCookie to the termios options
* struct.
*/
void setBaudrate(struct termios& options, UartBaudRate baud);
void setStopbits(struct termios& options, StopBits bits);
void setBitsPerWord(struct termios& options, BitsPerWord bits);
void enableRead(struct termios& options);
void setParity(struct termios& options, Parity parity);
void ignoreCtrlLines(struct termios& options);
int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter);
} // namespace uart
#endif /* FSFW_HAL_LINUX_UART_HELPER_H_ */

View File

@ -1 +0,0 @@
target_sources(${LIB_FSFW_NAME} PUBLIC UartComIF.cpp UartCookie.cpp)

View File

@ -1,51 +0,0 @@
#include "UartCookie.h"
#include <fsfw/serviceinterface.h>
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
UartBaudRate baudrate, size_t maxReplyLen)
: handlerId(handlerId),
deviceFile(deviceFile),
uartMode(uartMode),
baudrate(baudrate),
maxReplyLen(maxReplyLen) {}
UartCookie::~UartCookie() {}
UartBaudRate UartCookie::getBaudrate() const { return baudrate; }
size_t UartCookie::getMaxReplyLen() const { return maxReplyLen; }
std::string UartCookie::getDeviceFile() const { return deviceFile; }
void UartCookie::setParityOdd() { parity = Parity::ODD; }
void UartCookie::setParityEven() { parity = Parity::EVEN; }
Parity UartCookie::getParity() const { return parity; }
void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; }
BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; }
StopBits UartCookie::getStopBits() const { return stopBits; }
void UartCookie::setTwoStopBits() { stopBits = StopBits::TWO_STOP_BITS; }
void UartCookie::setOneStopBit() { stopBits = StopBits::ONE_STOP_BIT; }
UartModes UartCookie::getUartMode() const { return uartMode; }
void UartCookie::setReadCycles(uint8_t readCycles) { this->readCycles = readCycles; }
void UartCookie::setToFlushInput(bool enable) { this->flushInput = enable; }
uint8_t UartCookie::getReadCycles() const { return readCycles; }
bool UartCookie::getInputShouldBeFlushed() { return this->flushInput; }
object_id_t UartCookie::getHandlerId() const { return this->handlerId; }
void UartCookie::setNoFixedSizeReply() { replySizeFixed = false; }
bool UartCookie::isReplySizeFixed() { return replySizeFixed; }