UART ComIF update #11

Merged
meierj merged 10 commits from mueller/master into master 2021-06-21 16:58:32 +02:00
4 changed files with 100 additions and 56 deletions
Showing only changes of commit 7d0ae8d795 - Show all commits

View File

@ -14,7 +14,7 @@ UartComIF::UartComIF(object_id_t objectId): SystemObject(objectId){
UartComIF::~UartComIF() {} UartComIF::~UartComIF() {}
ReturnValue_t UartComIF::initializeInterface(CookieIF * cookie) { ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; UartDeviceMapIter uartDeviceMapIter;
@ -305,7 +305,6 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
int fd = 0; int fd = 0;
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; UartDeviceMapIter uartDeviceMapIter;
uint8_t* bufferPtr;
if(requestLen == 0) { if(requestLen == 0) {
return RETURN_OK; return RETURN_OK;
@ -326,57 +325,49 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
return RETURN_FAILED; return RETURN_FAILED;
} }
fd = uartDeviceMapIter->second.fileDescriptor;
bufferPtr = uartDeviceMapIter->second.replyBuffer.data();
if (uartMode == UartModes::CANONICAL) { if (uartMode == UartModes::CANONICAL) {
uint8_t maxReadCycles = uartCookie->getReadCycles(); return handleCanonicalRead(*uartCookie, uartDeviceMapIter, requestLen);
uint8_t currentReadCycles = 0;
int bytesRead = 0;
size_t currentBytesRead = 0;
size_t maxReplySize = uartCookie->getMaxReplyLen();
do {
size_t allowedReadSize = 0;
if(currentBytesRead >= maxReplySize) {
// 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.
// TODO: Emit event
// TODO: Return error?
#if OBSW_VERBOSE_LEVEL >= 1
sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!"
<< std::endl;
#endif
break;
}
else {
allowedReadSize = maxReplySize - currentBytesRead;
}
bytesRead = read(fd, bufferPtr, allowedReadSize);
if (bytesRead < 0) {
return RETURN_FAILED;
}
else if (bytesRead != static_cast<int>(requestLen)) {
sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead <<
" of " << requestLen << " bytes" << std::endl;
return RETURN_FAILED;
}
else if(bytesRead > 0) {
uartDeviceMapIter->second.replyLen += bytesRead;
bufferPtr += bytesRead;
currentBytesRead += bytesRead;
}
currentReadCycles++;
} while(bytesRead > 0 and currentReadCycles < maxReadCycles);
} }
else if (uartMode == UartModes::NON_CANONICAL) { else if (uartMode == UartModes::NON_CANONICAL) {
// Size check to prevent buffer overflow return handleNoncanonicalRead(*uartCookie, uartDeviceMapIter, requestLen);
if(requestLen > uartCookie->getMaxReplyLen()) { }
// TODO: Emit warning else {
// TODO: Emit event return HasReturnvaluesIF::RETURN_FAILED;
// TODO: Better returnvalue }
return HasReturnvaluesIF::RETURN_FAILED; }
ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
size_t requestLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
uint8_t maxReadCycles = uartCookie.getReadCycles();
uint8_t currentReadCycles = 0;
int bytesRead = 0;
size_t currentBytesRead = 0;
size_t maxReplySize = uartCookie.getMaxReplyLen();
int fd = iter->second.fileDescriptor;
auto bufferPtr = iter->second.replyBuffer.data();
do {
size_t allowedReadSize = 0;
if(currentBytesRead >= maxReplySize) {
// 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.
#if OBSW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!"
<< std::endl;
#else
sif::printWarning("UartComIF::requestReceiveMessage: "
"Next read would cause overflow!");
#endif
#endif
result = UART_RX_BUFFER_TOO_SMALL;
break;
} }
int bytesRead = read(fd, bufferPtr, requestLen); else {
allowedReadSize = maxReplySize - currentBytesRead;
}
bytesRead = read(fd, bufferPtr, allowedReadSize);
if (bytesRead < 0) { if (bytesRead < 0) {
return RETURN_FAILED; return RETURN_FAILED;
} }
@ -385,11 +376,46 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
" of " << requestLen << " bytes" << std::endl; " of " << requestLen << " bytes" << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
else { else if(bytesRead > 0) {
uartDeviceMapIter->second.replyLen = bytesRead; iter->second.replyLen += bytesRead;
bufferPtr += bytesRead;
currentBytesRead += bytesRead;
} }
currentReadCycles++;
} while(bytesRead > 0 and currentReadCycles < maxReadCycles);
return result;
}
ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie &uartCookie, UartDeviceMapIter &iter,
size_t requestLen) {
int fd = iter->second.fileDescriptor;
auto bufferPtr = iter->second.replyBuffer.data();
// Size check to prevent buffer overflow
if(requestLen > uartCookie.getMaxReplyLen()) {
#if OBSW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!"
<< std::endl;
#else
sif::printWarning("UartComIF::requestReceiveMessage: "
"Next read would cause overflow!");
#endif
#endif
return UART_RX_BUFFER_TOO_SMALL;
} }
return RETURN_OK; int bytesRead = read(fd, bufferPtr, requestLen);
if (bytesRead < 0) {
return RETURN_FAILED;
}
else if (bytesRead != static_cast<int>(requestLen)) {
sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead <<
" of " << requestLen << " bytes" << std::endl;
return RETURN_FAILED;
}
else {
iter->second.replyLen = bytesRead;
}
return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie, ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie,

