From 134073fd848e524268ea701c9c9c39ec6f1a3ad8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 13 Nov 2023 15:33:11 +0100 Subject: [PATCH] continue PLOC SUPV --- .gitignore | 4 + cmake/scripts/q7s/q7s-make-debug.sh | 2 + cmake/scripts/q7s/q7s-make-release.sh | 2 + fsfw | 2 +- linux/payload/FreshSupvHandler.cpp | 206 +++++++++++++++++++++++++- linux/payload/FreshSupvHandler.h | 9 +- linux/payload/PlocSupervisorHandler.h | 20 --- linux/payload/plocSupvDefs.h | 20 +++ 8 files changed, 241 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 5419ca42..eb6a49fa 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,7 @@ __pycache__ !/.idea/cmake.xml generators/*.db + +# Clangd LSP +/compile_commands.json +/.cache diff --git a/cmake/scripts/q7s/q7s-make-debug.sh b/cmake/scripts/q7s/q7s-make-debug.sh index 0abbc3cb..a9536c97 100755 --- a/cmake/scripts/q7s/q7s-make-debug.sh +++ b/cmake/scripts/q7s/q7s-make-debug.sh @@ -24,6 +24,8 @@ if [ ! -z "${EIVE_Q7S_EM}" ]; then build_defs="EIVE_Q7S_EM=ON" fi +build_defs="${build_defs} CMAKE_EXPORT_COMPILE_COMMANDS=ON" + os_fsfw="linux" tgt_bsp="arm/q7s" build_dir="cmake-build-debug-q7s" diff --git a/cmake/scripts/q7s/q7s-make-release.sh b/cmake/scripts/q7s/q7s-make-release.sh index b86ca873..f5e970df 100755 --- a/cmake/scripts/q7s/q7s-make-release.sh +++ b/cmake/scripts/q7s/q7s-make-release.sh @@ -24,6 +24,8 @@ if [ ! -z "${EIVE_Q7S_EM}" ]; then build_defs="EIVE_Q7S_EM=ON" fi +build_defs="${build_defs} CMAKE_EXPORT_COMPILE_COMMANDS=ON" + os_fsfw="linux" tgt_bsp="arm/q7s" build_dir="cmake-build-release-q7s" diff --git a/fsfw b/fsfw index bf7fac07..d554062b 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit bf7fac071c6d181251dbf9dee908728455be0925 +Subproject commit d554062b86999fd4d94ce9c3fe0341b73984d1ce diff --git a/linux/payload/FreshSupvHandler.cpp b/linux/payload/FreshSupvHandler.cpp index ad743705..8e3abd88 100644 --- a/linux/payload/FreshSupvHandler.cpp +++ b/linux/payload/FreshSupvHandler.cpp @@ -1,8 +1,15 @@ #include "FreshSupvHandler.h" #include +#include #include +#include + +#include "eive/definitions.h" +#include "fsfw/ipc/MessageQueueIF.h" +#include "fsfw/ipc/QueueFactory.h" +#include "fsfw/returnvalues/returnvalue.h" using namespace supv; using namespace returnvalue; @@ -22,7 +29,9 @@ FreshSupvHandler::FreshSupvHandler(DhbConfig cfg, CookieIF* comCookie, Gpio uart bootStatusReport(this), latchupStatusReport(this), countersReport(this), - adcReport(this) {} + adcReport(this) { + eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5); +} void FreshSupvHandler::performDeviceOperation(uint8_t opCode) { if (not transitionActive and mode == MODE_OFF) { @@ -30,6 +39,20 @@ void FreshSupvHandler::performDeviceOperation(uint8_t opCode) { return; } if (opCode == OpCode::DEFAULT_OPERATION) { + EventMessage event; + for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK; + result = eventQueue->receiveMessage(&event)) { + switch (event.getMessageId()) { + case EventMessage::EVENT_MESSAGE: + handleEvent(&event); + break; + default: + sif::debug + << "PlocSupervisorHandler::performOperationHook: Did not subscribe to this event" + << " message" << std::endl; + break; + } + } if (transitionActive) { if (targetMode == MODE_ON or targetMode == MODE_NORMAL) { handleTransitionToOn(); @@ -175,9 +198,47 @@ ReturnValue_t FreshSupvHandler::executeAction(ActionId_t actionId, MessageQueueI const uint8_t* data, size_t size) { // TODO: Handle all commands here. Need to add them to some command map. Send command immediately // then. - using namespace supv; ReturnValue_t result; + if (uartManager.longerRequestActive()) { + return result::SUPV_HELPER_EXECUTING; + } + + switch (actionId) { + case PERFORM_UPDATE: { + if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) { + return result::FILENAME_TOO_LONG; + } + UpdateParams params; + result = extractUpdateCommand(data, size, params); + if (result != returnvalue::OK) { + return result; + } + result = uartManager.performUpdate(params); + if (result != returnvalue::OK) { + return result; + } + return EXECUTION_FINISHED; + } + case CONTINUE_UPDATE: { + uartManager.initiateUpdateContinuation(); + return EXECUTION_FINISHED; + } + case MEMORY_CHECK_WITH_FILE: { + UpdateParams params; + result = extractBaseParams(&data, size, params); + if (result != returnvalue::OK) { + return result; + } + if (not std::filesystem::exists(params.file)) { + return HasFileSystemIF::FILE_DOES_NOT_EXIST; + } + uartManager.performMemCheck(params.file, params.memId, params.startAddr); + return EXECUTION_FINISHED; + } + default: + break; + } if (isCommandAlreadyActive(actionId)) { return HasActionsIF::IS_BUSY; } @@ -454,6 +515,11 @@ ReturnValue_t FreshSupvHandler::sendCommand(TcBase& tc) { ReturnValue_t FreshSupvHandler::initialize() { uartManager.initializeInterface(comCookie); + + ReturnValue_t result = eventSubscription(); + if (result != returnvalue::OK) { + return result; + } return FreshDeviceHandlerBase::initialize(); } @@ -724,3 +790,139 @@ bool FreshSupvHandler::isCommandAlreadyActive(ActionId_t actionId) const { } return false; } + +ReturnValue_t FreshSupvHandler::extractUpdateCommand(const uint8_t* commandData, size_t size, + supv::UpdateParams& params) { + size_t remSize = size; + if (size > (config::MAX_FILENAME_SIZE + config::MAX_PATH_SIZE + sizeof(params.memId)) + + sizeof(params.startAddr) + sizeof(params.bytesWritten) + sizeof(params.seqCount) + + sizeof(uint8_t)) { + sif::warning << "PlocSupervisorHandler::extractUpdateCommand: Data size too big" << std::endl; + return result::INVALID_LENGTH; + } + ReturnValue_t result = returnvalue::OK; + result = extractBaseParams(&commandData, size, params); + result = SerializeAdapter::deSerialize(¶ms.bytesWritten, &commandData, &remSize, + SerializeIF::Endianness::BIG); + if (result != returnvalue::OK) { + sif::warning << "PlocSupervisorHandler::extractUpdateCommand: Failed to deserialize bytes " + "already written" + << std::endl; + return result; + } + result = SerializeAdapter::deSerialize(¶ms.seqCount, &commandData, &remSize, + SerializeIF::Endianness::BIG); + if (result != returnvalue::OK) { + sif::warning + << "PlocSupervisorHandler::extractUpdateCommand: Failed to deserialize start sequence count" + << std::endl; + return result; + } + uint8_t delMemRaw = 0; + result = SerializeAdapter::deSerialize(&delMemRaw, &commandData, &remSize, + SerializeIF::Endianness::BIG); + if (result != returnvalue::OK) { + sif::warning + << "PlocSupervisorHandler::extractUpdateCommand: Failed to deserialize whether to delete " + "memory" + << std::endl; + return result; + } + params.deleteMemory = delMemRaw; + return returnvalue::OK; +} + +ReturnValue_t FreshSupvHandler::extractBaseParams(const uint8_t** commandData, size_t& remSize, + supv::UpdateParams& params) { + bool nullTermFound = false; + for (size_t idx = 0; idx < remSize; idx++) { + if ((*commandData)[idx] == '\0') { + nullTermFound = true; + break; + } + } + if (not nullTermFound) { + return returnvalue::FAILED; + } + params.file = std::string(reinterpret_cast(*commandData)); + if (params.file.size() > (config::MAX_FILENAME_SIZE + config::MAX_PATH_SIZE)) { + sif::warning << "PlocSupervisorHandler::extractUpdateCommand: Filename too long" << std::endl; + return result::FILENAME_TOO_LONG; + } + *commandData += params.file.size() + SIZE_NULL_TERMINATOR; + remSize -= (params.file.size() + SIZE_NULL_TERMINATOR); + params.memId = **commandData; + *commandData += 1; + remSize -= 1; + ReturnValue_t result = SerializeAdapter::deSerialize(¶ms.startAddr, commandData, &remSize, + SerializeIF::Endianness::BIG); + if (result != returnvalue::OK) { + sif::warning << "PlocSupervisorHandler::extractBaseParams: Failed to deserialize start address" + << std::endl; + return result; + } + return result; +} + +void FreshSupvHandler::handleEvent(EventMessage* eventMessage) { + ReturnValue_t result = returnvalue::OK; + object_id_t objectId = eventMessage->getReporter(); + Event event = eventMessage->getEvent(); + switch (objectId) { + case objects::PLOC_SUPERVISOR_HELPER: { + // After execution of update procedure, PLOC is in a state where it draws approx. 700 mA of + // current. To leave this state the shutdown MPSoC command must be sent here. + if (event == PlocSupvUartManager::SUPV_UPDATE_FAILED || + event == PlocSupvUartManager::SUPV_UPDATE_SUCCESSFUL || + event == PlocSupvUartManager::SUPV_CONTINUE_UPDATE_FAILED || + event == PlocSupvUartManager::SUPV_CONTINUE_UPDATE_SUCCESSFUL || + event == PlocSupvUartManager::SUPV_MEM_CHECK_FAIL || + event == PlocSupvUartManager::SUPV_MEM_CHECK_OK) { + // Wait for a short period for the uart state machine to adjust + // TaskFactory::delayTask(5); + if (not isCommandAlreadyActive(supv::SHUTDOWN_MPSOC)) { + result = this->executeAction(supv::SHUTDOWN_MPSOC, MessageQueueIF::NO_QUEUE, nullptr, 0); + if (result != returnvalue::OK) { + triggerEvent(supv::SUPV_MPSOC_SHUTDOWN_BUILD_FAILED); + sif::warning << "PlocSupervisorHandler::handleEvent: Failed to build MPSoC shutdown " + "command" + << std::endl; + return; + } + } + } + break; + } + default: + sif::debug << "PlocMPSoCHandler::handleEvent: Did not subscribe to this event" << std::endl; + break; + } +} + +ReturnValue_t FreshSupvHandler::eventSubscription() { + ReturnValue_t result = returnvalue::OK; + EventManagerIF* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); + if (manager == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PlocSupervisorHandler::eventSubscritpion: Invalid event manager" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + ; + } + result = manager->registerListener(eventQueue->getId()); + if (result != returnvalue::OK) { + return result; + } + result = manager->subscribeToEventRange( + eventQueue->getId(), event::getEventId(PlocSupvUartManager::SUPV_UPDATE_FAILED), + event::getEventId(PlocSupvUartManager::SUPV_MEM_CHECK_FAIL)); + if (result != returnvalue::OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "PlocSupervisorHandler::eventSubscritpion: Failed to subscribe to events from " + " ploc supervisor helper" + << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + return result; +} diff --git a/linux/payload/FreshSupvHandler.h b/linux/payload/FreshSupvHandler.h index e61b269f..859dfa43 100644 --- a/linux/payload/FreshSupvHandler.h +++ b/linux/payload/FreshSupvHandler.h @@ -62,6 +62,7 @@ class FreshSupvHandler : public FreshDeviceHandlerBase { private: static constexpr bool SET_TIME_DURING_BOOT = true; + static const uint8_t SIZE_NULL_TERMINATOR = 1; enum class StartupState : uint8_t { IDLE, @@ -74,6 +75,7 @@ class FreshSupvHandler : public FreshDeviceHandlerBase { }; StartupState startupState = StartupState::IDLE; + MessageQueueIF* eventQueue = nullptr; enum class ShutdownState : uint8_t { IDLE, POWER_SWITCHING }; ShutdownState shutdownState = ShutdownState::IDLE; @@ -148,7 +150,12 @@ class FreshSupvHandler : public FreshDeviceHandlerBase { ReturnValue_t prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData); ReturnValue_t prepareSetAdcThresholdCmd(const uint8_t* commandData); ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData, size_t cmdDataLen); - + ReturnValue_t extractUpdateCommand(const uint8_t* commandData, size_t size, + supv::UpdateParams& params); + ReturnValue_t extractBaseParams(const uint8_t** commandData, size_t& remSize, + supv::UpdateParams& params); + void handleEvent(EventMessage* eventMessage); + ReturnValue_t eventSubscription(); bool isCommandAlreadyActive(ActionId_t actionId) const; }; diff --git a/linux/payload/PlocSupervisorHandler.h b/linux/payload/PlocSupervisorHandler.h index 8df4b3fb..85c3d94e 100644 --- a/linux/payload/PlocSupervisorHandler.h +++ b/linux/payload/PlocSupervisorHandler.h @@ -68,26 +68,6 @@ class PlocSupervisorHandler : public DeviceHandlerBase { void doOffActivity() override; private: - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; - - //! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet - static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW); - //! [EXPORT] : [COMMENT] Unhandled event. P1: APID, P2: Service ID - static constexpr Event SUPV_UNKNOWN_TM = MAKE_EVENT(2, severity::LOW); - static constexpr Event SUPV_UNINIMPLEMENTED_TM = MAKE_EVENT(3, severity::LOW); - //! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report - static const Event SUPV_ACK_FAILURE = MAKE_EVENT(4, severity::LOW); - //! [EXPORT] : [COMMENT] PLOC received execution failure report - //! P1: ID of command for which the execution failed - //! P2: Status code sent by the supervisor handler - static const Event SUPV_EXE_FAILURE = MAKE_EVENT(5, severity::LOW); - //! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc - static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(6, severity::LOW); - //! [EXPORT] : [COMMENT] Supervisor helper currently executing a command - static const Event SUPV_HELPER_EXECUTING = MAKE_EVENT(7, severity::LOW); - //! [EXPORT] : [COMMENT] Failed to build the command to shutdown the MPSoC - static const Event SUPV_MPSOC_SHUTDOWN_BUILD_FAILED = MAKE_EVENT(8, severity::LOW); - static const uint16_t APID_MASK = 0x7FF; static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF; static const uint8_t EXE_STATUS_OFFSET = 10; diff --git a/linux/payload/plocSupvDefs.h b/linux/payload/plocSupvDefs.h index e991c519..fc9b9abe 100644 --- a/linux/payload/plocSupvDefs.h +++ b/linux/payload/plocSupvDefs.h @@ -17,6 +17,26 @@ namespace supv { +static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; + +//! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet +static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW); +//! [EXPORT] : [COMMENT] Unhandled event. P1: APID, P2: Service ID +static constexpr Event SUPV_UNKNOWN_TM = MAKE_EVENT(2, severity::LOW); +static constexpr Event SUPV_UNINIMPLEMENTED_TM = MAKE_EVENT(3, severity::LOW); +//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report +static const Event SUPV_ACK_FAILURE = MAKE_EVENT(4, severity::LOW); +//! [EXPORT] : [COMMENT] PLOC received execution failure report +//! P1: ID of command for which the execution failed +//! P2: Status code sent by the supervisor handler +static const Event SUPV_EXE_FAILURE = MAKE_EVENT(5, severity::LOW); +//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc +static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(6, severity::LOW); +//! [EXPORT] : [COMMENT] Supervisor helper currently executing a command +static const Event SUPV_HELPER_EXECUTING = MAKE_EVENT(7, severity::LOW); +//! [EXPORT] : [COMMENT] Failed to build the command to shutdown the MPSoC +static const Event SUPV_MPSOC_SHUTDOWN_BUILD_FAILED = MAKE_EVENT(8, severity::LOW); + extern std::atomic_bool SUPV_ON; static constexpr uint32_t BOOT_TIMEOUT_MS = 4000; static constexpr uint32_t MAX_TRANSITION_TIME_TO_ON_MS = 6000;