#include "PlocMemoryDumper.h" #include #include #include #include #include "fsfw/ipc/QueueFactory.h" PlocMemoryDumper::PlocMemoryDumper(object_id_t objectId) : SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { auto mqArgs = MqArgs(this->getObjectId()); commandQueue = QueueFactory::instance()->createMessageQueue( QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); } 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(Action* action) { return action->handle(); } ReturnValue_t PlocMemoryDumper::handleAction(DumpMemoryAction* action) { if (state != State::IDLE) { return IS_BUSY; } if (action->endAddress <= action->startAddress) { return MRAM_INVALID_ADDRESS_COMBINATION; } mram.startAddress = action->startAddress; mram.endAddress = action->endAddress; state = State::COMMAND_FIRST_MRAM_DUMP; return EXECUTION_FINISHED; } MessageQueueId_t PlocMemoryDumper::getCommandQueue() const { return commandQueue->getId(); } ActionHelper* PlocMemoryDumper::getActionHelper() { return &actionHelper; } MessageQueueIF* PlocMemoryDumper::getCommandQueuePtr() { return commandQueue; } void PlocMemoryDumper::readCommandQueue() { CommandMessage message; ReturnValue_t result = RETURN_OK; 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(supv::FIRST_MRAM_DUMP); break; case State::COMMAND_CONSECUTIVE_MRAM_DUMP: commandNextMramDump(supv::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) { triggerEvent(MRAM_DUMP_FAILED); state = State::IDLE; } void PlocMemoryDumper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {} void PlocMemoryDumper::completionSuccessfulReceived(ActionId_t actionId) { switch (pendingCommand) { case (supv::FIRST_MRAM_DUMP): case (supv::CONSECUTIVE_MRAM_DUMP): if (mram.endAddress == mram.startAddress) { triggerEvent(MRAM_DUMP_FINISHED); state = State::IDLE; } else { state = State::COMMAND_CONSECUTIVE_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 (supv::FIRST_MRAM_DUMP): case (supv::CONSECUTIVE_MRAM_DUMP): triggerEvent(MRAM_DUMP_FAILED, mram.lastStartAddress); pendingCommand = NONE; break; default: 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; } else { tempStartAddress = mram.startAddress; tempEndAddress = mram.endAddress; mram.startAddress = mram.endAddress; } mram.lastStartAddress = tempStartAddress; 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; }