some tweaks for busy handling #500

Merged
muellerr merged 28 commits from tweak_papb_busy_polling into develop 2023-03-24 14:15:01 +01:00
16 changed files with 65 additions and 31 deletions
Showing only changes of commit 45054cc863 - Show all commits

View File

@ -186,19 +186,19 @@ void scheduling::initTasks() {
scheduling::printAddObjectError("LIVE_TM", objects::LIVE_TM_TASK); scheduling::printAddObjectError("LIVE_TM", objects::LIVE_TM_TASK);
} }
PeriodicTaskIF* logTmTask = factory->createPeriodicTask( PeriodicTaskIF* logTmTask = factory->createPeriodicTask(
"LOG_PSTORE", 15, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr); "LOG_PSTORE", 120, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
result = logTmTask->addComponent(objects::LOG_STORE_AND_TM_TASK); result = logTmTask->addComponent(objects::LOG_STORE_AND_TM_TASK);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
scheduling::printAddObjectError("LOG_STORE_AND_TM", objects::LOG_STORE_AND_TM_TASK); scheduling::printAddObjectError("LOG_STORE_AND_TM", objects::LOG_STORE_AND_TM_TASK);
} }
PeriodicTaskIF* hkTmTask = factory->createPeriodicTask( PeriodicTaskIF* hkTmTask = factory->createPeriodicTask(
"HK_PSTORE", 15, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr); "HK_PSTORE", 120, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
result = hkTmTask->addComponent(objects::HK_STORE_AND_TM_TASK); result = hkTmTask->addComponent(objects::HK_STORE_AND_TM_TASK);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
scheduling::printAddObjectError("HK_STORE_AND_TM", objects::HK_STORE_AND_TM_TASK); scheduling::printAddObjectError("HK_STORE_AND_TM", objects::HK_STORE_AND_TM_TASK);
} }
PeriodicTaskIF* cfdpTmTask = factory->createPeriodicTask( PeriodicTaskIF* cfdpTmTask = factory->createPeriodicTask(
"CFDP_PSTORE", 15, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr); "CFDP_PSTORE", 120, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
result = cfdpTmTask->addComponent(objects::CFDP_STORE_AND_TM_TASK); result = cfdpTmTask->addComponent(objects::CFDP_STORE_AND_TM_TASK);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
scheduling::printAddObjectError("CFDP_STORE_AND_TM", objects::CFDP_STORE_AND_TM_TASK); scheduling::printAddObjectError("CFDP_STORE_AND_TM", objects::CFDP_STORE_AND_TM_TASK);

2
fsfw

@ -1 +1 @@
Subproject commit 33ac395072f0145b6e80e12deae978a5e0432f08 Subproject commit db4587bb59603bdc83e6720193fd1782649a0678

View File

@ -26,19 +26,24 @@ ReturnValue_t PapbVcInterface::initialize() {
} }
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) { ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
if (pollPapbBusySignal() == returnvalue::OK) { if (pollPapbBusySignal(0, 0) == returnvalue::OK) {
startPacketTransfer(); startPacketTransfer();
} else {
return DirectTmSinkIF::IS_BUSY;
} }
for (size_t idx = 0; idx < size; idx++) { for (size_t idx = 0; idx < size; idx++) {
if (pollPapbBusySignal() == returnvalue::OK) { if (pollPapbBusySignal(10, 10) == returnvalue::OK) {
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]); *(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]);
} else { } else {
abortPacketTransfer(); abortPacketTransfer();
return DirectTmSinkIF::IS_BUSY; return returnvalue::FAILED;
} }
} }
if (pollPapbBusySignal() == returnvalue::OK) { if (pollPapbBusySignal(10, 10) == returnvalue::OK) {
completePacketTransfer(); completePacketTransfer();
} else {
abortPacketTransfer();
return returnvalue::FAILED;
} }
return returnvalue::OK; return returnvalue::OK;
} }
@ -47,11 +52,11 @@ void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; }
void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; } void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; }
ReturnValue_t PapbVcInterface::pollPapbBusySignal() const { ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries,
uint32_t retryDelayUs) const {
gpio::Levels papbBusyState = gpio::Levels::LOW; gpio::Levels papbBusyState = gpio::Levels::LOW;
ReturnValue_t result; ReturnValue_t result;
uint32_t busyIdx = 0; uint32_t busyIdx = 0;
uint32_t delayCount = 0;
while (true) { while (true) {
/** Check if PAPB interface is ready to receive data */ /** Check if PAPB interface is ready to receive data */
@ -64,16 +69,13 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal() const {
if (papbBusyState == gpio::Levels::HIGH) { if (papbBusyState == gpio::Levels::HIGH) {
return returnvalue::OK; return returnvalue::OK;
} }
if (busyIdx == 3) {
usleep(100); busyIdx++;
busyIdx = 0; if (busyIdx >= maxPollRetries) {
delayCount += 1;
continue;
}
if (delayCount == 1000) {
return PAPB_BUSY; return PAPB_BUSY;
} }
busyIdx++;
usleep(retryDelayUs);
} }
return returnvalue::OK; return returnvalue::OK;
} }
@ -98,7 +100,9 @@ void PapbVcInterface::isVcInterfaceBufferEmpty() {
return; return;
} }
bool PapbVcInterface::isBusy() const { return pollPapbBusySignal() == PAPB_BUSY; } bool PapbVcInterface::isBusy() const { return pollPapbBusySignal(0, 0) == PAPB_BUSY; }
void PapbVcInterface::cancelTransfer() { abortPacketTransfer(); }
ReturnValue_t PapbVcInterface::sendTestFrame() { ReturnValue_t PapbVcInterface::sendTestFrame() {
/** Size of one complete transfer frame data field amounts to 1105 bytes */ /** Size of one complete transfer frame data field amounts to 1105 bytes */

View File

@ -41,6 +41,8 @@ class PapbVcInterface : public VirtualChannelIF {
*/ */
ReturnValue_t write(const uint8_t* data, size_t size) override; ReturnValue_t write(const uint8_t* data, size_t size) override;
void cancelTransfer() override;
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
private: private:
@ -109,7 +111,7 @@ class PapbVcInterface : public VirtualChannelIF {
* *
* @return returnvalue::OK when ready to receive data else PAPB_BUSY. * @return returnvalue::OK when ready to receive data else PAPB_BUSY.
*/ */
ReturnValue_t pollPapbBusySignal() const; ReturnValue_t pollPapbBusySignal(uint32_t maxPollRetries, uint32_t retryDelayUs) const;
/** /**
* @brief This function can be used for debugging to check whether there are packets in * @brief This function can be used for debugging to check whether there are packets in

View File

@ -20,7 +20,6 @@ ReturnValue_t Ptme::initialize() {
} }
ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t* data, size_t size) { ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t* data, size_t size) {
ReturnValue_t result = returnvalue::OK;
VcInterfaceMapIter vcInterfaceMapIter = vcInterfaceMap.find(vcId); VcInterfaceMapIter vcInterfaceMapIter = vcInterfaceMap.find(vcId);
if (vcInterfaceMapIter == vcInterfaceMap.end()) { if (vcInterfaceMapIter == vcInterfaceMap.end()) {
sif::warning << "Ptme::writeToVc: No virtual channel interface found for the virtual " sif::warning << "Ptme::writeToVc: No virtual channel interface found for the virtual "
@ -28,8 +27,7 @@ ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t* data, size_t size) {
<< static_cast<unsigned int>(vcId) << std::endl; << static_cast<unsigned int>(vcId) << std::endl;
return UNKNOWN_VC_ID; return UNKNOWN_VC_ID;
} }
result = vcInterfaceMapIter->second->write(data, size); return vcInterfaceMapIter->second->write(data, size);
return result;
} }
void Ptme::addVcInterface(VcId_t vcId, VirtualChannelIF* vc) { void Ptme::addVcInterface(VcId_t vcId, VirtualChannelIF* vc) {
@ -62,3 +60,11 @@ bool Ptme::isBusy(uint8_t vcId) const {
} }
return vcInterfaceMapIter->second->isBusy(); return vcInterfaceMapIter->second->isBusy();
} }
void Ptme::cancelTransfer(uint8_t vcId) {
VcInterfaceMapIter vcInterfaceMapIter = vcInterfaceMap.find(vcId);
if (vcInterfaceMapIter == vcInterfaceMap.end()) {
return;
}
return vcInterfaceMapIter->second->cancelTransfer();
}

View File

@ -36,6 +36,7 @@ class Ptme : public PtmeIF, public SystemObject {
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) override; ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) override;
bool isBusy(uint8_t vcId) const override; bool isBusy(uint8_t vcId) const override;
void cancelTransfer(uint8_t vcId) override;
/** /**
* @brief This function adds the reference to a virtual channel interface to the vcInterface * @brief This function adds the reference to a virtual channel interface to the vcInterface

View File

@ -23,6 +23,7 @@ class PtmeIF {
*/ */
virtual ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) = 0; virtual ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) = 0;
virtual bool isBusy(uint8_t vcId) const = 0; virtual bool isBusy(uint8_t vcId) const = 0;
virtual void cancelTransfer(uint8_t vcId) = 0;
}; };
#endif /* LINUX_OBC_PTMEIF_H_ */ #endif /* LINUX_OBC_PTMEIF_H_ */

