From 4e686b4ad05627af84ca6d3377612b587f530ef7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 13:11:11 +0200 Subject: [PATCH 01/12] better PDEC FDIR --- bsp_q7s/core/CoreController.cpp | 4 +- linux/ipcore/PdecHandler.cpp | 92 +++++++++++++++++++---------- linux/ipcore/PdecHandler.h | 53 +++-------------- linux/ipcore/pdec.h | 50 ++++++++++++++++ mission/system/EiveSystem.cpp | 15 ++++- mission/system/EiveSystem.h | 5 ++ mission/system/com/ComSubsystem.cpp | 10 ++-- 7 files changed, 146 insertions(+), 83 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index e1033943..49145f9f 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -369,7 +369,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ return actionReboot(data, size); } case (EXECUTE_SHELL_CMD_BLOCKING): { - std::string cmdToExecute = std::string(reinterpret_cast(data), size); + std::string cmdToExecute = std::string(reinterpret_cast(data), size); int result = std::system(cmdToExecute.c_str()); if (result != 0) { // TODO: Data reply with returnalue maybe? @@ -378,7 +378,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ return EXECUTION_FINISHED; } case (EXECUTE_SHELL_CMD_NON_BLOCKING): { - std::string cmdToExecute = std::string(reinterpret_cast(data), size); + std::string cmdToExecute = std::string(reinterpret_cast(data), size); if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or shellCmdIsExecuting) { return HasActionsIF::IS_BUSY; diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index d5e5c0c8..8b6a0b2e 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -15,6 +15,7 @@ #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw_hal/linux/uio/UioMapper.h" +#include "linux/ipcore/PdecConfig.h" #include "pdec.h" using namespace pdec; @@ -103,7 +104,7 @@ ReturnValue_t PdecHandler::firstLoop() { result = releasePdec(); if (result != returnvalue::OK) { - return returnvalue::FAILED; + return result; } // This configuration must be done while the PDEC is not held in reset. @@ -141,7 +142,7 @@ ReturnValue_t PdecHandler::polledOperation() { if (newTcReceived()) { handleNewTc(); } - checkLocks(); + doPeriodicWork(); break; } case State::PDEC_RESET: { @@ -182,8 +183,13 @@ ReturnValue_t PdecHandler::irqOperation() { switch (state) { case State::INIT: { result = handleInitState(); - if (result == returnvalue::OK) { - openIrqFile(&fd); + if (result != returnvalue::OK) { + break; + } + openIrqFile(&fd); + if (ptmeResetWithReinitializationPending) { + actionHelper.finish(true, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION); + ptmeResetWithReinitializationPending = false; } break; } @@ -192,11 +198,12 @@ ReturnValue_t PdecHandler::irqOperation() { if (result != returnvalue::OK) { triggerEvent(PDEC_RESET_FAILED); } + usleep(10); state = State::INIT; break; } case State::RUNNING: { - checkLocks(); + doPeriodicWork(); checkAndHandleIrqs(fd, info); break; } @@ -219,18 +226,19 @@ ReturnValue_t PdecHandler::handleInitState() { ReturnValue_t result = firstLoop(); if (result != returnvalue::OK) { if (result == LocalParameterHandler::SD_NOT_READY) { - TaskFactory::delayTask(400); if (initTries == MAX_INIT_TRIES) { - sif::error << "PdecHandler::handleInitState: SD card never " - "becomes ready" - << std::endl; - state = State::WAIT_FOR_RECOVERY; - } else { - state = State::INIT; + sif::error << "PdecHandler::handleInitState: SD card never becomes ready" << std::endl; + initFailedHandler(result); + return result; } + state = State::INIT; + initTries++; + TaskFactory::delayTask(400); return result; } - state = State::WAIT_FOR_RECOVERY; + sif::error << "PDEC: Init failed with reason 0x" << std::hex << std::setw(4) << result + << std::endl; + initFailedHandler(result); return result; } state = State::RUNNING; @@ -335,6 +343,7 @@ MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->get ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + using namespace pdec; switch (actionId) { case PRINT_CLCW: printClcw(); @@ -342,6 +351,18 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t c case PRINT_PDEC_MON: printPdecMon(); return EXECUTION_FINISHED; + case RESET_PDEC_NO_REINIITALIZATION: { + pdecToReset(); + usleep(20); + releasePdec(); + return EXECUTION_FINISHED; + } + case RESET_PDEC_WITH_REINIITALIZATION: { + state = State::PDEC_RESET; + ptmeResetWithReinitializationPending = true; + this->commandedBy = commandedBy; + return returnvalue::OK; + } default: return COMMAND_NOT_IMPLEMENTED; } @@ -449,23 +470,7 @@ bool PdecHandler::newTcReceived() { return true; } -void PdecHandler::checkLocks() { - uint32_t clcw = getClcw(); - if (not(clcw & NO_RF_MASK) && not carrierLock) { - triggerEvent(CARRIER_LOCK); - carrierLock = true; - } else if ((clcw & NO_RF_MASK) && carrierLock) { - carrierLock = false; - triggerEvent(LOST_CARRIER_LOCK_PDEC); - } - if (not(clcw & NO_BITLOCK_MASK) && not bitLock) { - triggerEvent(BIT_LOCK_PDEC); - bitLock = true; - } else if ((clcw & NO_BITLOCK_MASK) && bitLock) { - bitLock = false; - triggerEvent(LOST_BIT_LOCK_PDEC); - } -} +void PdecHandler::doPeriodicWork() { checkLocks(); } bool PdecHandler::checkFrameAna(uint32_t pdecFar) { bool frameValid = false; @@ -748,6 +753,33 @@ void PdecHandler::resetIrqLimiters() { interruptCounter = 0; } +void PdecHandler::checkLocks() { + uint32_t clcw = getClcw(); + if (not(clcw & NO_RF_MASK) && not carrierLock) { + triggerEvent(CARRIER_LOCK); + carrierLock = true; + } else if ((clcw & NO_RF_MASK) && carrierLock) { + carrierLock = false; + triggerEvent(LOST_CARRIER_LOCK_PDEC); + } + if (not(clcw & NO_BITLOCK_MASK) && not bitLock) { + triggerEvent(BIT_LOCK_PDEC); + bitLock = true; + } else if ((clcw & NO_BITLOCK_MASK) && bitLock) { + bitLock = false; + triggerEvent(LOST_BIT_LOCK_PDEC); + } +} + +void PdecHandler::initFailedHandler(ReturnValue_t reason) { + triggerEvent(pdec::PDEC_INIT_FAILED, reason, 0); + if (ptmeResetWithReinitializationPending) { + actionHelper.finish(false, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION, reason); + ptmeResetWithReinitializationPending = false; + } + state = State::WAIT_FOR_RECOVERY; +} + std::string PdecHandler::getMonStatusString(uint32_t status) { switch (status) { case TC_CHANNEL_INACTIVE: diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index 2f0bcca2..2c379099 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -3,6 +3,8 @@ #include +#include + #include "OBSWConfig.h" #include "PdecConfig.h" #include "eive/definitions.h" @@ -79,34 +81,6 @@ class PdecHandler : public SystemObject, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, uint16_t startAtIndex) override; - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; - - //! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame - //! P1: The frame analysis information (FrameAna field of PDEC_FAR register) - //! P2: When frame declared illegal this parameter this parameter gives information about the - //! reason (IReason field of the PDEC_FAR register) - static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH); - //! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup - static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH); - //! [EXPORT] : [COMMENT] Carrier lock detected - static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO); - //! [EXPORT] : [COMMENT] Bit lock detected (data valid) - static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO); - //! [EXPORT] : [COMMENT] Lost carrier lock - static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO); - //! [EXPORT] : [COMMENT] Lost bit lock - static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO); - //! [EXPORT] : [COMMENT] Too many IRQs over the time window of one second. P1: Allowed TCs - static constexpr Event TOO_MANY_IRQS = MAKE_EVENT(7, severity::MEDIUM); - static constexpr Event POLL_SYSCALL_ERROR_PDEC = - event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM); - static constexpr Event WRITE_SYSCALL_ERROR_PDEC = - event::makeEvent(SUBSYSTEM_ID, 9, severity::HIGH); - //! [EXPORT] : [COMMENT] Failed to pull PDEC reset to low - static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 10, severity::HIGH); - //! [EXPORT] : [COMMENT] Failed to open the IRQ uio file - static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 11, severity::HIGH); - private: static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; @@ -141,11 +115,6 @@ class PdecHandler : public SystemObject, static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE; - // Action IDs - static const ActionId_t PRINT_CLCW = 0; - // Print PDEC monitor register - static const ActionId_t PRINT_PDEC_MON = 1; - #ifdef TE0720_1CFA static const int CONFIG_MEMORY_MAP_SIZE = 0x400; static const int RAM_MAP_SIZE = 0x4000; @@ -185,17 +154,6 @@ class PdecHandler : public SystemObject, static constexpr uint32_t MAX_ALLOWED_IRQS_PER_WINDOW = 800; - enum class FrameAna_t : uint8_t { - ABANDONED_CLTU, - FRAME_DIRTY, - FRAME_ILLEGAL, - FRAME_ILLEGAL_MULTI_REASON, - AD_DISCARDED_LOCKOUT, - AD_DISCARDED_WAIT, - AD_DISCARDED_NS_VR, - FRAME_ACCEPTED - }; - enum class IReason_t : uint8_t { NO_REPORT, ERROR_VERSION_NUMBER, @@ -258,6 +216,9 @@ class PdecHandler : public SystemObject, bool carrierLock = false; bool bitLock = false; + MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE; + bool ptmeResetWithReinitializationPending = false; + UioNames uioNames; ParameterHelper paramHelper; @@ -325,6 +286,8 @@ class PdecHandler : public SystemObject, * @brief Checks if carrier lock or bit lock has been detected and triggers appropriate * event. */ + void doPeriodicWork(); + void checkLocks(); void resetIrqLimiters(); @@ -400,6 +363,8 @@ class PdecHandler : public SystemObject, */ void printPdecMon(); + void initFailedHandler(ReturnValue_t reason); + std::string getMonStatusString(uint32_t status); }; diff --git a/linux/ipcore/pdec.h b/linux/ipcore/pdec.h index 7485f744..656250a7 100644 --- a/linux/ipcore/pdec.h +++ b/linux/ipcore/pdec.h @@ -1,10 +1,60 @@ #ifndef LINUX_OBC_PDEC_H_ #define LINUX_OBC_PDEC_H_ +#include + #include namespace pdec { +static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; + +//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame +//! P1: The frame analysis information (FrameAna field of PDEC_FAR register) +//! P2: When frame declared illegal this parameter this parameter gives information about the +//! reason (IReason field of the PDEC_FAR register) +static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH); +//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup +static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH); +//! [EXPORT] : [COMMENT] Carrier lock detected +static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO); +//! [EXPORT] : [COMMENT] Bit lock detected (data valid) +static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO); +//! [EXPORT] : [COMMENT] Lost carrier lock +static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO); +//! [EXPORT] : [COMMENT] Lost bit lock +static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO); +//! [EXPORT] : [COMMENT] Too many IRQs over the time window of one second. P1: Allowed TCs +static constexpr Event TOO_MANY_IRQS = MAKE_EVENT(7, severity::MEDIUM); +static constexpr Event POLL_SYSCALL_ERROR_PDEC = + event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM); +static constexpr Event WRITE_SYSCALL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 9, severity::HIGH); +//! [EXPORT] : [COMMENT] Failed to pull PDEC reset to low +static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 10, severity::HIGH); +//! [EXPORT] : [COMMENT] Failed to open the IRQ uio file +static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 11, severity::HIGH); +//! [EXPORT] : [COMMENT] PDEC initialization failed. This might also be due to the persistent +//! confiuration never becoming available, for example due to SD card issues. +static constexpr Event PDEC_INIT_FAILED = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH); + +// Action IDs +static constexpr ActionId_t PRINT_CLCW = 0; +// Print PDEC monitor register +static constexpr ActionId_t PRINT_PDEC_MON = 1; +static constexpr ActionId_t RESET_PDEC_NO_REINIITALIZATION = 2; +static constexpr ActionId_t RESET_PDEC_WITH_REINIITALIZATION = 3; + +enum class FrameAna_t : uint8_t { + ABANDONED_CLTU, + FRAME_DIRTY, + FRAME_ILLEGAL, + FRAME_ILLEGAL_MULTI_REASON, + AD_DISCARDED_LOCKOUT, + AD_DISCARDED_WAIT, + AD_DISCARDED_NS_VR, + FRAME_ACCEPTED +}; + static const uint8_t STAT_POSITION = 31; static const uint8_t FRAME_ANA_POSITION = 28; static const uint8_t IREASON_POSITION = 25; diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp index f93aa099..a8035c3a 100644 --- a/mission/system/EiveSystem.cpp +++ b/mission/system/EiveSystem.cpp @@ -8,6 +8,7 @@ #include #include +#include "linux/ipcore/pdec.h" #include "mission/power/bpxBattDefs.h" #include "mission/power/defs.h" #include "mission/sysDefs.h" @@ -62,6 +63,11 @@ void EiveSystem::performChildOperation() { performSafeRecovery = false; return; } + if (frameDirtyCheckCd.hasTimedOut()) { + if (frameDirtyErrorCounter >= 4) { + } + frameDirtyErrorCounter = 0; + } i2cRecoveryLogic(); } @@ -105,8 +111,7 @@ ReturnValue_t EiveSystem::initialize() { manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING)); manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING)); - - // manager->subscribeToEvent(eventQueue->getId(), event::getEventId(CoreController::)) + manager->subscribeToEvent(eventQueue->getId(), event::getEventId(pdec::INVALID_TC_FRAME)); return Subsystem::initialize(); } @@ -117,6 +122,12 @@ void EiveSystem::handleEventMessages() { switch (event.getMessageId()) { case EventMessage::EVENT_MESSAGE: switch (event.getEvent()) { + case pdec::INVALID_TC_FRAME: { + if (event.getParameter1() == static_cast(pdec::FrameAna_t::FRAME_DIRTY)) { + frameDirtyErrorCounter++; + } + break; + } case tcsCtrl::OBC_OVERHEATING: case tcsCtrl::PCDU_SYSTEM_OVERHEATING: { if (isInTransition) { diff --git a/mission/system/EiveSystem.h b/mission/system/EiveSystem.h index 504d4317..8ad11e0d 100644 --- a/mission/system/EiveSystem.h +++ b/mission/system/EiveSystem.h @@ -9,6 +9,8 @@ class EiveSystem : public Subsystem, public HasActionsIF { public: + static constexpr uint8_t FRAME_DIRTY_COM_REBOOT_LIMIT = 4; + static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10; EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables, @@ -33,6 +35,9 @@ class EiveSystem : public Subsystem, public HasActionsIF { bool performI2cReboot = false; bool alreadyTriedI2cRecovery = false; + uint8_t frameDirtyErrorCounter = 0; + Countdown frameDirtyCheckCd = Countdown(10000); + ActionHelper actionHelper; PowerSwitchIF* powerSwitcher = nullptr; std::atomic_uint16_t& i2cErrors; diff --git a/mission/system/com/ComSubsystem.cpp b/mission/system/com/ComSubsystem.cpp index fa2c31d3..dfcbbd42 100644 --- a/mission/system/com/ComSubsystem.cpp +++ b/mission/system/com/ComSubsystem.cpp @@ -105,9 +105,9 @@ ReturnValue_t ComSubsystem::initialize() { if (result != returnvalue::OK) { return ObjectManager::CHILD_INIT_FAILED; } - result = manager->subscribeToEventRange(eventQueue->getId(), - event::getEventId(PdecHandler::CARRIER_LOCK), - event::getEventId(PdecHandler::BIT_LOCK_PDEC)); + result = + manager->subscribeToEventRange(eventQueue->getId(), event::getEventId(pdec::CARRIER_LOCK), + event::getEventId(pdec::BIT_LOCK_PDEC)); if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "ComSubsystem::initialize: Failed to subscribe to events from PDEC " @@ -167,11 +167,11 @@ void ComSubsystem::handleEventMessage(EventMessage *eventMessage) { startRxOnlyRecovery(true); break; } - case PdecHandler::BIT_LOCK_PDEC: { + case pdec::BIT_LOCK_PDEC: { handleBitLockEvent(); break; } - case PdecHandler::CARRIER_LOCK: { + case pdec::CARRIER_LOCK: { handleCarrierLockEvent(); break; } From 213dba1e75689b361b6ee043c363c6818f97e4d3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 13:12:03 +0200 Subject: [PATCH 02/12] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 731c87d8..5a160c55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ will consitute of a breaking change warranting a new major release: - Add parameter interface for core controller - Allow setting the preferred SD card via the new parameter interface of the core controller with domain ID 0 and unque ID 0. +- Added action commands to reset the PDEC. Also added autonomous reset handling for the PDEC, + because there is no way so send TCs with a faulty PDEC. # [v1.44.1] 2023-04-12 From dc1e51891e6d1c85c7a2c632fa59eb3b79f20b71 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 13:26:44 +0200 Subject: [PATCH 03/12] added rest of necessary logic --- linux/ipcore/PdecHandler.cpp | 15 ++++++++---- linux/ipcore/PdecHandler.h | 2 ++ linux/ipcore/pdec.h | 12 +++++++--- mission/system/EiveSystem.cpp | 45 ++++++++++++++++++++++++++++------- mission/system/EiveSystem.h | 7 ++++++ 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index 8b6a0b2e..fa32dd47 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -146,6 +146,7 @@ ReturnValue_t PdecHandler::polledOperation() { break; } case State::PDEC_RESET: { + triggerEvent(pdec::PDEC_TRYING_RESET_WITH_INIT); ReturnValue_t result = pdecToReset(); if (result != returnvalue::OK) { triggerEvent(PDEC_RESET_FAILED); @@ -194,11 +195,12 @@ ReturnValue_t PdecHandler::irqOperation() { break; } case State::PDEC_RESET: { + triggerEvent(pdec::PDEC_TRYING_RESET_WITH_INIT); result = pdecToReset(); if (result != returnvalue::OK) { triggerEvent(PDEC_RESET_FAILED); } - usleep(10); + usleep(20); state = State::INIT; break; } @@ -352,9 +354,7 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t c printPdecMon(); return EXECUTION_FINISHED; case RESET_PDEC_NO_REINIITALIZATION: { - pdecToReset(); - usleep(20); - releasePdec(); + pdecResetNoInit(); return EXECUTION_FINISHED; } case RESET_PDEC_WITH_REINIITALIZATION: { @@ -780,6 +780,13 @@ void PdecHandler::initFailedHandler(ReturnValue_t reason) { state = State::WAIT_FOR_RECOVERY; } +void PdecHandler::pdecResetNoInit() { + triggerEvent(pdec::PDEC_TRYING_RESET_NO_INIT); + pdecToReset(); + usleep(20); + releasePdec(); +} + std::string PdecHandler::getMonStatusString(uint32_t status) { switch (status) { case TC_CHANNEL_INACTIVE: diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index 2c379099..e6000601 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -363,6 +363,8 @@ class PdecHandler : public SystemObject, */ void printPdecMon(); + void pdecResetNoInit(); + void initFailedHandler(ReturnValue_t reason); std::string getMonStatusString(uint32_t status); diff --git a/linux/ipcore/pdec.h b/linux/ipcore/pdec.h index 656250a7..f0d5ebed 100644 --- a/linux/ipcore/pdec.h +++ b/linux/ipcore/pdec.h @@ -29,13 +29,19 @@ static constexpr Event TOO_MANY_IRQS = MAKE_EVENT(7, severity::MEDIUM); static constexpr Event POLL_SYSCALL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM); static constexpr Event WRITE_SYSCALL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 9, severity::HIGH); +//! [EXPORT] : [COMMENT] Trying a PDEC reset with complete re-initialization +static constexpr Event PDEC_TRYING_RESET_WITH_INIT = + event::makeEvent(SUBSYSTEM_ID, 10, severity::LOW); +//! [EXPORT] : [COMMENT] Trying a PDEC reset without re-initialization. +static constexpr Event PDEC_TRYING_RESET_NO_INIT = + event::makeEvent(SUBSYSTEM_ID, 11, severity::LOW); //! [EXPORT] : [COMMENT] Failed to pull PDEC reset to low -static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 10, severity::HIGH); +static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH); //! [EXPORT] : [COMMENT] Failed to open the IRQ uio file -static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 11, severity::HIGH); +static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 13, severity::HIGH); //! [EXPORT] : [COMMENT] PDEC initialization failed. This might also be due to the persistent //! confiuration never becoming available, for example due to SD card issues. -static constexpr Event PDEC_INIT_FAILED = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH); +static constexpr Event PDEC_INIT_FAILED = event::makeEvent(SUBSYSTEM_ID, 14, severity::HIGH); // Action IDs static constexpr ActionId_t PRINT_CLCW = 0; diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp index a8035c3a..a319146a 100644 --- a/mission/system/EiveSystem.cpp +++ b/mission/system/EiveSystem.cpp @@ -63,11 +63,8 @@ void EiveSystem::performChildOperation() { performSafeRecovery = false; return; } - if (frameDirtyCheckCd.hasTimedOut()) { - if (frameDirtyErrorCounter >= 4) { - } - frameDirtyErrorCounter = 0; - } + pdecRecoveryLogic(); + i2cRecoveryLogic(); } @@ -92,6 +89,12 @@ ReturnValue_t EiveSystem::initialize() { } coreCtrlQueueId = coreCtrl->getCommandQueue(); + auto* pdecHandler = ObjectManager::instance()->get(objects::PDEC_HANDLER); + if (pdecHandler == nullptr) { + return ObjectManager::CHILD_INIT_FAILED; + } + pdecHandlerQueueId = pdecHandler->getCommandQueue(); + auto* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); if (manager == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -188,9 +191,8 @@ void EiveSystem::i2cRecoveryLogic() { } else { // We already tried an I2C recovery but the bus is still broken. // Send full reboot request to core controller. - CommandMessage msg; - ActionMessage::setCommand(&msg, core::REBOOT_OBC, store_address_t()); - result = commandQueue->sendMessage(coreCtrlQueueId, &msg); + sendFullRebootCommand(); + return; } } } @@ -269,6 +271,33 @@ void EiveSystem::i2cRecoveryLogic() { void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); } +ReturnValue_t EiveSystem::sendFullRebootCommand() { + CommandMessage msg; + ActionMessage::setCommand(&msg, core::REBOOT_OBC, store_address_t()); + return commandQueue->sendMessage(coreCtrlQueueId, &msg); +} + +void EiveSystem::pdecRecoveryLogic() { + if (frameDirtyCheckCd.hasTimedOut()) { + if (frameDirtyErrorCounter >= 4) { + // If a PTME reset was already attempted and there is still an issue receiving TC frames, + // reboot the system. + if (ptmeResetWasAttemptedCd.isBusy()) { + // Send reboot command. + sendFullRebootCommand(); + } else { + // Try one full PDEC reset. + CommandMessage msg; + store_address_t dummy{}; + ActionMessage::setCommand(&msg, pdec::RESET_PDEC_WITH_REINIITALIZATION, dummy); + commandQueue->sendMessage(pdecHandlerQueueId, &msg); + ptmeResetWasAttemptedCd.resetTimer(); + } + } + frameDirtyErrorCounter = 0; + } +} + void EiveSystem::commonI2cRecoverySequenceFinish() { alreadyTriedI2cRecovery = true; performI2cReboot = false; diff --git a/mission/system/EiveSystem.h b/mission/system/EiveSystem.h index 8ad11e0d..ecb5cf65 100644 --- a/mission/system/EiveSystem.h +++ b/mission/system/EiveSystem.h @@ -37,11 +37,14 @@ class EiveSystem : public Subsystem, public HasActionsIF { uint8_t frameDirtyErrorCounter = 0; Countdown frameDirtyCheckCd = Countdown(10000); + Countdown ptmeResetWasAttemptedCd = Countdown(60000); ActionHelper actionHelper; PowerSwitchIF* powerSwitcher = nullptr; std::atomic_uint16_t& i2cErrors; + MessageQueueId_t pdecHandlerQueueId = MessageQueueIF::NO_QUEUE; + MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t coreCtrlQueueId = MessageQueueIF::NO_QUEUE; MessageQueueId_t actionCommandedBy = MessageQueueIF::NO_QUEUE; @@ -56,6 +59,10 @@ class EiveSystem : public Subsystem, public HasActionsIF { const uint8_t* data, size_t size) override; ReturnValue_t handleCommandMessage(CommandMessage* message) override; + ReturnValue_t sendFullRebootCommand(); + + void pdecRecoveryLogic(); + void i2cRecoveryLogic(); void handleEventMessages(); void commandSelfToSafe(); From 46862825ec90e9ac924b9f6a832ee3166fa4d63c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 13:27:50 +0200 Subject: [PATCH 04/12] 2 minutes countdown for ptme was attempted CD --- mission/system/EiveSystem.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mission/system/EiveSystem.h b/mission/system/EiveSystem.h index ecb5cf65..30a01df9 100644 --- a/mission/system/EiveSystem.h +++ b/mission/system/EiveSystem.h @@ -37,7 +37,9 @@ class EiveSystem : public Subsystem, public HasActionsIF { uint8_t frameDirtyErrorCounter = 0; Countdown frameDirtyCheckCd = Countdown(10000); - Countdown ptmeResetWasAttemptedCd = Countdown(60000); + // If the PDEC reset was already attempted in the last 2 minutes, there is a high chance that + // only a full reboot will fix the issue. + Countdown ptmeResetWasAttemptedCd = Countdown(120000); ActionHelper actionHelper; PowerSwitchIF* powerSwitcher = nullptr; From 644a7687781d53f351aed926cac6fffdff8538ea Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 19:02:18 +0200 Subject: [PATCH 05/12] re-run generators --- .../fsfwconfig/events/translateEvents.cpp | 15 ++++++++--- .../fsfwconfig/objects/translateObjects.cpp | 2 +- generators/bsp_hosted_events.csv | 27 ++++++++++--------- generators/bsp_q7s_events.csv | 27 ++++++++++--------- generators/events/translateEvents.cpp | 15 ++++++++--- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 15 ++++++++--- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- tmtc | 2 +- 9 files changed, 70 insertions(+), 37 deletions(-) diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index c4b537e8..567a8942 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 285 translations. + * @brief Auto-generated event translation file. Contains 288 translations. * @details - * Generated on: 2023-04-07 17:42:57 + * Generated on: 2023-04-14 19:01:33 */ #include "translateEvents.h" @@ -160,8 +160,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC"; const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS"; const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC"; const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC"; +const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT"; +const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT"; const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED"; const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED"; +const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED"; const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED"; const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED"; const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL"; @@ -604,9 +607,15 @@ const char *translateEvents(Event event) { case (12409): return WRITE_SYSCALL_ERROR_PDEC_STRING; case (12410): - return PDEC_RESET_FAILED_STRING; + return PDEC_TRYING_RESET_WITH_INIT_STRING; case (12411): + return PDEC_TRYING_RESET_NO_INIT_STRING; + case (12412): + return PDEC_RESET_FAILED_STRING; + case (12413): return OPEN_IRQ_FILE_FAILED_STRING; + case (12414): + return PDEC_INIT_FAILED_STRING; case (12500): return IMAGE_UPLOAD_FAILED_STRING; case (12501): diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 148ac0b3..6c971110 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 171 translations. - * Generated on: 2023-04-07 17:42:57 + * Generated on: 2023-04-14 19:01:33 */ #include "translateObjects.h" diff --git a/generators/bsp_hosted_events.csv b/generators/bsp_hosted_events.csv index af15edff..c838a590 100644 --- a/generators/bsp_hosted_events.csv +++ b/generators/bsp_hosted_events.csv @@ -145,17 +145,20 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h 12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h 12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h -12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/PdecHandler.h -12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/PdecHandler.h -12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/PdecHandler.h -12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/PdecHandler.h -12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/PdecHandler.h -12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/PdecHandler.h -12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/PdecHandler.h -12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/PdecHandler.h -12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/PdecHandler.h -12410;0x307a;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/PdecHandler.h -12411;0x307b;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/PdecHandler.h +12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/pdec.h +12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/pdec.h +12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/pdec.h +12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/pdec.h +12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/pdec.h +12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/pdec.h +12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/pdec.h +12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/pdec.h +12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/pdec.h +12410;0x307a;PDEC_TRYING_RESET_WITH_INIT;LOW;Trying a PDEC reset with complete re-initialization;linux/ipcore/pdec.h +12411;0x307b;PDEC_TRYING_RESET_NO_INIT;LOW;Trying a PDEC reset without re-initialization.;linux/ipcore/pdec.h +12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h +12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h +12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h 12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h 12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h 12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h @@ -208,7 +211,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h 12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h 12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h -13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/objects/TcsBoardAssembly.h +13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/tcs/TcsBoardAssembly.h 13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h 13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h 13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index af15edff..c838a590 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -145,17 +145,20 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h 12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h 12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h -12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/PdecHandler.h -12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/PdecHandler.h -12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/PdecHandler.h -12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/PdecHandler.h -12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/PdecHandler.h -12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/PdecHandler.h -12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/PdecHandler.h -12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/PdecHandler.h -12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/PdecHandler.h -12410;0x307a;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/PdecHandler.h -12411;0x307b;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/PdecHandler.h +12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/pdec.h +12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/pdec.h +12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/pdec.h +12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/pdec.h +12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/pdec.h +12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/pdec.h +12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/pdec.h +12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/pdec.h +12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/pdec.h +12410;0x307a;PDEC_TRYING_RESET_WITH_INIT;LOW;Trying a PDEC reset with complete re-initialization;linux/ipcore/pdec.h +12411;0x307b;PDEC_TRYING_RESET_NO_INIT;LOW;Trying a PDEC reset without re-initialization.;linux/ipcore/pdec.h +12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h +12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h +12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h 12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h 12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h 12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h @@ -208,7 +211,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h 12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h 12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h -13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/objects/TcsBoardAssembly.h +13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/tcs/TcsBoardAssembly.h 13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h 13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h 13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index c4b537e8..567a8942 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 285 translations. + * @brief Auto-generated event translation file. Contains 288 translations. * @details - * Generated on: 2023-04-07 17:42:57 + * Generated on: 2023-04-14 19:01:33 */ #include "translateEvents.h" @@ -160,8 +160,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC"; const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS"; const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC"; const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC"; +const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT"; +const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT"; const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED"; const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED"; +const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED"; const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED"; const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED"; const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL"; @@ -604,9 +607,15 @@ const char *translateEvents(Event event) { case (12409): return WRITE_SYSCALL_ERROR_PDEC_STRING; case (12410): - return PDEC_RESET_FAILED_STRING; + return PDEC_TRYING_RESET_WITH_INIT_STRING; case (12411): + return PDEC_TRYING_RESET_NO_INIT_STRING; + case (12412): + return PDEC_RESET_FAILED_STRING; + case (12413): return OPEN_IRQ_FILE_FAILED_STRING; + case (12414): + return PDEC_INIT_FAILED_STRING; case (12500): return IMAGE_UPLOAD_FAILED_STRING; case (12501): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 76ce0db3..7a19a934 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 175 translations. - * Generated on: 2023-04-07 17:42:57 + * Generated on: 2023-04-14 19:01:33 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index c4b537e8..567a8942 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 285 translations. + * @brief Auto-generated event translation file. Contains 288 translations. * @details - * Generated on: 2023-04-07 17:42:57 + * Generated on: 2023-04-14 19:01:33 */ #include "translateEvents.h" @@ -160,8 +160,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC"; const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS"; const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC"; const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC"; +const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT"; +const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT"; const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED"; const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED"; +const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED"; const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED"; const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED"; const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL"; @@ -604,9 +607,15 @@ const char *translateEvents(Event event) { case (12409): return WRITE_SYSCALL_ERROR_PDEC_STRING; case (12410): - return PDEC_RESET_FAILED_STRING; + return PDEC_TRYING_RESET_WITH_INIT_STRING; case (12411): + return PDEC_TRYING_RESET_NO_INIT_STRING; + case (12412): + return PDEC_RESET_FAILED_STRING; + case (12413): return OPEN_IRQ_FILE_FAILED_STRING; + case (12414): + return PDEC_INIT_FAILED_STRING; case (12500): return IMAGE_UPLOAD_FAILED_STRING; case (12501): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 76ce0db3..7a19a934 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 175 translations. - * Generated on: 2023-04-07 17:42:57 + * Generated on: 2023-04-14 19:01:33 */ #include "translateObjects.h" diff --git a/tmtc b/tmtc index f5734260..183cd859 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit f57342602da3232c0bfecaecb0c10be6d692b384 +Subproject commit 183cd859073899d7f4d7a2f485eacd17d774fe50 From 62d18826f1c42cf7509a533dec3c478f240078d7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 19:29:22 +0200 Subject: [PATCH 06/12] proper post reset handling for PDEC reset --- linux/ipcore/PdecHandler.cpp | 34 ++++++++++++++++++++++------------ linux/ipcore/PdecHandler.h | 2 ++ mission/system/EiveSystem.cpp | 6 +++++- mission/system/EiveSystem.h | 1 + tmtc | 2 +- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index fa32dd47..575844ca 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -107,18 +107,7 @@ ReturnValue_t PdecHandler::firstLoop() { return result; } - // This configuration must be done while the PDEC is not held in reset. - if (OP_MODE == Modes::IRQ) { - // Configure interrupt mask register to enable interrupts - *(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); - } - result = resetFarStatFlag(); - if (result != returnvalue::OK) { - // Requires reconfiguration and reinitialization of PDEC - triggerEvent(INVALID_FAR); - return result; - } - return returnvalue::OK; + return postResetOperation(); } ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) { @@ -785,6 +774,27 @@ void PdecHandler::pdecResetNoInit() { pdecToReset(); usleep(20); releasePdec(); + ReturnValue_t result = postResetOperation(); + if (result != returnvalue::OK) { + // What can we really do here? Event was already triggered if this is due to the FAR flag + // not being reset. + sif::error << "PdecHandler::pdecResetNoInit: Post reset operation failed unexpectedly" + << std::endl; + } +} + +ReturnValue_t PdecHandler::postResetOperation() { + // This configuration must be done while the PDEC is not held in reset. + if (OP_MODE == Modes::IRQ) { + // Configure interrupt mask register to enable interrupts + *(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg(); + } + ReturnValue_t result = resetFarStatFlag(); + if (result != returnvalue::OK) { + // Requires reconfiguration and reinitialization of PDEC + triggerEvent(INVALID_FAR); + } + return result; } std::string PdecHandler::getMonStatusString(uint32_t status) { diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index e6000601..70b85ecd 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -365,6 +365,8 @@ class PdecHandler : public SystemObject, void pdecResetNoInit(); + ReturnValue_t postResetOperation(); + void initFailedHandler(ReturnValue_t reason); std::string getMonStatusString(uint32_t status); diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp index a319146a..142034dc 100644 --- a/mission/system/EiveSystem.cpp +++ b/mission/system/EiveSystem.cpp @@ -278,11 +278,14 @@ ReturnValue_t EiveSystem::sendFullRebootCommand() { } void EiveSystem::pdecRecoveryLogic() { + if (ptmeResetWasAttempted and ptmeResetWasAttemptedCd.hasTimedOut()) { + ptmeResetWasAttempted = false; + } if (frameDirtyCheckCd.hasTimedOut()) { if (frameDirtyErrorCounter >= 4) { // If a PTME reset was already attempted and there is still an issue receiving TC frames, // reboot the system. - if (ptmeResetWasAttemptedCd.isBusy()) { + if (ptmeResetWasAttempted) { // Send reboot command. sendFullRebootCommand(); } else { @@ -292,6 +295,7 @@ void EiveSystem::pdecRecoveryLogic() { ActionMessage::setCommand(&msg, pdec::RESET_PDEC_WITH_REINIITALIZATION, dummy); commandQueue->sendMessage(pdecHandlerQueueId, &msg); ptmeResetWasAttemptedCd.resetTimer(); + ptmeResetWasAttempted = true; } } frameDirtyErrorCounter = 0; diff --git a/mission/system/EiveSystem.h b/mission/system/EiveSystem.h index 30a01df9..67f11c3e 100644 --- a/mission/system/EiveSystem.h +++ b/mission/system/EiveSystem.h @@ -40,6 +40,7 @@ class EiveSystem : public Subsystem, public HasActionsIF { // If the PDEC reset was already attempted in the last 2 minutes, there is a high chance that // only a full reboot will fix the issue. Countdown ptmeResetWasAttemptedCd = Countdown(120000); + bool ptmeResetWasAttempted = false; ActionHelper actionHelper; PowerSwitchIF* powerSwitcher = nullptr; diff --git a/tmtc b/tmtc index 183cd859..63c584e0 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 183cd859073899d7f4d7a2f485eacd17d774fe50 +Subproject commit 63c584e061a8e0d27189d66fb3ac1c48d011afe7 From 8cf9dd91369d025d5d6be7f9c1b2cd237f331e35 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 19:30:40 +0200 Subject: [PATCH 07/12] use config constant --- mission/system/EiveSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp index 142034dc..b12f95f4 100644 --- a/mission/system/EiveSystem.cpp +++ b/mission/system/EiveSystem.cpp @@ -282,7 +282,7 @@ void EiveSystem::pdecRecoveryLogic() { ptmeResetWasAttempted = false; } if (frameDirtyCheckCd.hasTimedOut()) { - if (frameDirtyErrorCounter >= 4) { + if (frameDirtyErrorCounter >= FRAME_DIRTY_COM_REBOOT_LIMIT) { // If a PTME reset was already attempted and there is still an issue receiving TC frames, // reboot the system. if (ptmeResetWasAttempted) { From e023220be42d5f0ef410238f35364e328d1bff8c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 19:42:11 +0200 Subject: [PATCH 08/12] better reset handling --- linux/ipcore/PdecHandler.cpp | 39 +++++++++++++++++++++--------------- linux/ipcore/PdecHandler.h | 6 ++++-- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index 575844ca..70eaf3e6 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -156,8 +156,8 @@ ReturnValue_t PdecHandler::polledOperation() { // See https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html for more information. ReturnValue_t PdecHandler::irqOperation() { ReturnValue_t result = returnvalue::OK; - int fd = -1; - // Used to unmask IRQ + // int fd = -1; + // Used to unmask IRQ uint32_t info = 1; interruptWindowCd.resetTimer(); @@ -176,7 +176,7 @@ ReturnValue_t PdecHandler::irqOperation() { if (result != returnvalue::OK) { break; } - openIrqFile(&fd); + openIrqFile(); if (ptmeResetWithReinitializationPending) { actionHelper.finish(true, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION); ptmeResetWithReinitializationPending = false; @@ -195,7 +195,7 @@ ReturnValue_t PdecHandler::irqOperation() { } case State::RUNNING: { doPeriodicWork(); - checkAndHandleIrqs(fd, info); + checkAndHandleIrqs(info); break; } case State::WAIT_FOR_RECOVERY: @@ -236,9 +236,9 @@ ReturnValue_t PdecHandler::handleInitState() { return returnvalue::OK; } -void PdecHandler::openIrqFile(int* fd) { - *fd = open(uioNames.irq, O_RDWR); - if (*fd < 0) { +void PdecHandler::openIrqFile() { + irqFd = open(uioNames.irq, O_RDWR); + if (irqFd < 0) { sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed" << std::endl; triggerEvent(OPEN_IRQ_FILE_FAILED); @@ -246,16 +246,16 @@ void PdecHandler::openIrqFile(int* fd) { } } -ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) { - ssize_t nb = write(fd, &info, sizeof(info)); +ReturnValue_t PdecHandler::checkAndHandleIrqs(uint32_t& info) { + ssize_t nb = write(irqFd, &info, sizeof(info)); if (nb != static_cast(sizeof(info))) { sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl; triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno); - close(fd); + close(irqFd); state = State::INIT; return returnvalue::FAILED; } - struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0}; + struct pollfd fds = {.fd = irqFd, .events = POLLIN, .revents = 0}; int ret = poll(&fds, 1, IRQ_TIMEOUT_MS); if (ret == 0) { // No TCs for timeout period @@ -263,7 +263,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) { resetIrqLimiters(); } else if (ret >= 1) { // Interrupt handling. - nb = read(fd, &info, sizeof(info)); + nb = read(irqFd, &info, sizeof(info)); interruptCounter++; if (nb == static_cast(sizeof(info))) { uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET); @@ -302,7 +302,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) { sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": " << strerror(errno) << std::endl; triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno); - close(fd); + close(irqFd); state = State::INIT; return returnvalue::FAILED; } @@ -347,7 +347,7 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t c return EXECUTION_FINISHED; } case RESET_PDEC_WITH_REINIITALIZATION: { - state = State::PDEC_RESET; + initializeReset(); ptmeResetWithReinitializationPending = true; this->commandedBy = commandedBy; return returnvalue::OK; @@ -380,7 +380,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi return returnvalue::FAILED; } // PDEC needs reset to apply this parameter change - state = State::PDEC_RESET; + initializeReset(); return returnvalue::OK; } else if ((domainId == 0) and (uniqueIdentifier == ParameterId::NEGATIVE_WINDOW)) { uint8_t newVal = 0; @@ -402,7 +402,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi return returnvalue::FAILED; } // PDEC needs reset to apply this parameter change - state = State::PDEC_RESET; + initializeReset(); return returnvalue::OK; } return returnvalue::OK; @@ -797,6 +797,13 @@ ReturnValue_t PdecHandler::postResetOperation() { return result; } +void PdecHandler::initializeReset() { + if (irqFd != 0) { + close(irqFd); + } + state = State::PDEC_RESET; +} + std::string PdecHandler::getMonStatusString(uint32_t status) { switch (status) { case TC_CHANNEL_INACTIVE: diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index 70b85ecd..fd3c7362 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -171,6 +171,7 @@ class PdecHandler : public SystemObject, Countdown genericCheckCd = Countdown(IRQ_TIMEOUT_MS); object_id_t tcDestinationId; + int irqFd = 0; AcceptsTelecommandsIF* tcDestination = nullptr; @@ -243,8 +244,8 @@ class PdecHandler : public SystemObject, ReturnValue_t polledOperation(); ReturnValue_t irqOperation(); ReturnValue_t handleInitState(); - void openIrqFile(int* fd); - ReturnValue_t checkAndHandleIrqs(int fd, uint32_t& info); + void openIrqFile(); + ReturnValue_t checkAndHandleIrqs(uint32_t& info); uint32_t readFar(); @@ -366,6 +367,7 @@ class PdecHandler : public SystemObject, void pdecResetNoInit(); ReturnValue_t postResetOperation(); + void initializeReset(); void initFailedHandler(ReturnValue_t reason); From 7f1fe3a2d82c9cd7fd13b855a187b595e45b6dae Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 19:58:22 +0200 Subject: [PATCH 09/12] bugfix --- linux/ipcore/PdecHandler.cpp | 9 ++++++++- linux/ipcore/PdecHandler.h | 32 +++----------------------------- linux/ipcore/pdec.h | 28 ++++++++++++++++++++++++++++ mission/system/EiveSystem.cpp | 3 ++- 4 files changed, 41 insertions(+), 31 deletions(-) diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index 70eaf3e6..7506dd11 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -459,7 +459,14 @@ bool PdecHandler::newTcReceived() { return true; } -void PdecHandler::doPeriodicWork() { checkLocks(); } +void PdecHandler::doPeriodicWork() { + // scuffed test code + // if(testCntr < 30) { + // triggerEvent(pdec::INVALID_TC_FRAME, FRAME_DIRTY_RETVAL); + // testCntr++; + // } + checkLocks(); +} bool PdecHandler::checkFrameAna(uint32_t pdecFar) { bool frameValid = false; diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index fd3c7362..882dca50 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -82,37 +82,8 @@ class PdecHandler : public SystemObject, uint16_t startAtIndex) override; private: - static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; - static constexpr Modes OP_MODE = Modes::IRQ; - static const ReturnValue_t ABANDONED_CLTU_RETVAL = MAKE_RETURN_CODE(0xA0); - static const ReturnValue_t FRAME_DIRTY_RETVAL = MAKE_RETURN_CODE(0xA1); - static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2); - static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2); - static const ReturnValue_t AD_DISCARDED_LOCKOUT_RETVAL = MAKE_RETURN_CODE(0xA3); - static const ReturnValue_t AD_DISCARDED_WAIT_RETVAL = MAKE_RETURN_CODE(0xA4); - static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5); - - //! [EXPORT] : [COMMENT] Received action message with unknown action id - static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0); - - static const ReturnValue_t NO_REPORT_RETVAL = MAKE_RETURN_CODE(0xA6); - //! Error in version number and reserved A and B fields - static const ReturnValue_t ERROR_VERSION_NUMBER_RETVAL = MAKE_RETURN_CODE(0xA7); - //! Illegal combination of bypass and control command flag - static const ReturnValue_t ILLEGAL_COMBINATION_RETVAL = MAKE_RETURN_CODE(0xA8); - //! Spacecraft identifier did not match - static const ReturnValue_t INVALID_SC_ID_RETVAL = MAKE_RETURN_CODE(0xA9); - //! VC identifier bits 0 to 4 did not match - static const ReturnValue_t INVALID_VC_ID_MSB_RETVAL = MAKE_RETURN_CODE(0xAA); - //! VC identifier bit 5 did not match - static const ReturnValue_t INVALID_VC_ID_LSB_RETVAL = MAKE_RETURN_CODE(0xAB); - //! N(S) of BC or BD frame not set to all zeros - static const ReturnValue_t NS_NOT_ZERO_RETVAL = MAKE_RETURN_CODE(0xAC); - //! Invalid BC control command - static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE); - static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE; #ifdef TE0720_1CFA @@ -228,6 +199,9 @@ class PdecHandler : public SystemObject, uint32_t initTries = 0; + // scuffed test counter. + uint8_t testCntr = 0; + /** * @brief Performs initialization stuff which must be performed in first * loop of running task diff --git a/linux/ipcore/pdec.h b/linux/ipcore/pdec.h index f0d5ebed..e0e61e10 100644 --- a/linux/ipcore/pdec.h +++ b/linux/ipcore/pdec.h @@ -7,6 +7,34 @@ namespace pdec { +static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; +static const ReturnValue_t ABANDONED_CLTU_RETVAL = MAKE_RETURN_CODE(0xA0); +static const ReturnValue_t FRAME_DIRTY_RETVAL = MAKE_RETURN_CODE(0xA1); +static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2); +static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2); +static const ReturnValue_t AD_DISCARDED_LOCKOUT_RETVAL = MAKE_RETURN_CODE(0xA3); +static const ReturnValue_t AD_DISCARDED_WAIT_RETVAL = MAKE_RETURN_CODE(0xA4); +static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5); + +//! [EXPORT] : [COMMENT] Received action message with unknown action id +static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0); + +static const ReturnValue_t NO_REPORT_RETVAL = MAKE_RETURN_CODE(0xA6); +//! Error in version number and reserved A and B fields +static const ReturnValue_t ERROR_VERSION_NUMBER_RETVAL = MAKE_RETURN_CODE(0xA7); +//! Illegal combination of bypass and control command flag +static const ReturnValue_t ILLEGAL_COMBINATION_RETVAL = MAKE_RETURN_CODE(0xA8); +//! Spacecraft identifier did not match +static const ReturnValue_t INVALID_SC_ID_RETVAL = MAKE_RETURN_CODE(0xA9); +//! VC identifier bits 0 to 4 did not match +static const ReturnValue_t INVALID_VC_ID_MSB_RETVAL = MAKE_RETURN_CODE(0xAA); +//! VC identifier bit 5 did not match +static const ReturnValue_t INVALID_VC_ID_LSB_RETVAL = MAKE_RETURN_CODE(0xAB); +//! N(S) of BC or BD frame not set to all zeros +static const ReturnValue_t NS_NOT_ZERO_RETVAL = MAKE_RETURN_CODE(0xAC); +//! Invalid BC control command +static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE); + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; //! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp index b12f95f4..6e4564f5 100644 --- a/mission/system/EiveSystem.cpp +++ b/mission/system/EiveSystem.cpp @@ -126,7 +126,7 @@ void EiveSystem::handleEventMessages() { case EventMessage::EVENT_MESSAGE: switch (event.getEvent()) { case pdec::INVALID_TC_FRAME: { - if (event.getParameter1() == static_cast(pdec::FrameAna_t::FRAME_DIRTY)) { + if (event.getParameter1() == pdec::FRAME_DIRTY_RETVAL) { frameDirtyErrorCounter++; } break; @@ -299,6 +299,7 @@ void EiveSystem::pdecRecoveryLogic() { } } frameDirtyErrorCounter = 0; + frameDirtyCheckCd.resetTimer(); } } From aa800c4524c020ac6e184b3b465f269fe11eb671 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 20:04:51 +0200 Subject: [PATCH 10/12] trigger special reboot events --- mission/sysDefs.h | 2 ++ mission/system/EiveSystem.cpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mission/sysDefs.h b/mission/sysDefs.h index e8ada9f8..1f86ff42 100644 --- a/mission/sysDefs.h +++ b/mission/sysDefs.h @@ -93,6 +93,8 @@ static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8 static constexpr Event TRYING_I2C_RECOVERY = event::makeEvent(SUBSYSTEM_ID, 10, severity::MEDIUM); //! [EXPORT] : [COMMENT] I2C is unavailable. Recovery did not work, performing full reboot. static constexpr Event I2C_REBOOT = event::makeEvent(SUBSYSTEM_ID, 11, severity::MEDIUM); +//! [EXPORT] : [COMMENT] PDEC recovery through reset was not possible, performing full reboot. +static constexpr Event PDEC_REBOOT = event::makeEvent(SUBSYSTEM_ID, 12, severity::MEDIUM); } // namespace core diff --git a/mission/system/EiveSystem.cpp b/mission/system/EiveSystem.cpp index 6e4564f5..eb1c4101 100644 --- a/mission/system/EiveSystem.cpp +++ b/mission/system/EiveSystem.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -64,7 +65,6 @@ void EiveSystem::performChildOperation() { return; } pdecRecoveryLogic(); - i2cRecoveryLogic(); } @@ -189,6 +189,7 @@ void EiveSystem::i2cRecoveryLogic() { // Try recovery. executeAction(EXECUTE_I2C_REBOOT, MessageQueueIF::NO_QUEUE, nullptr, 0); } else { + triggerEvent(core::I2C_REBOOT); // We already tried an I2C recovery but the bus is still broken. // Send full reboot request to core controller. sendFullRebootCommand(); @@ -286,6 +287,7 @@ void EiveSystem::pdecRecoveryLogic() { // If a PTME reset was already attempted and there is still an issue receiving TC frames, // reboot the system. if (ptmeResetWasAttempted) { + triggerEvent(core::PDEC_REBOOT); // Send reboot command. sendFullRebootCommand(); } else { From 379fd6046e52a2a8e982f4c055315c677a22f3b1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 20:08:05 +0200 Subject: [PATCH 11/12] ge-generate files --- CHANGELOG.md | 3 +- .../fsfwconfig/events/translateEvents.cpp | 7 +++-- .../fsfwconfig/objects/translateObjects.cpp | 2 +- generators/bsp_hosted_events.csv | 1 + generators/bsp_q7s_events.csv | 1 + generators/bsp_q7s_returnvalues.csv | 30 +++++++++---------- generators/events/translateEvents.cpp | 7 +++-- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 7 +++-- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- mission/sysDefs.h | 6 ++-- tmtc | 2 +- 12 files changed, 41 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f061adf0..96f9c5f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,7 +49,8 @@ will consitute of a breaking change warranting a new major release: with domain ID 0 and unque ID 0. - Added action commands to reset the PDEC. Also added autonomous reset handling for the PDEC, because there is no way so send TCs with a faulty PDEC. - +- Added `I2C_REBOOT` and `PDEC_REBOOT` events for EIVE system component to ensure ground gets + informed. # [v1.44.1] 2023-04-12 diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index 567a8942..f09c8c6d 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 288 translations. + * @brief Auto-generated event translation file. Contains 289 translations. * @details - * Generated on: 2023-04-14 19:01:33 + * Generated on: 2023-04-14 20:05:50 */ #include "translateEvents.h" @@ -271,6 +271,7 @@ const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER"; const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS"; const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY"; const char *I2C_REBOOT_STRING = "I2C_REBOOT"; +const char *PDEC_REBOOT_STRING = "PDEC_REBOOT"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -828,6 +829,8 @@ const char *translateEvents(Event event) { return TRYING_I2C_RECOVERY_STRING; case (14011): return I2C_REBOOT_STRING; + case (14012): + return PDEC_REBOOT_STRING; case (14100): return NO_VALID_SENSOR_TEMPERATURE_STRING; case (14101): diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 6c971110..30ff46f9 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 171 translations. - * Generated on: 2023-04-14 19:01:33 + * Generated on: 2023-04-14 20:05:50 */ #include "translateObjects.h" diff --git a/generators/bsp_hosted_events.csv b/generators/bsp_hosted_events.csv index c838a590..332a38a3 100644 --- a/generators/bsp_hosted_events.csv +++ b/generators/bsp_hosted_events.csv @@ -265,6 +265,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h 14010;0x36ba;TRYING_I2C_RECOVERY;MEDIUM;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h 14011;0x36bb;I2C_REBOOT;MEDIUM;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h +14012;0x36bc;PDEC_REBOOT;MEDIUM;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h 14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h 14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h 14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index c838a590..332a38a3 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -265,6 +265,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h 14010;0x36ba;TRYING_I2C_RECOVERY;MEDIUM;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h 14011;0x36bb;I2C_REBOOT;MEDIUM;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h +14012;0x36bc;PDEC_REBOOT;MEDIUM;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h 14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h 14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h 14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index fcb4a5ee..e450cf02 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -517,21 +517,21 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x5d05;GOMS_UnknownReplyId;No description;5;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h 0x5ea0;PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;160;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h 0x5ea1;PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;161;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h -0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fa1;PDEC_FrameDirtyRetval;No description;161;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fa2;PDEC_FrameIllegalMultipleReasons;No description;162;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fa3;PDEC_AdDiscardedLockoutRetval;No description;163;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fa4;PDEC_AdDiscardedWaitRetval;No description;164;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fa5;PDEC_AdDiscardedNsVs;No description;165;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fa6;PDEC_NoReportRetval;No description;166;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fa7;PDEC_ErrorVersionNumberRetval;No description;167;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fa8;PDEC_IllegalCombinationRetval;No description;168;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fa9;PDEC_InvalidScIdRetval;No description;169;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5faa;PDEC_InvalidVcIdMsbRetval;No description;170;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fab;PDEC_InvalidVcIdLsbRetval;No description;171;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fac;PDEC_NsNotZeroRetval;No description;172;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fae;PDEC_InvalidBcCc;No description;174;PDEC_HANDLER;linux/ipcore/PdecHandler.h -0x5fb0;PDEC_CommandNotImplemented;Received action message with unknown action id;176;PDEC_HANDLER;linux/ipcore/PdecHandler.h +0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fa1;PDEC_FrameDirtyRetval;No description;161;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fa2;PDEC_FrameIllegalMultipleReasons;No description;162;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fa3;PDEC_AdDiscardedLockoutRetval;No description;163;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fa4;PDEC_AdDiscardedWaitRetval;No description;164;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fa5;PDEC_AdDiscardedNsVs;No description;165;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fa6;PDEC_NoReportRetval;No description;166;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fa7;PDEC_ErrorVersionNumberRetval;No description;167;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fa8;PDEC_IllegalCombinationRetval;No description;168;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fa9;PDEC_InvalidScIdRetval;No description;169;PDEC_HANDLER;linux/ipcore/pdec.h +0x5faa;PDEC_InvalidVcIdMsbRetval;No description;170;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fab;PDEC_InvalidVcIdLsbRetval;No description;171;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fac;PDEC_NsNotZeroRetval;No description;172;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fae;PDEC_InvalidBcCc;No description;174;PDEC_HANDLER;linux/ipcore/pdec.h +0x5fb0;PDEC_CommandNotImplemented;Received action message with unknown action id;176;PDEC_HANDLER;linux/ipcore/pdec.h 0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/com/CcsdsIpCoreHandler.h 0x61a0;RS_RateNotSupported;The commanded rate is not supported by the current FPGA design;160;RATE_SETTER;linux/ipcore/PtmeConfig.h 0x61a1;RS_BadBitRate;Bad bitrate has been commanded (e.g. 0);161;RATE_SETTER;linux/ipcore/PtmeConfig.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 567a8942..f09c8c6d 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 288 translations. + * @brief Auto-generated event translation file. Contains 289 translations. * @details - * Generated on: 2023-04-14 19:01:33 + * Generated on: 2023-04-14 20:05:50 */ #include "translateEvents.h" @@ -271,6 +271,7 @@ const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER"; const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS"; const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY"; const char *I2C_REBOOT_STRING = "I2C_REBOOT"; +const char *PDEC_REBOOT_STRING = "PDEC_REBOOT"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -828,6 +829,8 @@ const char *translateEvents(Event event) { return TRYING_I2C_RECOVERY_STRING; case (14011): return I2C_REBOOT_STRING; + case (14012): + return PDEC_REBOOT_STRING; case (14100): return NO_VALID_SENSOR_TEMPERATURE_STRING; case (14101): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 7a19a934..dbd6cc6e 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 175 translations. - * Generated on: 2023-04-14 19:01:33 + * Generated on: 2023-04-14 20:05:50 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 567a8942..f09c8c6d 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 288 translations. + * @brief Auto-generated event translation file. Contains 289 translations. * @details - * Generated on: 2023-04-14 19:01:33 + * Generated on: 2023-04-14 20:05:50 */ #include "translateEvents.h" @@ -271,6 +271,7 @@ const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER"; const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS"; const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY"; const char *I2C_REBOOT_STRING = "I2C_REBOOT"; +const char *PDEC_REBOOT_STRING = "PDEC_REBOOT"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -828,6 +829,8 @@ const char *translateEvents(Event event) { return TRYING_I2C_RECOVERY_STRING; case (14011): return I2C_REBOOT_STRING; + case (14012): + return PDEC_REBOOT_STRING; case (14100): return NO_VALID_SENSOR_TEMPERATURE_STRING; case (14101): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 7a19a934..dbd6cc6e 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 175 translations. - * Generated on: 2023-04-14 19:01:33 + * Generated on: 2023-04-14 20:05:50 */ #include "translateObjects.h" diff --git a/mission/sysDefs.h b/mission/sysDefs.h index 1f86ff42..424b5752 100644 --- a/mission/sysDefs.h +++ b/mission/sysDefs.h @@ -90,11 +90,11 @@ static constexpr Event REBOOT_COUNTER = event::makeEvent(SUBSYSTEM_ID, 7, severi static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO); //! [EXPORT] : [COMMENT] I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C //! devices. -static constexpr Event TRYING_I2C_RECOVERY = event::makeEvent(SUBSYSTEM_ID, 10, severity::MEDIUM); +static constexpr Event TRYING_I2C_RECOVERY = event::makeEvent(SUBSYSTEM_ID, 10, severity::HIGH); //! [EXPORT] : [COMMENT] I2C is unavailable. Recovery did not work, performing full reboot. -static constexpr Event I2C_REBOOT = event::makeEvent(SUBSYSTEM_ID, 11, severity::MEDIUM); +static constexpr Event I2C_REBOOT = event::makeEvent(SUBSYSTEM_ID, 11, severity::HIGH); //! [EXPORT] : [COMMENT] PDEC recovery through reset was not possible, performing full reboot. -static constexpr Event PDEC_REBOOT = event::makeEvent(SUBSYSTEM_ID, 12, severity::MEDIUM); +static constexpr Event PDEC_REBOOT = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH); } // namespace core diff --git a/tmtc b/tmtc index 63c584e0..1f06ea45 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 63c584e061a8e0d27189d66fb3ac1c48d011afe7 +Subproject commit 1f06ea4590d6340990fb8d9534a84e7e9de68951 From 4de71062af4ed2723d612cb8e03a8243b5e41b6d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 20:11:33 +0200 Subject: [PATCH 12/12] fix host build --- linux/ipcore/pdec.h | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/ipcore/pdec.h b/linux/ipcore/pdec.h index e0e61e10..0574ee73 100644 --- a/linux/ipcore/pdec.h +++ b/linux/ipcore/pdec.h @@ -1,6 +1,7 @@ #ifndef LINUX_OBC_PDEC_H_ #define LINUX_OBC_PDEC_H_ +#include #include #include