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:
commit
38afa494ce
@ -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;
|
||||||
|
@ -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() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user