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,25 +325,42 @@ 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);
}
else if (uartMode == UartModes::NON_CANONICAL) {
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; uint8_t currentReadCycles = 0;
int bytesRead = 0; int bytesRead = 0;
size_t currentBytesRead = 0; size_t currentBytesRead = 0;
size_t maxReplySize = uartCookie->getMaxReplyLen(); size_t maxReplySize = uartCookie.getMaxReplyLen();
int fd = iter->second.fileDescriptor;
auto bufferPtr = iter->second.replyBuffer.data();
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.
// TODO: Emit event
// TODO: Return error?
#if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_VERBOSE_LEVEL >= 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;
#else
sif::printWarning("UartComIF::requestReceiveMessage: "
"Next read would cause overflow!");
#endif #endif
#endif
result = UART_RX_BUFFER_TOO_SMALL;
break; break;
} }
else { else {
@ -361,20 +377,31 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
return RETURN_FAILED; return RETURN_FAILED;
} }
else if(bytesRead > 0) { else if(bytesRead > 0) {
uartDeviceMapIter->second.replyLen += bytesRead; iter->second.replyLen += bytesRead;
bufferPtr += bytesRead; bufferPtr += bytesRead;
currentBytesRead += bytesRead; currentBytesRead += bytesRead;
} }
currentReadCycles++; currentReadCycles++;
} while(bytesRead > 0 and currentReadCycles < maxReadCycles); } while(bytesRead > 0 and currentReadCycles < maxReadCycles);
} return result;
else if (uartMode == UartModes::NON_CANONICAL) { }
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 // Size check to prevent buffer overflow
if(requestLen > uartCookie->getMaxReplyLen()) { if(requestLen > uartCookie.getMaxReplyLen()) {
// TODO: Emit warning #if OBSW_VERBOSE_LEVEL >= 1
// TODO: Emit event #if FSFW_CPP_OSTREAM_ENABLED == 1
// TODO: Better returnvalue sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!"
return HasReturnvaluesIF::RETURN_FAILED; << std::endl;
#else
sif::printWarning("UartComIF::requestReceiveMessage: "
"Next read would cause overflow!");
#endif
#endif
return UART_RX_BUFFER_TOO_SMALL;
} }
int bytesRead = read(fd, bufferPtr, requestLen); int bytesRead = read(fd, bufferPtr, requestLen);
if (bytesRead < 0) { if (bytesRead < 0) {
@ -386,10 +413,9 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
return RETURN_FAILED; return RETURN_FAILED;
} }
else { else {
uartDeviceMapIter->second.replyLen = bytesRead; iter->second.replyLen = bytesRead;
} }
} return HasReturnvaluesIF::RETURN_OK;
return 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;