Compare commits
28 Commits
2aa4af6974
...
bugfix_dhb
Author | SHA1 | Date | |
---|---|---|---|
034eb34c2e | |||
4374c7c4f4 | |||
5343844be5 | |||
e300490b93 | |||
0f811777a7 | |||
e93137939e | |||
0e7c6b117f | |||
d16c5024dc | |||
a4531e4ced | |||
97c629ad84 | |||
bf12f284fa | |||
8589f4d63a | |||
ca80589233 | |||
f2ebaed092 | |||
f0b89e98df | |||
5557d95994 | |||
fc24c9b5d8 | |||
7ef69c839c | |||
9b798d798e | |||
b13453f46b | |||
d0e322d7e2 | |||
ecde164f68 | |||
50930b41ba | |||
bf4ca56658 | |||
16ffa00155 | |||
f05295bada | |||
8199b8f359 | |||
9483c2809d |
@ -12,6 +12,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Fixes
|
||||
|
||||
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
|
||||
to false correctly because the `read` and `write` calls were missing.
|
||||
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
|
||||
of the correct unsegmented flags (0b11) as specified in the standard.
|
||||
- TC Scheduler Service 11: Add size and CRC check for contained TC.
|
||||
- Only delete health table entry in `HealthHelper` destructor if
|
||||
health table was set.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/710/files
|
||||
@ -27,6 +32,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Added
|
||||
|
||||
- `DleParser` helper class to parse DLE encoded packets from a byte stream.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/711
|
||||
- `UioMapper` is able to resolve symlinks now.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/709
|
||||
- Add new `UnsignedByteField` class
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
#include "fsfw/datapoollocal/LocalPoolVariable.h"
|
||||
#include "fsfw/devicehandlers/AcceptsDeviceResponsesIF.h"
|
||||
#include "fsfw/devicehandlers/DeviceTmReportingWrapper.h"
|
||||
@ -359,6 +360,8 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
if ((switchState == PowerSwitchIF::SWITCH_ON) || (switchState == NO_SWITCH)) {
|
||||
// NOTE: TransitionSourceMode and -SubMode are set by handleCommandedModeTransition
|
||||
childTransitionFailure = CHILD_TIMEOUT;
|
||||
transitionSourceMode = _MODE_SHUT_DOWN;
|
||||
transitionSourceSubMode = SUBMODE_NONE;
|
||||
setMode(_MODE_START_UP);
|
||||
callChildStatemachine();
|
||||
}
|
||||
@ -1506,7 +1509,10 @@ DeviceCommandId_t DeviceHandlerBase::getPendingCommand() const {
|
||||
void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() {
|
||||
for (const auto& reply : deviceReplyMap) {
|
||||
if (reply.second.dataSet != nullptr) {
|
||||
reply.second.dataSet->setValidity(false, true);
|
||||
PoolReadGuard pg(reply.second.dataSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
reply.second.dataSet->setValidity(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ target_sources(
|
||||
AsciiConverter.cpp
|
||||
CRC.cpp
|
||||
DleEncoder.cpp
|
||||
DleParser.cpp
|
||||
PeriodicOperationDivider.cpp
|
||||
timevalOperations.cpp
|
||||
Type.cpp
|
||||
|
173
src/fsfw/globalfunctions/DleParser.cpp
Normal file
173
src/fsfw/globalfunctions/DleParser.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
#include "DleParser.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
DleParser::DleParser(SimpleRingBuffer& decodeRingBuf, DleEncoder& decoder, BufPair encodedBuf,
|
||||
BufPair decodedBuf)
|
||||
: decodeRingBuf(decodeRingBuf),
|
||||
decoder(decoder),
|
||||
encodedBuf(encodedBuf),
|
||||
decodedBuf(decodedBuf) {}
|
||||
|
||||
ReturnValue_t DleParser::passData(const uint8_t* data, size_t len) {
|
||||
if (data == nullptr or len == 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return decodeRingBuf.writeData(data, len);
|
||||
}
|
||||
|
||||
ReturnValue_t DleParser::parseRingBuf(size_t& readSize) {
|
||||
ctx.setType(DleParser::ContextType::NONE);
|
||||
size_t availableData = decodeRingBuf.getAvailableReadData();
|
||||
if (availableData == 0) {
|
||||
return NO_PACKET_FOUND;
|
||||
}
|
||||
if (availableData > encodedBuf.second) {
|
||||
ErrorInfo info;
|
||||
info.len = decodeRingBuf.getAvailableReadData();
|
||||
setErrorContext(ErrorTypes::DECODING_BUF_TOO_SMALL, info);
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
ReturnValue_t result = decodeRingBuf.readData(encodedBuf.first, availableData);
|
||||
if (result != returnvalue::OK) {
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
setErrorContext(ErrorTypes::RING_BUF_ERROR, info);
|
||||
return result;
|
||||
}
|
||||
bool stxFound = false;
|
||||
size_t stxIdx = 0;
|
||||
for (size_t vectorIdx = 0; vectorIdx < availableData; vectorIdx++) {
|
||||
// handle STX char
|
||||
if (encodedBuf.first[vectorIdx] == DleEncoder::STX_CHAR) {
|
||||
if (not stxFound) {
|
||||
stxFound = true;
|
||||
stxIdx = vectorIdx;
|
||||
} else {
|
||||
// might be lost packet, so we should advance the read pointer
|
||||
// without skipping the STX
|
||||
readSize = vectorIdx;
|
||||
ErrorInfo info;
|
||||
setErrorContext(ErrorTypes::CONSECUTIVE_STX_CHARS, info);
|
||||
return POSSIBLE_PACKET_LOSS;
|
||||
}
|
||||
}
|
||||
// handle ETX char
|
||||
if (encodedBuf.first[vectorIdx] == DleEncoder::ETX_CHAR) {
|
||||
if (stxFound) {
|
||||
// This is propably a packet, so we decode it.
|
||||
size_t decodedLen = 0;
|
||||
size_t dummy = 0;
|
||||
|
||||
ReturnValue_t result =
|
||||
decoder.decode(&encodedBuf.first[stxIdx], availableData - stxIdx, &dummy,
|
||||
decodedBuf.first, decodedBuf.second, &decodedLen);
|
||||
if (result == returnvalue::OK) {
|
||||
ctx.setType(ContextType::PACKET_FOUND);
|
||||
ctx.decodedPacket.first = decodedBuf.first;
|
||||
ctx.decodedPacket.second = decodedLen;
|
||||
readSize = ++vectorIdx;
|
||||
return returnvalue::OK;
|
||||
} else {
|
||||
// invalid packet, skip.
|
||||
readSize = ++vectorIdx;
|
||||
ErrorInfo info;
|
||||
info.res = result;
|
||||
setErrorContext(ErrorTypes::DECODE_ERROR, info);
|
||||
return POSSIBLE_PACKET_LOSS;
|
||||
}
|
||||
} else {
|
||||
// might be lost packet, so we should advance the read pointer
|
||||
readSize = ++vectorIdx;
|
||||
ErrorInfo info;
|
||||
info.len = 0;
|
||||
setErrorContext(ErrorTypes::CONSECUTIVE_ETX_CHARS, info);
|
||||
return POSSIBLE_PACKET_LOSS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NO_PACKET_FOUND;
|
||||
}
|
||||
|
||||
void DleParser::defaultFoundPacketHandler(uint8_t* packet, size_t len, void* args) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "DleParserBase::handleFoundPacket: Detected DLE packet with " << len << " bytes"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printInfo("DleParserBase::handleFoundPacket: Detected DLE packet with %d bytes\n", len);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void DleParser::defaultErrorHandler() {
|
||||
if (ctx.getType() != DleParser::ContextType::ERROR) {
|
||||
errorPrinter("No error");
|
||||
return;
|
||||
}
|
||||
switch (ctx.error.first) {
|
||||
case (ErrorTypes::NONE): {
|
||||
errorPrinter("No error");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::DECODE_ERROR): {
|
||||
errorPrinter("Decode Error");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::RING_BUF_ERROR): {
|
||||
errorPrinter("Ring Buffer Error");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::ENCODED_BUF_TOO_SMALL):
|
||||
case (ErrorTypes::DECODING_BUF_TOO_SMALL): {
|
||||
char opt[64];
|
||||
snprintf(opt, sizeof(opt), ": Too small for packet with length %zu",
|
||||
ctx.decodedPacket.second);
|
||||
if (ctx.error.first == ErrorTypes::ENCODED_BUF_TOO_SMALL) {
|
||||
errorPrinter("Encoded buf too small", opt);
|
||||
} else {
|
||||
errorPrinter("Decoding buf too small", opt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::CONSECUTIVE_STX_CHARS): {
|
||||
errorPrinter("Consecutive STX chars detected");
|
||||
break;
|
||||
}
|
||||
case (ErrorTypes::CONSECUTIVE_ETX_CHARS): {
|
||||
errorPrinter("Consecutive ETX chars detected");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DleParser::errorPrinter(const char* str, const char* opt) {
|
||||
if (opt == nullptr) {
|
||||
opt = "";
|
||||
}
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "DleParserBase::handleParseError: " << str << opt << std::endl;
|
||||
#else
|
||||
sif::printInfo("DleParserBase::handleParseError: %s%s\n", str, opt);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void DleParser::setErrorContext(ErrorTypes err, ErrorInfo info) {
|
||||
ctx.setType(ContextType::ERROR);
|
||||
ctx.error.first = err;
|
||||
ctx.error.second = info;
|
||||
}
|
||||
|
||||
ReturnValue_t DleParser::confirmBytesRead(size_t bytesRead) {
|
||||
return decodeRingBuf.deleteData(bytesRead);
|
||||
}
|
||||
|
||||
const DleParser::Context& DleParser::getContext() { return ctx; }
|
||||
|
||||
void DleParser::reset() { decodeRingBuf.clear(); }
|
127
src/fsfw/globalfunctions/DleParser.h
Normal file
127
src/fsfw/globalfunctions/DleParser.h
Normal file
@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw/container/SimpleRingBuffer.h>
|
||||
#include <fsfw/globalfunctions/DleEncoder.h>
|
||||
#include <fsfw/returnvalues/returnvalue.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* @brief This base helper class can be used to extract DLE encoded packets from a data stream
|
||||
* @details
|
||||
* The core API of the parser takes received packets which can contains DLE packets. The parser
|
||||
* can deal with DLE packets split across multiple packets. It does so by using a dedicated
|
||||
* decoding ring buffer. The user can process received packets and detect errors by
|
||||
* overriding two provided virtual methods. This also allows detecting multiple DLE packets
|
||||
* inside one passed packet.
|
||||
*/
|
||||
class DleParser {
|
||||
public:
|
||||
static constexpr ReturnValue_t NO_PACKET_FOUND = returnvalue::makeCode(1, 1);
|
||||
static constexpr ReturnValue_t POSSIBLE_PACKET_LOSS = returnvalue::makeCode(1, 2);
|
||||
using BufPair = std::pair<uint8_t*, size_t>;
|
||||
|
||||
enum class ContextType { NONE, PACKET_FOUND, ERROR };
|
||||
|
||||
enum class ErrorTypes {
|
||||
NONE,
|
||||
ENCODED_BUF_TOO_SMALL,
|
||||
DECODING_BUF_TOO_SMALL,
|
||||
DECODE_ERROR,
|
||||
RING_BUF_ERROR,
|
||||
CONSECUTIVE_STX_CHARS,
|
||||
CONSECUTIVE_ETX_CHARS
|
||||
};
|
||||
|
||||
union ErrorInfo {
|
||||
size_t len;
|
||||
ReturnValue_t res;
|
||||
};
|
||||
|
||||
using ErrorPair = std::pair<ErrorTypes, ErrorInfo>;
|
||||
|
||||
struct Context {
|
||||
public:
|
||||
Context() { setType(ContextType::PACKET_FOUND); }
|
||||
|
||||
void setType(ContextType type) {
|
||||
this->type = type;
|
||||
if (type == ContextType::PACKET_FOUND) {
|
||||
error.first = ErrorTypes::NONE;
|
||||
error.second.len = 0;
|
||||
} else {
|
||||
decodedPacket.first = nullptr;
|
||||
decodedPacket.second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ContextType getType() const { return type; }
|
||||
|
||||
BufPair decodedPacket = {};
|
||||
ErrorPair error;
|
||||
|
||||
private:
|
||||
ContextType type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class constructor
|
||||
* @param decodeRingBuf Ring buffer used to store multiple packets to allow detecting DLE packets
|
||||
* split across multiple packets
|
||||
* @param decoder Decoder instance
|
||||
* @param encodedBuf Buffer used to store encoded packets. It has to be large enough to hold
|
||||
* the largest expected encoded DLE packet size
|
||||
* @param decodedBuf Buffer used to store decoded packets. It has to be large enough to hold the
|
||||
* largest expected decoded DLE packet size
|
||||
* @param handler Function which will be called on a found packet
|
||||
* @param args Arbitrary user argument
|
||||
*/
|
||||
DleParser(SimpleRingBuffer& decodeRingBuf, DleEncoder& decoder, BufPair encodedBuf,
|
||||
BufPair decodedBuf);
|
||||
|
||||
/**
|
||||
* This function allows to pass new data into the parser. It then scans for DLE packets
|
||||
* automatically and inserts (part of) the packet into a ring buffer if necessary.
|
||||
* @param data
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t passData(const uint8_t* data, size_t len);
|
||||
|
||||
ReturnValue_t parseRingBuf(size_t& bytesRead);
|
||||
|
||||
ReturnValue_t confirmBytesRead(size_t bytesRead);
|
||||
|
||||
const Context& getContext();
|
||||
/**
|
||||
* Example found packet handler
|
||||
* function call
|
||||
* @param packet Decoded packet
|
||||
* @param len Length of detected packet
|
||||
*/
|
||||
void defaultFoundPacketHandler(uint8_t* packet, size_t len, void* args);
|
||||
/**
|
||||
* Will be called if an error occured in the #passData call
|
||||
* @param err
|
||||
* @param ctx Context information depending on the error type
|
||||
* - For buffer length errors, will be set to the detected packet length which is too large
|
||||
* - For decode or ring buffer errors, will be set to the result returned from the failed call
|
||||
*/
|
||||
void defaultErrorHandler();
|
||||
|
||||
static void errorPrinter(const char* str, const char* opt = nullptr);
|
||||
|
||||
void setErrorContext(ErrorTypes err, ErrorInfo ctx);
|
||||
/**
|
||||
* Resets the parser by resetting the internal states and clearing the decoding ring buffer
|
||||
*/
|
||||
void reset();
|
||||
|
||||
private:
|
||||
SimpleRingBuffer& decodeRingBuf;
|
||||
DleEncoder& decoder;
|
||||
BufPair encodedBuf;
|
||||
BufPair decodedBuf;
|
||||
Context ctx;
|
||||
};
|
@ -41,6 +41,8 @@ class Service11TelecommandScheduling final : public PusServiceBase {
|
||||
static constexpr ReturnValue_t INVALID_TIME_WINDOW = returnvalue::makeCode(CLASS_ID, 2);
|
||||
static constexpr ReturnValue_t TIMESHIFTING_NOT_POSSIBLE = returnvalue::makeCode(CLASS_ID, 3);
|
||||
static constexpr ReturnValue_t INVALID_RELATIVE_TIME = returnvalue::makeCode(CLASS_ID, 4);
|
||||
static constexpr ReturnValue_t CONTAINED_TC_TOO_SMALL = returnvalue::makeCode(CLASS_ID, 5);
|
||||
static constexpr ReturnValue_t CONTAINED_TC_CRC_MISSMATCH = returnvalue::makeCode(CLASS_ID, 6);
|
||||
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_11;
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "fsfw/tmtcpacket/pus/tc/PusTcIF.h"
|
||||
#include "fsfw/globalfunctions/CRC.h"
|
||||
|
||||
static constexpr auto DEF_END = SerializeIF::Endianness::BIG;
|
||||
|
||||
@ -171,6 +173,14 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
if (size < PusTcIF::MIN_SIZE) {
|
||||
return CONTAINED_TC_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (CRC::crc16ccitt(data, size) != 0) {
|
||||
return CONTAINED_TC_CRC_MISSMATCH;
|
||||
}
|
||||
|
||||
// store currentPacket and receive the store address
|
||||
store_address_t addr{};
|
||||
if (tcStore->addData(&addr, data, size) != returnvalue::OK ||
|
||||
|
@ -100,5 +100,6 @@ ReturnValue_t PusTcCreator::setSerializableUserData(const SerializeIF &serializa
|
||||
void PusTcCreator::setup() {
|
||||
spCreator.setPacketType(ccsds::PacketType::TC);
|
||||
spCreator.setSecHeaderFlag();
|
||||
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
|
||||
updateSpLengthField();
|
||||
}
|
||||
|
@ -119,6 +119,7 @@ void PusTmCreator::setup() {
|
||||
updateSpLengthField();
|
||||
spCreator.setPacketType(ccsds::PacketType::TM);
|
||||
spCreator.setSecHeaderFlag();
|
||||
spCreator.setSeqFlags(ccsds::SequenceFlags::UNSEGMENTED);
|
||||
}
|
||||
|
||||
void PusTmCreator::setMessageTypeCounter(uint16_t messageTypeCounter) {
|
||||
|
@ -5,20 +5,28 @@
|
||||
|
||||
class SourceSequenceCounter {
|
||||
private:
|
||||
uint16_t sequenceCount;
|
||||
uint16_t sequenceCount = 0;
|
||||
|
||||
public:
|
||||
SourceSequenceCounter() : sequenceCount(0) {}
|
||||
void increment() {
|
||||
sequenceCount = (sequenceCount + 1) % (SpacePacketBase::LIMIT_SEQUENCE_COUNT);
|
||||
SourceSequenceCounter(uint16_t initialSequenceCount = 0) : sequenceCount(initialSequenceCount) {}
|
||||
void increment() { sequenceCount = (sequenceCount + 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||
void decrement() { sequenceCount = (sequenceCount - 1) % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||
uint16_t get() const { return this->sequenceCount; }
|
||||
void reset(uint16_t toValue = 0) { sequenceCount = toValue % (ccsds::LIMIT_SEQUENCE_COUNT); }
|
||||
SourceSequenceCounter& operator++(int) {
|
||||
this->increment();
|
||||
return *this;
|
||||
}
|
||||
void decrement() {
|
||||
sequenceCount = (sequenceCount - 1) % (SpacePacketBase::LIMIT_SEQUENCE_COUNT);
|
||||
SourceSequenceCounter& operator--(int) {
|
||||
this->decrement();
|
||||
return *this;
|
||||
}
|
||||
uint16_t get() { return this->sequenceCount; }
|
||||
void reset(uint16_t toValue = 0) {
|
||||
sequenceCount = toValue % (SpacePacketBase::LIMIT_SEQUENCE_COUNT);
|
||||
SourceSequenceCounter& operator=(const uint16_t& newCount) {
|
||||
sequenceCount = newCount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator uint16_t() { return this->get(); }
|
||||
};
|
||||
|
||||
#endif /* FSFW_TMTCSERVICES_SOURCESEQUENCECOUNTER_H_ */
|
||||
|
@ -32,6 +32,8 @@ ReturnValue_t CommandExecutor::execute() {
|
||||
} else if (state == States::PENDING) {
|
||||
return COMMAND_PENDING;
|
||||
}
|
||||
// Reset data in read vector
|
||||
std::memset(readVec.data(), 0, readVec.size());
|
||||
currentCmdFile = popen(currentCmd.c_str(), "r");
|
||||
if (currentCmdFile == nullptr) {
|
||||
lastError = errno;
|
||||
@ -205,3 +207,5 @@ ReturnValue_t CommandExecutor::executeBlocking() {
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
const std::vector<char>& CommandExecutor::getReadVector() const { return readVec; }
|
||||
|
@ -107,6 +107,8 @@ class CommandExecutor {
|
||||
*/
|
||||
void reset();
|
||||
|
||||
const std::vector<char>& getReadVector() const;
|
||||
|
||||
private:
|
||||
std::string currentCmd;
|
||||
bool blocking = true;
|
||||
|
@ -168,12 +168,18 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
|
||||
int readLen = read(fd, replyBuffer, requestLen);
|
||||
if (readLen != static_cast<int>(requestLen)) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1 and FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "I2cComIF::requestReceiveMessage: Reading from I2C "
|
||||
<< "device failed with error code " << errno << ". Description"
|
||||
<< " of error: " << strerror(errno) << std::endl;
|
||||
sif::error << "I2cComIF::requestReceiveMessage: Read only " << readLen << " from " << requestLen
|
||||
<< " bytes" << std::endl;
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
if (readLen < 0) {
|
||||
sif::warning << "I2cComIF::requestReceiveMessage: Reading from I2C "
|
||||
<< "device failed with error code " << errno << " | " << strerror(errno)
|
||||
<< std::endl;
|
||||
} else {
|
||||
sif::warning << "I2cComIF::requestReceiveMessage: Read only " << readLen << " from "
|
||||
<< requestLen << " bytes" << std::endl;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
#endif
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::debug << "I2cComIF::requestReceiveMessage: Read " << readLen << " of " << requestLen
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace addresses {
|
||||
/* Logical addresses have uint32_t datatype */
|
||||
enum logicalAddresses : address_t {};
|
||||
enum LogicAddress : address_t {};
|
||||
} // namespace addresses
|
||||
|
||||
#endif /* CONFIG_DEVICES_LOGICALADDRESSES_H_ */
|
||||
|
Reference in New Issue
Block a user