better PDEC FDIR

This commit is contained in:
Robin Müller 2023-04-14 13:11:11 +02:00
parent a7c227f8ea
commit 4e686b4ad0
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
7 changed files with 146 additions and 83 deletions

View File

@ -369,7 +369,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
return actionReboot(data, size); return actionReboot(data, size);
} }
case (EXECUTE_SHELL_CMD_BLOCKING): { case (EXECUTE_SHELL_CMD_BLOCKING): {
std::string cmdToExecute = std::string(reinterpret_cast<const char*>(data), size); std::string cmdToExecute = std::string(reinterpret_cast<const char *>(data), size);
int result = std::system(cmdToExecute.c_str()); int result = std::system(cmdToExecute.c_str());
if (result != 0) { if (result != 0) {
// TODO: Data reply with returnalue maybe? // TODO: Data reply with returnalue maybe?
@ -378,7 +378,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
case (EXECUTE_SHELL_CMD_NON_BLOCKING): { case (EXECUTE_SHELL_CMD_NON_BLOCKING): {
std::string cmdToExecute = std::string(reinterpret_cast<const char*>(data), size); std::string cmdToExecute = std::string(reinterpret_cast<const char *>(data), size);
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or
shellCmdIsExecuting) { shellCmdIsExecuting) {
return HasActionsIF::IS_BUSY; return HasActionsIF::IS_BUSY;

View File

@ -15,6 +15,7 @@
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw/tmtcservices/TmTcMessage.h"
#include "fsfw_hal/linux/uio/UioMapper.h" #include "fsfw_hal/linux/uio/UioMapper.h"
#include "linux/ipcore/PdecConfig.h"
#include "pdec.h" #include "pdec.h"
using namespace pdec; using namespace pdec;
@ -103,7 +104,7 @@ ReturnValue_t PdecHandler::firstLoop() {
result = releasePdec(); result = releasePdec();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return returnvalue::FAILED; return result;
} }
// This configuration must be done while the PDEC is not held in reset. // This configuration must be done while the PDEC is not held in reset.
@ -141,7 +142,7 @@ ReturnValue_t PdecHandler::polledOperation() {
if (newTcReceived()) { if (newTcReceived()) {
handleNewTc(); handleNewTc();
} }
checkLocks(); doPeriodicWork();
break; break;
} }
case State::PDEC_RESET: { case State::PDEC_RESET: {
@ -182,8 +183,13 @@ ReturnValue_t PdecHandler::irqOperation() {
switch (state) { switch (state) {
case State::INIT: { case State::INIT: {
result = handleInitState(); result = handleInitState();
if (result == returnvalue::OK) { if (result != returnvalue::OK) {
break;
}
openIrqFile(&fd); openIrqFile(&fd);
if (ptmeResetWithReinitializationPending) {
actionHelper.finish(true, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION);
ptmeResetWithReinitializationPending = false;
} }
break; break;
} }
@ -192,11 +198,12 @@ ReturnValue_t PdecHandler::irqOperation() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
triggerEvent(PDEC_RESET_FAILED); triggerEvent(PDEC_RESET_FAILED);
} }
usleep(10);
state = State::INIT; state = State::INIT;
break; break;
} }
case State::RUNNING: { case State::RUNNING: {
checkLocks(); doPeriodicWork();
checkAndHandleIrqs(fd, info); checkAndHandleIrqs(fd, info);
break; break;
} }
@ -219,18 +226,19 @@ ReturnValue_t PdecHandler::handleInitState() {
ReturnValue_t result = firstLoop(); ReturnValue_t result = firstLoop();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (result == LocalParameterHandler::SD_NOT_READY) { if (result == LocalParameterHandler::SD_NOT_READY) {
TaskFactory::delayTask(400);
if (initTries == MAX_INIT_TRIES) { if (initTries == MAX_INIT_TRIES) {
sif::error << "PdecHandler::handleInitState: SD card never " sif::error << "PdecHandler::handleInitState: SD card never becomes ready" << std::endl;
"becomes ready" initFailedHandler(result);
<< std::endl;
state = State::WAIT_FOR_RECOVERY;
} else {
state = State::INIT;
}
return result; return result;
} }
state = State::WAIT_FOR_RECOVERY; state = State::INIT;
initTries++;
TaskFactory::delayTask(400);
return result;
}
sif::error << "PDEC: Init failed with reason 0x" << std::hex << std::setw(4) << result
<< std::endl;
initFailedHandler(result);
return result; return result;
} }
state = State::RUNNING; 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, ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) { const uint8_t* data, size_t size) {
using namespace pdec;
switch (actionId) { switch (actionId) {
case PRINT_CLCW: case PRINT_CLCW:
printClcw(); printClcw();
@ -342,6 +351,18 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t c
case PRINT_PDEC_MON: case PRINT_PDEC_MON:
printPdecMon(); printPdecMon();
return EXECUTION_FINISHED; 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: default:
return COMMAND_NOT_IMPLEMENTED; return COMMAND_NOT_IMPLEMENTED;
} }
@ -449,23 +470,7 @@ bool PdecHandler::newTcReceived() {
return true; return true;
} }
void PdecHandler::checkLocks() { void PdecHandler::doPeriodicWork() { 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);
}
}
bool PdecHandler::checkFrameAna(uint32_t pdecFar) { bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
bool frameValid = false; bool frameValid = false;
@ -748,6 +753,33 @@ void PdecHandler::resetIrqLimiters() {
interruptCounter = 0; 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) { std::string PdecHandler::getMonStatusString(uint32_t status) {
switch (status) { switch (status) {
case TC_CHANNEL_INACTIVE: case TC_CHANNEL_INACTIVE:

View File

@ -3,6 +3,8 @@
#include <fsfw/timemanager/Countdown.h> #include <fsfw/timemanager/Countdown.h>
#include <atomic>
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "PdecConfig.h" #include "PdecConfig.h"
#include "eive/definitions.h" #include "eive/definitions.h"
@ -79,34 +81,6 @@ class PdecHandler : public SystemObject,
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
uint16_t startAtIndex) override; 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: private:
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; 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; 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 #ifdef TE0720_1CFA
static const int CONFIG_MEMORY_MAP_SIZE = 0x400; static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
static const int RAM_MAP_SIZE = 0x4000; 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; 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 { enum class IReason_t : uint8_t {
NO_REPORT, NO_REPORT,
ERROR_VERSION_NUMBER, ERROR_VERSION_NUMBER,
@ -258,6 +216,9 @@ class PdecHandler : public SystemObject,
bool carrierLock = false; bool carrierLock = false;
bool bitLock = false; bool bitLock = false;
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
bool ptmeResetWithReinitializationPending = false;
UioNames uioNames; UioNames uioNames;
ParameterHelper paramHelper; ParameterHelper paramHelper;
@ -325,6 +286,8 @@ class PdecHandler : public SystemObject,
* @brief Checks if carrier lock or bit lock has been detected and triggers appropriate * @brief Checks if carrier lock or bit lock has been detected and triggers appropriate
* event. * event.
*/ */
void doPeriodicWork();
void checkLocks(); void checkLocks();
void resetIrqLimiters(); void resetIrqLimiters();
@ -400,6 +363,8 @@ class PdecHandler : public SystemObject,
*/ */
void printPdecMon(); void printPdecMon();
void initFailedHandler(ReturnValue_t reason);
std::string getMonStatusString(uint32_t status); std::string getMonStatusString(uint32_t status);
}; };

View File

@ -1,10 +1,60 @@
#ifndef LINUX_OBC_PDEC_H_ #ifndef LINUX_OBC_PDEC_H_
#define LINUX_OBC_PDEC_H_ #define LINUX_OBC_PDEC_H_
#include <fsfw/action/ActionMessage.h>
#include <cstdint> #include <cstdint>
namespace pdec { 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 STAT_POSITION = 31;
static const uint8_t FRAME_ANA_POSITION = 28; static const uint8_t FRAME_ANA_POSITION = 28;
static const uint8_t IREASON_POSITION = 25; static const uint8_t IREASON_POSITION = 25;

View File

@ -8,6 +8,7 @@
#include <mission/com/defs.h> #include <mission/com/defs.h>
#include <mission/controller/tcsDefs.h> #include <mission/controller/tcsDefs.h>
#include "linux/ipcore/pdec.h"
#include "mission/power/bpxBattDefs.h" #include "mission/power/bpxBattDefs.h"
#include "mission/power/defs.h" #include "mission/power/defs.h"
#include "mission/sysDefs.h" #include "mission/sysDefs.h"
@ -62,6 +63,11 @@ void EiveSystem::performChildOperation() {
performSafeRecovery = false; performSafeRecovery = false;
return; return;
} }
if (frameDirtyCheckCd.hasTimedOut()) {
if (frameDirtyErrorCounter >= 4) {
}
frameDirtyErrorCounter = 0;
}
i2cRecoveryLogic(); i2cRecoveryLogic();
} }
@ -105,8 +111,7 @@ ReturnValue_t EiveSystem::initialize() {
manager->subscribeToEvent(eventQueue->getId(), manager->subscribeToEvent(eventQueue->getId(),
event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING)); event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING));
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING)); manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING));
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(pdec::INVALID_TC_FRAME));
// manager->subscribeToEvent(eventQueue->getId(), event::getEventId(CoreController::))
return Subsystem::initialize(); return Subsystem::initialize();
} }
@ -117,6 +122,12 @@ void EiveSystem::handleEventMessages() {
switch (event.getMessageId()) { switch (event.getMessageId()) {
case EventMessage::EVENT_MESSAGE: case EventMessage::EVENT_MESSAGE:
switch (event.getEvent()) { switch (event.getEvent()) {
case pdec::INVALID_TC_FRAME: {
if (event.getParameter1() == static_cast<uint32_t>(pdec::FrameAna_t::FRAME_DIRTY)) {
frameDirtyErrorCounter++;
}
break;
}
case tcsCtrl::OBC_OVERHEATING: case tcsCtrl::OBC_OVERHEATING:
case tcsCtrl::PCDU_SYSTEM_OVERHEATING: { case tcsCtrl::PCDU_SYSTEM_OVERHEATING: {
if (isInTransition) { if (isInTransition) {

View File

@ -9,6 +9,8 @@
class EiveSystem : public Subsystem, public HasActionsIF { class EiveSystem : public Subsystem, public HasActionsIF {
public: public:
static constexpr uint8_t FRAME_DIRTY_COM_REBOOT_LIMIT = 4;
static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10; static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10;
EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables, 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 performI2cReboot = false;
bool alreadyTriedI2cRecovery = false; bool alreadyTriedI2cRecovery = false;
uint8_t frameDirtyErrorCounter = 0;
Countdown frameDirtyCheckCd = Countdown(10000);
ActionHelper actionHelper; ActionHelper actionHelper;
PowerSwitchIF* powerSwitcher = nullptr; PowerSwitchIF* powerSwitcher = nullptr;
std::atomic_uint16_t& i2cErrors; std::atomic_uint16_t& i2cErrors;

View File

@ -105,9 +105,9 @@ ReturnValue_t ComSubsystem::initialize() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return ObjectManager::CHILD_INIT_FAILED; return ObjectManager::CHILD_INIT_FAILED;
} }
result = manager->subscribeToEventRange(eventQueue->getId(), result =
event::getEventId(PdecHandler::CARRIER_LOCK), manager->subscribeToEventRange(eventQueue->getId(), event::getEventId(pdec::CARRIER_LOCK),
event::getEventId(PdecHandler::BIT_LOCK_PDEC)); event::getEventId(pdec::BIT_LOCK_PDEC));
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ComSubsystem::initialize: Failed to subscribe to events from PDEC " sif::error << "ComSubsystem::initialize: Failed to subscribe to events from PDEC "
@ -167,11 +167,11 @@ void ComSubsystem::handleEventMessage(EventMessage *eventMessage) {
startRxOnlyRecovery(true); startRxOnlyRecovery(true);
break; break;
} }
case PdecHandler::BIT_LOCK_PDEC: { case pdec::BIT_LOCK_PDEC: {
handleBitLockEvent(); handleBitLockEvent();
break; break;
} }
case PdecHandler::CARRIER_LOCK: { case pdec::CARRIER_LOCK: {
handleCarrierLockEvent(); handleCarrierLockEvent();
break; break;
} }