View File

@ -18,6 +18,7 @@ class VirtualChannelIF : public DirectTmSinkIF {
virtual ~VirtualChannelIF(){}; virtual ~VirtualChannelIF(){};
virtual ReturnValue_t initialize() = 0; virtual ReturnValue_t initialize() = 0;
virtual void cancelTransfer() = 0;
}; };
#endif /* LINUX_OBC_VCINTERFACEIF_H_ */ #endif /* LINUX_OBC_VCINTERFACEIF_H_ */

View File

@ -206,6 +206,8 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; } void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; }
void CcsdsIpCoreHandler::enableTransmit() { void CcsdsIpCoreHandler::enableTransmit() {
// Reset PTME on each transmit enable.
updateBatPriorityFromParam();
#ifndef TE0720_1CFA #ifndef TE0720_1CFA
gpioIF->pullHigh(ptmeGpios.enableTxClock); gpioIF->pullHigh(ptmeGpios.enableTxClock);
gpioIF->pullHigh(ptmeGpios.enableTxData); gpioIF->pullHigh(ptmeGpios.enableTxData);

View File

@ -32,10 +32,10 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
stateHandlingForStore(handleOneStore(stores.notOkStore, notOkStoreContext)); stateHandlingForStore(handleOneStore(stores.notOkStore, notOkStoreContext));
stateHandlingForStore(handleOneStore(stores.miscStore, miscStoreContext)); stateHandlingForStore(handleOneStore(stores.miscStore, miscStoreContext));
if (not someonesBusy) { if (not someonesBusy) {
TaskFactory::delayTask(40); TaskFactory::delayTask(100);
} else if (someFileWasSwapped and graceDelayDuringDumping.hasTimedOut()) { } else /* and graceDelayDuringDumping.hasTimedOut()*/ {
if (someFileWasSwapped) { if (someFileWasSwapped) {
TaskFactory::delayTask(1); TaskFactory::delayTask(20);
} }
// TaskFactory::delayTask(2); // TaskFactory::delayTask(2);
// graceDelayDuringDumping.resetTimer(); // graceDelayDuringDumping.resetTimer();

View File

@ -17,10 +17,10 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
} }
bool busy = handleOneStore(storeWithQueue, dumpContext); bool busy = handleOneStore(storeWithQueue, dumpContext);
if (not busy) { if (not busy) {
TaskFactory::delayTask(40); TaskFactory::delayTask(100);
} else { } else {
if (fileHasSwapped) { if (fileHasSwapped) {
TaskFactory::delayTask(1); TaskFactory::delayTask(20);
} }
// if (fileHasSwapped and graceDelayDuringDumping.hasTimedOut()) { // if (fileHasSwapped and graceDelayDuringDumping.hasTimedOut()) {
// TaskFactory::delayTask(2); // TaskFactory::delayTask(2);

View File

@ -218,7 +218,7 @@ ReturnValue_t PersistentTmStore::loadNextDumpFile() {
} }
// sif::debug << "Path: " << dumpParams.dirEntry.path() << std::endl; // sif::debug << "Path: " << dumpParams.dirEntry.path() << std::endl;
// Can't even read CCSDS header. // File empty or can't even read CCSDS header.
if (dumpParams.fileSize <= 6) { if (dumpParams.fileSize <= 6) {
continue; continue;
} }

View File

@ -29,7 +29,7 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store,
tmSinkBusyCd.resetTimer(); tmSinkBusyCd.resetTimer();
result = store.dumpNextPacket(channel, dumpedLen, fileHasSwapped); result = store.dumpNextPacket(channel, dumpedLen, fileHasSwapped);
if (result == DirectTmSinkIF::IS_BUSY) { if (result == DirectTmSinkIF::IS_BUSY) {
sif::warning << "PersistentTmStore: PAPB was too busy for dump" << std::endl; sif::warning << "Unexpected PAPB busy" << std::endl;
} }
if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK) and dumpedLen > 0) { if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK) and dumpedLen > 0) {
dumpContext.dumpedBytes += dumpedLen; dumpContext.dumpedBytes += dumpedLen;
@ -45,6 +45,13 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store,
} else if (result == returnvalue::OK) { } else if (result == returnvalue::OK) {
dumpsPerformed = true; dumpsPerformed = true;
} }
} else {
dumpContext.ptmeBusyCounter++;
if (dumpContext.ptmeBusyCounter == 50) {
sif::warning << "PTME busy for longer period. Dumped length so far: "
<< dumpContext.dumpedBytes << std::endl;
dumpContext.ptmeBusyCounter = 0;
}
} }
if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) { if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) {
triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId()); triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId());

