more bugfixes
This commit is contained in:
parent
7c42e05c23
commit
8dbc5cad48
@ -16,6 +16,14 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- If the PTME is driven in a way where it fills faster than it can be emptied, the interface
|
||||||
|
can become full during the process of a regular packet write. The interface of the PAPB VC
|
||||||
|
component was adapted to account for this partial success state. The caller must now check
|
||||||
|
for the `PARTIALLY_WRITTEN` state and must take care of finishing a write in some shape or
|
||||||
|
form before starting the next packet transfer.
|
||||||
|
|
||||||
# [v7.1.0] 2023-10-11
|
# [v7.1.0] 2023-10-11
|
||||||
|
|
||||||
- Bumped `eive-tmtc` to v5.8.0.
|
- Bumped `eive-tmtc` to v5.8.0.
|
||||||
|
@ -28,6 +28,10 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size, size_t& w
|
|||||||
if (size < 4) {
|
if (size < 4) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
// The user must call finishWrite before starting a new packet transfer.
|
||||||
|
if (partialWriteActive) {
|
||||||
|
return INCOMPLETE_PARTIAL_WRITE;
|
||||||
|
}
|
||||||
if (pollReadyForPacket()) {
|
if (pollReadyForPacket()) {
|
||||||
startPacketTransfer(ByteWidthCfg::ONE);
|
startPacketTransfer(ByteWidthCfg::ONE);
|
||||||
} else {
|
} else {
|
||||||
@ -37,7 +41,7 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size, size_t& w
|
|||||||
abortPacketTransfer();
|
abortPacketTransfer();
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
return finishWriteInternal(data, size, writtenSize);
|
return finishWriteInternal(data, 0, size, writtenSize, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PapbVcInterface::startPacketTransfer(ByteWidthCfg initWidth) {
|
void PapbVcInterface::startPacketTransfer(ByteWidthCfg initWidth) {
|
||||||
@ -53,26 +57,34 @@ bool PapbVcInterface::pollReadyForPacket() const {
|
|||||||
return (reg >> 6) & 0b1;
|
return (reg >> 6) & 0b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PapbVcInterface::finishWrite(const uint8_t* data, size_t remainingSize) {
|
ReturnValue_t PapbVcInterface::finishWrite(const uint8_t* data, size_t start,
|
||||||
|
size_t remainingSize) {
|
||||||
if (not pollReadyForPacket()) {
|
if (not pollReadyForPacket()) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
size_t dummy = 0;
|
size_t dummy = 0;
|
||||||
return finishWriteInternal(data, remainingSize, dummy);
|
return finishWriteInternal(data, start, remainingSize, dummy, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PapbVcInterface::finishWriteInternal(const uint8_t* data, size_t remainingSize,
|
ReturnValue_t PapbVcInterface::finishWriteInternal(const uint8_t* data, size_t start,
|
||||||
size_t& writtenSize) {
|
size_t remainingSize, size_t& writtenSize,
|
||||||
|
bool abortOnPartialWrite) {
|
||||||
for (size_t idx = 0; idx < remainingSize; idx++) {
|
for (size_t idx = 0; idx < remainingSize; idx++) {
|
||||||
if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
|
if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
|
||||||
if (not pollReadyForPacket()) {
|
if (not pollReadyForPacket()) {
|
||||||
writtenSize = idx;
|
writtenSize = start + idx;
|
||||||
|
partialWriteActive = true;
|
||||||
|
if (abortOnPartialWrite) {
|
||||||
|
abortPacketTransfer();
|
||||||
|
partialWriteActive = false;
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
return PARTIALLY_WRITTEN;
|
return PARTIALLY_WRITTEN;
|
||||||
}
|
}
|
||||||
abortPacketTransfer();
|
abortPacketTransfer();
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]);
|
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[start + idx]);
|
||||||
}
|
}
|
||||||
if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
|
if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
|
||||||
abortPacketTransfer();
|
abortPacketTransfer();
|
||||||
|
@ -42,8 +42,9 @@ class PapbVcInterface : public VirtualChannelIF {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) override;
|
ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) override;
|
||||||
|
|
||||||
ReturnValue_t finishWrite(const uint8_t* data, size_t remainingSize) override;
|
ReturnValue_t finishWrite(const uint8_t* data, size_t start, size_t remainingSize) override;
|
||||||
ReturnValue_t finishWriteInternal(const uint8_t* data, size_t remainingSize, size_t& writtenSize);
|
ReturnValue_t finishWriteInternal(const uint8_t* data, size_t start, size_t remainingSize,
|
||||||
|
size_t& writtenSize, bool abortOnPartialWrite);
|
||||||
|
|
||||||
void cancelTransfer() override;
|
void cancelTransfer() override;
|
||||||
|
|
||||||
@ -91,6 +92,7 @@ class PapbVcInterface : public VirtualChannelIF {
|
|||||||
|
|
||||||
std::string uioFile;
|
std::string uioFile;
|
||||||
int mapNum = 0;
|
int mapNum = 0;
|
||||||
|
bool partialWriteActive = false;
|
||||||
mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0};
|
mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0};
|
||||||
const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 10};
|
const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 10};
|
||||||
mutable struct timespec remDelay;
|
mutable struct timespec remDelay;
|
||||||
|
@ -21,11 +21,11 @@ ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size, size_t& wr
|
|||||||
|
|
||||||
uint8_t VirtualChannel::getVcid() const { return vcId; }
|
uint8_t VirtualChannel::getVcid() const { return vcId; }
|
||||||
|
|
||||||
ReturnValue_t VirtualChannel::finishWrite(const uint8_t* data, size_t remainingSize) {
|
ReturnValue_t VirtualChannel::finishWrite(const uint8_t* data, size_t start, size_t remainingSize) {
|
||||||
if (!ptme.containsVc(vcId)) {
|
if (!ptme.containsVc(vcId)) {
|
||||||
return CHANNEL_DOES_NOT_EXIST;
|
return CHANNEL_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
return ptme.getVirtChannel(vcId)->finishWrite(data, remainingSize);
|
return ptme.getVirtChannel(vcId)->finishWrite(data, start, remainingSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
||||||
@ -58,7 +58,7 @@ ReturnValue_t VirtualChannel::handleLastWriteSynchronously(const uint8_t* data,
|
|||||||
delayMs += 10;
|
delayMs += 10;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return finishWrite(data, start);
|
return finishWrite(data, start, remLen);
|
||||||
}
|
}
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF {
|
|||||||
ReturnValue_t sendNextTm(const uint8_t* data, size_t size, size_t& writtenSize);
|
ReturnValue_t sendNextTm(const uint8_t* data, size_t size, size_t& writtenSize);
|
||||||
bool isBusy() const override;
|
bool isBusy() const override;
|
||||||
ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) override;
|
ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) override;
|
||||||
ReturnValue_t finishWrite(const uint8_t* data, size_t remainingSize) override;
|
ReturnValue_t finishWrite(const uint8_t* data, size_t start, size_t remainingSize) override;
|
||||||
ReturnValue_t handleLastWriteSynchronously(const uint8_t* data, size_t start, size_t remLen,
|
ReturnValue_t handleLastWriteSynchronously(const uint8_t* data, size_t start, size_t remLen,
|
||||||
unsigned maxDelayMs);
|
unsigned maxDelayMs);
|
||||||
void cancelTransfer() override;
|
void cancelTransfer() override;
|
||||||
|
@ -14,6 +14,7 @@ class DirectTmSinkIF {
|
|||||||
|
|
||||||
static constexpr ReturnValue_t IS_BUSY = returnvalue::makeCode(CLASS_ID, 0);
|
static constexpr ReturnValue_t IS_BUSY = returnvalue::makeCode(CLASS_ID, 0);
|
||||||
static constexpr ReturnValue_t PARTIALLY_WRITTEN = returnvalue::makeCode(CLASS_ID, 1);
|
static constexpr ReturnValue_t PARTIALLY_WRITTEN = returnvalue::makeCode(CLASS_ID, 1);
|
||||||
|
static constexpr ReturnValue_t INCOMPLETE_PARTIAL_WRITE = returnvalue::makeCode(CLASS_ID, 2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implements the functionality to write to a TM sink directly
|
* @brief Implements the functionality to write to a TM sink directly
|
||||||
@ -26,7 +27,7 @@ class DirectTmSinkIF {
|
|||||||
*/
|
*/
|
||||||
virtual ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) = 0;
|
virtual ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) = 0;
|
||||||
|
|
||||||
virtual ReturnValue_t finishWrite(const uint8_t* data, size_t remainingSize) = 0;
|
virtual ReturnValue_t finishWrite(const uint8_t* data, size_t start, size_t remainingSize) = 0;
|
||||||
|
|
||||||
virtual bool isBusy() const = 0;
|
virtual bool isBusy() const = 0;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user