From 89b68940bede3cecdb3958dec149211fb454fd47 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sun, 29 Aug 2021 07:31:34 +0200 Subject: [PATCH] ploc memory dumper wip --- bsp_q7s/devices/PlocMemoryDumper.cpp | 203 ++++++++++++++++++ bsp_q7s/devices/PlocMemoryDumper.h | 113 ++++++++++ .../PlocMemDumpDefinitions.h | 31 +++ .../PlocSupervisorDefinitions.h | 3 +- common/config/commonClassIds.h | 1 + common/config/commonSubsystemIds.h | 1 + 6 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 bsp_q7s/devices/PlocMemoryDumper.cpp create mode 100644 bsp_q7s/devices/PlocMemoryDumper.h create mode 100644 bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h diff --git a/bsp_q7s/devices/PlocMemoryDumper.cpp b/bsp_q7s/devices/PlocMemoryDumper.cpp new file mode 100644 index 00000000..34d94186 --- /dev/null +++ b/bsp_q7s/devices/PlocMemoryDumper.cpp @@ -0,0 +1,203 @@ +#include "fsfw/ipc/QueueFactory.h" +#include "PlocMemoryDumper.h" + +#include +#include +#include + +PlocMemoryDumper::PlocMemoryDumper(object_id_t objectId) : + SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { + commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); +} + +PlocMemoryDumper::~PlocMemoryDumper() { +} + +ReturnValue_t PlocMemoryDumper::initialize() { + + ReturnValue_t result = SystemObject::initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = commandActionHelper.initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = actionHelper.initialize(commandQueue); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t PlocMemoryDumper::performOperation(uint8_t operationCode) { + readCommandQueue(); + doStateMachine(); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t PlocMemoryDumper::executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + ReturnValue_t result = RETURN_FAILED; + + if (state != State::IDLE) { + return IS_BUSY; + } + + switch (actionId) { + case DUMP_MRAM: + SerializeAdapter::deSerialize(&mram.startAddress, &data, sizeof(mramStartAdress), + SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&mram.endAddress, &data, sizeof(mramStartAdress), + SerializeIF::Endianness::BIG); + if (mram.endAddress > MAX_MRAM_ADDRESS) { + return MRAM_ADDRESS_TOO_HIGH; + } + if (mram.endAddress <= mram.startAddress) { + return MRAM_INVALID_ADDRESS_COMBINATION; + } + state = State::COMMAND_FIRST_MRAM_DUMP; + break; + default: + sif::warning << "PlocMemoryDumper::executeAction: Received command with invalid action id" + << std::endl; + return INVALID_ACTION_ID; + } + + return RETURN_OK; +} + +MessageQueueId_t PlocMemoryDumper::getCommandQueue() const { + return commandQueue->getId(); +} + +MessageQueueIF* PlocMemoryDumper::getCommandQueuePtr() { + return commandQueue; +} + +void PlocMemoryDumper::readCommandQueue() { + CommandMessage message; + ReturnValue_t result; + + for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK; + result = commandQueue->receiveMessage(&message)) { + if (result != RETURN_OK) { + continue; + } + result = actionHelper.handleActionMessage(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + + result = commandActionHelper.handleReply(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + + sif::debug << "PlocMemoryDumper::readCommandQueue: Received message with invalid format" + << std::endl; + } +} + +void PlocMemoryDumper::doStateMachine() { + switch (state) { + case State::IDLE: + break; + case State::COMMAND_FIRST_MRAM_DUMP: + commandNextMramDump(PLOC_SPV::FIRST_MRAM_DUMP); + break; + case State::COMMAND_CONSECUTIVE_MRAM_DUMP: + commandNextMramDump(PLOC_SPV::CONSECUTIVE_MRAM_DUMP); + break; + case State::EXECUTING_MRAM_DUMP: + break; + default: + sif::debug << "PlocMemoryDumper::doStateMachine: Invalid state" << std::endl; + break; + } +} + +void PlocMemoryDumper::stepSuccessfulReceived(ActionId_t actionId, + uint8_t step) { +} + +void PlocMemoryDumper::stepFailedReceived(ActionId_t actionId, uint8_t step, + ReturnValue_t returnCode) { +} + +void PlocMemoryDumper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) { + +} + +void PlocMemoryDumper::completionSuccessfulReceived(ActionId_t actionId) { + switch (pendingCommand) { + case (PLOC_SPV::FIRST_MRAM_DUMP): + case (PLOC_SPV::CONSECUTIVE_MRAM_DUMP): + if (mram.endAddress == mram.startAddress) { + triggerEvent(MRAM_DUMP_FINISHED); + state = State::IDLE; + } + else { + state = State::COMMAND_MRAM_DUMP; + } + break; + default: + sif::debug << "PlocMemoryDumper::completionSuccessfulReceived: Invalid pending command" + << std::endl; + state = State::IDLE; + break; + } +} + +void PlocMemoryDumper::completionFailedReceived(ActionId_t actionId, + ReturnValue_t returnCode) { + switch(pendingCommand) { + case(PLOC_SPV::FIRST_MRAM_DUMP): + case(PLOC_SPV::CONSECUTIVE_MRAM_DUMP): + triggerEvent(MRAM_DUMP_FAILED, mram.lastStartAddress); + break; + default: + sif::debug << "PlocMemoryDumper::completionFailedReceived: Invalid pending command " + << std::endl; + break; + } + state = State::IDLE; +} + +void PlocMemoryDumper::commandNextMramDump(ActionId_t dumpCommand) { + ReturnValue_t result = RETURN_OK; + + uint32_t tempStartAddress = 0; + uint32_t tempEndAddress = 0; + + if (mram.endAddress - mram.startAddress > MAX_MRAM_DUMP_SIZE) { + tempStartAddress = mram.startAddress; + tempEndAddress = mram.startAddress + MAX_MRAM_DUMP_SIZE; + mram.startAddress += MAX_MRAM_DUMP_SIZE; + mram.lastStartAddress = tempStartAddress; + } + else { + tempStartAddress = mram.startAddress; + tempEndAddress = mram.endAddress; + mram.startAddress = mram.endAddress; + } + + MemoryParams params(tempStartAddress, tempEndAddress); + + result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, + dumpCommand, ¶ms); + if (result != RETURN_OK) { + sif::warning << "PlocMemoryDumper::commandNextMramDump: Failed to send mram dump command " + << "with start address " << tempStartAddress << " and end address " + << tempEndAddress << std::endl; + triggerEvent(SEND_MRAM_DUMP_FAILED, result, tempStartAddress); + state = State::IDLE; + pendingCommand = NONE; + return; + } + state = State::EXECUTING_MRAM_DUMP; + pendingCommand = dumpCommand; + return; +} + diff --git a/bsp_q7s/devices/PlocMemoryDumper.h b/bsp_q7s/devices/PlocMemoryDumper.h new file mode 100644 index 00000000..ef3a9212 --- /dev/null +++ b/bsp_q7s/devices/PlocMemoryDumper.h @@ -0,0 +1,113 @@ +#ifndef MISSION_DEVICES_PLOCMEMORYDUMPER_H_ +#define MISSION_DEVICES_PLOCMEMORYDUMPER_H_ + +#include +#include +#include "OBSWConfig.h" +#include "fsfw/action/CommandActionHelper.h" +#include "fsfw/action/ActionHelper.h" +#include "fsfw/action/HasActionsIF.h" +#include "fsfw/action/CommandsActionsIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "bsp_q7s/memory/SdCardManager.h" +#include "linux/fsfwconfig/objects/systemObjectList.h" +#include "fsfw/tmtcpacket/SpacePacket.h" + + +/** + * @brief Because the buffer of the linux tty driver is limited to 2 x 65535 bytes, this class is + * created to perform large dumps of PLOC memories. + * + * @details Currently the PLOC supervisor only implements the functionality to dump the MRAM. + * + * @author J. Meier + */ +class PlocMemoryDumper : public SystemObject, + public HasActionsIF, + public ExecutableObjectIF, + public HasReturnvaluesIF, + public CommandsActionsIF { +public: + + static const ActionId_t NONE = 0; + static const ActionId_t DUMP_MRAM = 1; + + PlocMemoryDumper(object_id_t objectId); + virtual ~PlocMemoryDumper(); + + ReturnValue_t performOperation(uint8_t operationCode = 0) override; + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size); + MessageQueueId_t getCommandQueue() const; + ReturnValue_t initialize() override; + MessageQueueIF* getCommandQueuePtr() override; + void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; + void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override; + void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override; + void completionSuccessfulReceived(ActionId_t actionId) override; + void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override; + +private: + + static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MEMORY_DUMPER; + + //! [EXPORT] : [COMMENT] The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000. + static const ReturnValue_t MRAM_ADDRESS_TOO_HIGH = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] The specified end address is lower than the start address + static const ReturnValue_t MRAM_INVALID_ADDRESS_COMBINATION = MAKE_RETURN_CODE(0xA1); + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MEMORY_DUMPER; + + //! [EXPORT] : [COMMENT] 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 + static const Event SEND_MRAM_DUMP_FAILED = MAKE_EVENT(0, severity::LOW); + //! [EXPORT] : [COMMENT] Received completion failure report form PLOC supervisor handler + //! P1: MRAM start address of failing dump command + static const Event MRAM_DUMP_FAILED = MAKE_EVENT(1, severity::LOW); + //! [EXPORT] : [COMMENT] MRAM dump finished successfully + static const Event MRAM_DUMP_FINISHED = MAKE_EVENT(2, severity::LOW); + + // Maximum size of mram dump which can be retrieved with one command + static const uint32_t MAX_MRAM_DUMP_SIZE = 100000; + static const uint32_t MAX_MRAM_ADDRESS = 0x7d000; + + MessageQueueIF* commandQueue = nullptr; + + CommandActionHelper commandActionHelper; + + ActionHelper actionHelper; + + enum class State: uint8_t { + IDLE, + COMMAND_FIRST_MRAM_DUMP, + COMMAND_CONSECUTIVE_MRAM_DUMP, + EXECUTING_MRAM_DUMP + }; + + State state = State::IDLE; + + ActionId_t pendingCommand = NONE; + + typedef struct MemoryRange { + // Stores the start address of the next memory range to dump + uint32_t startAddress; + uint32_t endAddress; + // Stores the start address of the last sent dump command + uint32_t lastStartAddress; + } MemoryRange_t; + + MemoryRange_t mram = {0, 0, 0}; + + void readCommandQueue(); + void doStateMachine(); + + /** + * @brief Sends the next mram dump command to the PLOC supervisor handler. + */ + void commandNextMramDump(); +}; + +#endif /* MISSION_DEVICES_PLOCMEMORYDUMPER_H_ */ diff --git a/bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h b/bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h new file mode 100644 index 00000000..e221ac1e --- /dev/null +++ b/bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h @@ -0,0 +1,31 @@ +#ifndef BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_ +#define BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_ + +class MemoryParams: public SerialLinkedListAdapter { +public: + + /** + * @brief Constructor + * @param startAddress Start of address range to dump + * @param endAddress End of address range to dump + */ + MemoryParams(uint32_t startAddress, uint32_t endAddress) : + startAddress(startAddress), endAddress(endAddress) { + setLinks(); + } +private: + + void setLinks() { + setStart(&startAddress); + startAddress.setNext(&endAddress); + } + + SerializeElement startAddress; + SerializeElement endAddress; + +}; + + + + +#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_ */ diff --git a/bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h b/bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h index a28418e7..87cf0cb2 100644 --- a/bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -42,7 +42,7 @@ static const DeviceCommandId_t ENABLE_NVMS = 26; static const DeviceCommandId_t SELECT_NVM = 27; static const DeviceCommandId_t RUN_AUTO_EM_TESTS = 28; static const DeviceCommandId_t WIPE_MRAM = 29; -static const DeviceCommandId_t DUMP_MRAM = 30; +static const DeviceCommandId_t FIRST_MRAM_DUMP = 30; static const DeviceCommandId_t SET_DBG_VERBOSITY = 31; static const DeviceCommandId_t CAN_LOOPBACK_TEST = 32; static const DeviceCommandId_t PRINT_CPU_STATS = 33; @@ -55,6 +55,7 @@ static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39; static const DeviceCommandId_t FACTORY_RESET_CLEAR_MIRROR = 40; static const DeviceCommandId_t FACTORY_RESET_CLEAR_CIRCULAR = 41; static const DeviceCommandId_t UPDATE_VERIFY = 42; +static const DeviceCommandId_t CONSECUTIVE_MRAM_DUMP = 41; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index 8f751df1..793cb1ba 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -21,6 +21,7 @@ enum commonClassIds: uint8_t { CCSDS_IP_CORE_BRIDGE, //IPCI PLOC_UPDATER, //PLUD GOM_SPACE_HANDLER, //GOMS + PLOC_MEMORY_DUMPER, //PLMEMDUMP COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index ab87d119..58ebac66 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -18,6 +18,7 @@ enum: uint8_t { PLOC_SUPERVISOR_HANDLER = 115, FILE_SYSTEM = 116, PLOC_UPDATER = 117, + PLOC_MEMORY_DUMPER = 118, COMMON_SUBSYSTEM_ID_END }; }