View File

@ -16,6 +16,7 @@ class TmStoreTaskBase : public SystemObject {
const Event eventIfDone; const Event eventIfDone;
uint32_t numberOfDumpedPackets = 0; uint32_t numberOfDumpedPackets = 0;
uint32_t dumpedBytes = 0; uint32_t dumpedBytes = 0;
uint32_t ptmeBusyCounter = 0;
}; };
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel, TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel,

View File

@ -25,4 +25,12 @@ uint8_t VirtualChannel::getVcid() const { return vcId; }
const char* VirtualChannel::getName() const { return vcName.c_str(); } const char* VirtualChannel::getName() const { return vcName.c_str(); }
bool VirtualChannel::isBusy() const { return ptme.isBusy(vcId); } bool VirtualChannel::isBusy() const {
// Data is discarded, so channel is not busy.
if (linkStateProvider.load()) {
return false;
}
return ptme.isBusy(vcId);
}
void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); }

View File

@ -28,6 +28,7 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF {
ReturnValue_t sendNextTm(const uint8_t* data, size_t size); ReturnValue_t sendNextTm(const uint8_t* data, size_t size);
bool isBusy() const override; bool isBusy() const override;
ReturnValue_t write(const uint8_t* data, size_t size) override; ReturnValue_t write(const uint8_t* data, size_t size) override;
void cancelTransfer() override;
uint8_t getVcid() const; uint8_t getVcid() const;
const char* getName() const; const char* getName() const;