View File

@ -26,6 +26,10 @@ public:
HasReturnvaluesIF::makeReturnCode(uartRetvalId, 1); HasReturnvaluesIF::makeReturnCode(uartRetvalId, 1);
static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH =
HasReturnvaluesIF::makeReturnCode(uartRetvalId, 2); HasReturnvaluesIF::makeReturnCode(uartRetvalId, 2);
static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL =
HasReturnvaluesIF::makeReturnCode(uartRetvalId, 3);
static constexpr uint8_t uartSubsystemId = SUBSYSTEM_ID::HAL_UART;
UartComIF(object_id_t objectId); UartComIF(object_id_t objectId);
@ -99,6 +103,11 @@ private:
void setUartMode(struct termios* options, UartCookie& uartCookie); void setUartMode(struct termios* options, UartCookie& uartCookie);
ReturnValue_t handleCanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
size_t requestLen);
ReturnValue_t handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
size_t requestLen);
}; };
#endif /* BSP_Q7S_COMIF_UARTCOMIF_H_ */ #endif /* BSP_Q7S_COMIF_UARTCOMIF_H_ */

View File

@ -2,9 +2,10 @@
#include <fsfw/serviceinterface/ServiceInterface.h> #include <fsfw/serviceinterface/ServiceInterface.h>
UartCookie::UartCookie(std::string deviceFile, UartModes uartMode, uint32_t baudrate, UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
size_t maxReplyLen) : uint32_t baudrate, size_t maxReplyLen):
deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate), maxReplyLen(maxReplyLen) { handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate),
maxReplyLen(maxReplyLen) {
} }
UartCookie::~UartCookie() {} UartCookie::~UartCookie() {}
@ -82,3 +83,7 @@ uint8_t UartCookie::getReadCycles() const {
bool UartCookie::getInputShouldBeFlushed() { bool UartCookie::getInputShouldBeFlushed() {
return this->flushInput; return this->flushInput;
} }
object_id_t UartCookie::getHandlerId() const {
return this->handlerId;
}

View File

@ -45,7 +45,8 @@ public:
* 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(std::string deviceFile, UartModes uartMode, uint32_t baudrate, size_t maxReplyLen); UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
uint32_t baudrate, size_t maxReplyLen);
virtual ~UartCookie(); virtual ~UartCookie();
@ -56,6 +57,8 @@ public:
uint8_t getBitsPerWord() const; uint8_t getBitsPerWord() const;
StopBits getStopBits() const; StopBits getStopBits() const;
UartModes getUartMode() const; UartModes getUartMode() const;
object_id_t getHandlerId() const;
/** /**
* The UART ComIF will only perform a specified number of read cycles for the canonical mode. * The UART ComIF will only perform a specified number of read cycles for the canonical mode.
* The user can specify how many of those read cycles are performed for one device handler * The user can specify how many of those read cycles are performed for one device handler
@ -92,6 +95,7 @@ public:
private: private:
const object_id_t handlerId;
std::string deviceFile; std::string deviceFile;
const UartModes uartMode; const UartModes uartMode;
bool flushInput = false; bool flushInput = false;