Merge pull request 'UART bugfixes and improvements' (#471) from eive/fsfw:mueller/uart-improvements into development

Reviewed-on: fsfw/fsfw#471
This commit is contained in:
Jakob Meier 2021-09-08 17:19:29 +02:00
commit 38afa494ce
2 changed files with 33 additions and 13 deletions

View File

@ -1,6 +1,7 @@
#include "fsfw_hal/linux/uart/UartComIF.h" #include "UartComIF.h"
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "fsfw_hal/linux/utility.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
#include <cstring> #include <cstring>
@ -60,7 +61,13 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
struct termios options = {}; struct termios options = {};
std::string deviceFile = uartCookie->getDeviceFile(); std::string deviceFile = uartCookie->getDeviceFile();
int fd = open(deviceFile.c_str(), O_RDWR); int flags = O_RDWR;
if(uartCookie->getUartMode() == UartModes::CANONICAL) {
// In non-canonical mode, don't specify O_NONBLOCK because these properties will be
// controlled by the VTIME and VMIN parameters and O_NONBLOCK would override this
flags |= O_NONBLOCK;
}
int fd = open(deviceFile.c_str(), flags);
if (fd < 0) { if (fd < 0) {
sif::warning << "UartComIF::configureUartPort: Failed to open uart " << deviceFile << sif::warning << "UartComIF::configureUartPort: Failed to open uart " << deviceFile <<
@ -259,23 +266,22 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki
ReturnValue_t UartComIF::sendMessage(CookieIF *cookie, ReturnValue_t UartComIF::sendMessage(CookieIF *cookie,
const uint8_t *sendData, size_t sendLen) { const uint8_t *sendData, size_t sendLen) {
int fd = 0; int fd = 0;
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; UartDeviceMapIter uartDeviceMapIter;
if(sendData == nullptr) {
sif::debug << "UartComIF::sendMessage: Send Data is nullptr" << std::endl;
return RETURN_FAILED;
}
if(sendLen == 0) { if(sendLen == 0) {
return RETURN_OK; return RETURN_OK;
} }
if(sendData == nullptr) {
sif::warning << "UartComIF::sendMessage: Send data is nullptr" << std::endl;
return RETURN_FAILED;
}
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie); UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
if(uartCookie == nullptr) { if(uartCookie == nullptr) {
sif::debug << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl; sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl;
return NULLPOINTER; return NULLPOINTER;
} }
@ -347,12 +353,13 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM
size_t maxReplySize = uartCookie.getMaxReplyLen(); size_t maxReplySize = uartCookie.getMaxReplyLen();
int fd = iter->second.fileDescriptor; int fd = iter->second.fileDescriptor;
auto bufferPtr = iter->second.replyBuffer.data(); auto bufferPtr = iter->second.replyBuffer.data();
iter->second.replyLen = 0;
do { do {
size_t allowedReadSize = 0; size_t allowedReadSize = 0;
if(currentBytesRead >= maxReplySize) { if(currentBytesRead >= maxReplySize) {
// Overflow risk. Emit warning, trigger event and break. If this happens, // Overflow risk. Emit warning, trigger event and break. If this happens,
// the reception buffer is not large enough or data is not polled often enough. // the reception buffer is not large enough or data is not polled often enough.
#if OBSW_VERBOSE_LEVEL >= 1 #if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!" sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!"
<< std::endl; << std::endl;
@ -370,8 +377,21 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM
bytesRead = read(fd, bufferPtr, allowedReadSize); bytesRead = read(fd, bufferPtr, allowedReadSize);
if (bytesRead < 0) { if (bytesRead < 0) {
// EAGAIN: No data available in non-blocking mode
if(errno != EAGAIN) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::handleCanonicalRead: read failed with code" <<
errno << ": " << strerror(errno) << std::endl;
#else
sif::printWarning("UartComIF::handleCanonicalRead: read failed with code %d: %s\n",
errno, strerror(errno));
#endif
#endif
return RETURN_FAILED; return RETURN_FAILED;
} }
}
else if(bytesRead > 0) { else if(bytesRead > 0) {
iter->second.replyLen += bytesRead; iter->second.replyLen += bytesRead;
bufferPtr += bytesRead; bufferPtr += bytesRead;

View File

@ -4,8 +4,8 @@
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
uint32_t baudrate, size_t maxReplyLen): uint32_t baudrate, size_t maxReplyLen):
handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate), handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode),
maxReplyLen(maxReplyLen) { baudrate(baudrate), maxReplyLen(maxReplyLen) {
} }
UartCookie::~UartCookie() {} UartCookie::~UartCookie() {}