refactored a bit

This commit is contained in:
Robin Müller 2021-06-21 16:40:27 +02:00
parent 34db4bd8e8
commit 7d0ae8d795
No known key found for this signature in database
GPG Key ID: FC76078F520434A5
4 changed files with 100 additions and 56 deletions

View File

@ -14,7 +14,7 @@ UartComIF::UartComIF(object_id_t objectId): SystemObject(objectId){
UartComIF::~UartComIF() {}
ReturnValue_t UartComIF::initializeInterface(CookieIF * cookie) {
ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter;
@ -305,7 +305,6 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
int fd = 0;
std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter;
uint8_t* bufferPtr;
if(requestLen == 0) {
return RETURN_OK;
@ -326,57 +325,49 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
return RETURN_FAILED;
}
fd = uartDeviceMapIter->second.fileDescriptor;
bufferPtr = uartDeviceMapIter->second.replyBuffer.data();
if (uartMode == UartModes::CANONICAL) {
uint8_t maxReadCycles = uartCookie->getReadCycles();
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);
return handleCanonicalRead(*uartCookie, uartDeviceMapIter, requestLen);
}
else if (uartMode == UartModes::NON_CANONICAL) {
// Size check to prevent buffer overflow
if(requestLen > uartCookie->getMaxReplyLen()) {
// TODO: Emit warning
// TODO: Emit event
// TODO: Better returnvalue
return HasReturnvaluesIF::RETURN_FAILED;
return handleNoncanonicalRead(*uartCookie, uartDeviceMapIter, requestLen);
}
else {
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) {
return RETURN_FAILED;
}
@ -385,11 +376,46 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
" of " << requestLen << " bytes" << std::endl;
return RETURN_FAILED;
}
else {
uartDeviceMapIter->second.replyLen = bytesRead;
else if(bytesRead > 0) {
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,

View File

@ -26,6 +26,10 @@ public:
HasReturnvaluesIF::makeReturnCode(uartRetvalId, 1);
static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH =
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);
@ -99,6 +103,11 @@ private:
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_ */

View File

@ -2,9 +2,10 @@
#include <fsfw/serviceinterface/ServiceInterface.h>
UartCookie::UartCookie(std::string deviceFile, UartModes uartMode, uint32_t baudrate,
size_t maxReplyLen) :
deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate), maxReplyLen(maxReplyLen) {
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
uint32_t baudrate, size_t maxReplyLen):
handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate),
maxReplyLen(maxReplyLen) {
}
UartCookie::~UartCookie() {}
@ -82,3 +83,7 @@ uint8_t UartCookie::getReadCycles() const {
bool UartCookie::getInputShouldBeFlushed() {
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)
* 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();
@ -56,6 +57,8 @@ public:
uint8_t getBitsPerWord() const;
StopBits getStopBits() 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 user can specify how many of those read cycles are performed for one device handler
@ -92,6 +95,7 @@ public:
private:
const object_id_t handlerId;
std::string deviceFile;
const UartModes uartMode;
bool flushInput = false;