diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 536d4fe8..7ba018a4 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -170,7 +170,8 @@ void ObjectFactory::produce(void* args){ /* Configuration for MIO0 on TE0720-03-1CFA */ UartCookie* plocSupervisorCookie = new UartCookie(objects::PLOC_SUPERVISOR_HANDLER, std::string("/dev/ttyUL3"), UartModes::NON_CANONICAL, 115200, - PLOC_SPV::MAX_REPLY_SIZE); + PLOC_SPV::MAX_PACKET_SIZE * 20); + plocSupervisorCookie->setNoFixedSizeReply(); PlocSupervisorHandler* plocSupervisor = new PlocSupervisorHandler( objects::PLOC_SUPERVISOR_HANDLER, objects::UART_COM_IF, plocSupervisorCookie); plocSupervisor->setStartUpImmediately(); diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index a6708f98..cc1b88e5 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -36,14 +36,14 @@ void ObjectFactory::produceGenericObjects() { { PoolManager::LocalPoolConfig poolCfg = { - {100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024} + {100, 16}, {50, 32}, {25, 64}, {15, 128}, {10, 1024}, {5, 2048} }; new PoolManager(objects::TC_STORE, poolCfg); } { PoolManager::LocalPoolConfig poolCfg = { - {100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024} + {100, 16}, {50, 32}, {25, 64}, {15, 128}, {10, 1024}, {5, 2048} }; new PoolManager(objects::TM_STORE, poolCfg); } diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index cfb9ef3a..7a55e7a6 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -247,7 +247,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::SELECT_NVM); this->insertInCommandMap(PLOC_SPV::RUN_AUTO_EM_TESTS); this->insertInCommandMap(PLOC_SPV::WIPE_MRAM); - this->insertInCommandMap(PLOC_SPV::DUMP_MRAM); + this->insertInCommandAndReplyMap(PLOC_SPV::DUMP_MRAM, 3); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -260,6 +260,11 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { + if (nextReplyId == PLOC_SPV::DUMP_MRAM) { + *foundId = PLOC_SPV::DUMP_MRAM; + return parseMramPackets(start, remainingSize, foundLen); + } + ReturnValue_t result = RETURN_OK; uint16_t apid = (*(start) << 8 | *(start + 1)) & APID_MASK; @@ -325,6 +330,10 @@ ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id, result = handleLatchupStatusReport(packet); break; } + case (PLOC_SPV::DUMP_MRAM): { + result = handleMramDumpPacket(); + break; + } case (PLOC_SPV::EXE_REPORT): { result = handleExecutionReport(packet); break; @@ -429,6 +438,16 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite } break; } + case PLOC_SPV::DUMP_MRAM: { + enabledReplies = expectedMramDumpPackets + 2; + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC_SPV::DUMP_MRAM); + if (result != RETURN_OK) { + sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " + << PLOC_SPV::LATCHUP_REPORT << " not in replyMap" << std::endl; + } + break; + } case PLOC_SPV::RESTART_MPSOC: case PLOC_SPV::START_MPSOC: case PLOC_SPV::SHUTDOWN_MPSOC: @@ -454,7 +473,6 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite case PLOC_SPV::SELECT_NVM: case PLOC_SPV::RUN_AUTO_EM_TESTS: case PLOC_SPV::WIPE_MRAM: - case PLOC_SPV::DUMP_MRAM: case PLOC_SPV::SET_DBG_VERBOSITY: case PLOC_SPV::CAN_LOOPBACK_TEST: case PLOC_SPV::PRINT_CPU_STATS: @@ -823,6 +841,9 @@ void PlocSupervisorHandler::setNextReplyId() { case PLOC_SPV::GET_LATCHUP_STATUS_REPORT: nextReplyId = PLOC_SPV::LATCHUP_REPORT; break; + case PLOC_SPV::DUMP_MRAM: + nextReplyId = PLOC_SPV::DUMP_MRAM; + break; default: /* If no telemetry is expected the next reply is always the execution report */ nextReplyId = PLOC_SPV::EXE_REPORT; @@ -838,6 +859,16 @@ size_t PlocSupervisorHandler::getNextReplyLength(DeviceCommandId_t commandId){ return replyLen; } + if (nextReplyId == PLOC_SPV::DUMP_MRAM) { + /** + * Try to read 20 MRAM packets. If reply is larger, the packets will be read with the + * next doSendRead call. The command will be as long active as the packet with the sequence + * count indicating the last packet has not been received. + */ + replyLen = PLOC_SPV::MAX_PACKET_SIZE * 20; + return replyLen; + } + DeviceReplyIter iter = deviceReplyMap.find(nextReplyId); if (iter != deviceReplyMap.end()) { if (iter->second.delayCycles == 0) { @@ -1113,6 +1144,14 @@ void PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandData) { SerializeAdapter::deSerialize(&stop, &commandData, &size, SerializeIF::Endianness::BIG); PLOC_SPV::MramCmd packet(start, stop, PLOC_SPV::MramCmd::MramAction::DUMP); packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + expectedMramDumpPackets = (stop - start) / PLOC_SPV::MAX_DATA_CAPACITY; + if ((stop - start) % PLOC_SPV::MAX_DATA_CAPACITY) { + expectedMramDumpPackets++; + mramLastPktLen = (stop - start) % PLOC_SPV::MAX_DATA_CAPACITY; + } + else { + mramLastPktLen = 0; + } } void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { @@ -1143,6 +1182,13 @@ void PlocSupervisorHandler::disableAllReplies() { info->command = deviceCommandMap.end(); break; } + case PLOC_SPV::DUMP_MRAM: { + iter = deviceReplyMap.find(PLOC_SPV::DUMP_MRAM); + info = &(iter->second); + info->delayCycles = 0; + info->command = deviceCommandMap.end(); + break; + } default: { break; } @@ -1182,3 +1228,50 @@ void PlocSupervisorHandler::disableExeReportReply() { /* Expected replies is set to one here. The value will set to 0 in replyToReply() */ info->command->second.expectedReplies = 1; } + +ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t *packet, size_t remainingSize, + size_t* foundLen) { + uint16_t packetLen = 0; + + for (size_t idx = 0; idx < remainingSize; idx++) { + std::memcpy(spacePacketBuffer + bufferTop, packet + idx, 1); + bufferTop += 1; + *foundLen += 1; + if (bufferTop >= PLOC_SPV::SPACE_PACKET_HEADER_LENGTH) { + packetLen = spacePacketBuffer[4] << 8 | spacePacketBuffer[5]; + } + + if (bufferTop == PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1) { + packetInBuffer = true; + bufferTop = 0; + return RETURN_OK; + } + + if (bufferTop == PLOC_SPV::MAX_PACKET_SIZE) { + *foundLen = remainingSize; + disableAllReplies(); + bufferTop = 0; + return MRAM_PACKET_PARSING_FAILURE; + } + } + + return IGNORE_FULL_PACKET; +} + +ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket() { + + ReturnValue_t result = RETURN_OK; + + // Prepare packet for downlink + if (packetInBuffer) { + uint16_t packetLen = spacePacketBuffer[4] << 8 | spacePacketBuffer[5]; + result = verifyPacket(spacePacketBuffer, PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1); + if (result != RETURN_OK) { + sif::warning << "PlocSupervisorHandler::handleMramDumpPacket: CRC failure" << std::endl; + } + handleDeviceTM(spacePacketBuffer + PLOC_SPV::SPACE_PACKET_HEADER_LENGTH, packetLen - 1, + PLOC_SPV::DUMP_MRAM); + packetInBuffer = false; + } + return RETURN_OK; +} diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index 9736d1a2..35098ffb 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -73,6 +73,8 @@ private: static const ReturnValue_t SWEEP_PERIOD_TOO_SMALL = MAKE_RETURN_CODE(0xA9); //! [EXPORT] : [COMMENT] Receive auto EM test command with invalid test param. Valid params are 1 and 2. static const ReturnValue_t INVALID_TEST_PARAM = MAKE_RETURN_CODE(0xAA); + //! [EXPORT] : [COMMENT] Returned when scanning for MRAM dump packets failed. + static const ReturnValue_t MRAM_PACKET_PARSING_FAILURE = MAKE_RETURN_CODE(0xAB); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; @@ -90,18 +92,6 @@ private: uint8_t commandBuffer[PLOC_SPV::MAX_COMMAND_SIZE]; - /** - * @brief This object is incremented each time a packet is sent or received. By checking the - * packet sequence count of a received packet, no packets can be lost without noticing - * it. Only the least significant 14 bits represent the packet sequence count in a - * space packet. Thus the maximum value amounts to 16383 (0x3FFF). - * @note Normally this should never happen because the PLOC replies are always sent in a - * fixed order. However, the PLOC software checks this value and will return an ACK - * failure report in case the sequence count is not incremented with each transferred - * space packet. - */ - uint16_t packetSequenceCount = 0x3FFF; - /** * This variable is used to store the id of the next reply to receive. This is necessary * because the PLOC sends as reply to each command at least one acknowledgment and execution @@ -115,6 +105,17 @@ private: PLOC_SPV::BootStatusReport bootStatusReport; PLOC_SPV::LatchupStatusReport latchupStatusReport; + /** Number of expected replies following the MRAM dump command */ + uint32_t expectedMramDumpPackets = 0; + size_t mramLastPktLen = 0; + /** Set to true as soon as a complete space packet is present in the spacePacketBuffer */ + bool packetInBuffer = false; + /** Points to the next free position in the space packet buffer */ + uint16_t bufferTop = 0; + + /** This buffer is used to concatenate space packets received in two different read steps */ + uint8_t spacePacketBuffer[PLOC_SPV::MAX_PACKET_SIZE]; + /** * @brief This function checks the crc of the received PLOC reply. * @@ -266,6 +267,14 @@ private: * the variable expectedReplies of an active command will be set to 0. */ void disableExeReportReply(); + + /** + * @brief Function is called in scanForReply and fills the spacePacketBuffer with the read + * data until a full packet has been received. + */ + ReturnValue_t parseMramPackets(const uint8_t *packet, size_t remainingSize, size_t* foundlen); + + ReturnValue_t handleMramDumpPacket(); }; #endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index ce1400be..ff0f7bd9 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -77,7 +77,7 @@ static const uint16_t APID_UPDATE_STATUS_REPORT = 0x206; static const uint16_t APID_WDG_STATUS_REPORT = 0x207; static const uint16_t APID_LATCHUP_STATUS_REPORT = 0x208; static const uint16_t APID_SOC_SYSMON = 0x209; -static const uint16_t APID_MRAM = 0x20A; +static const uint16_t APID_MRAM_DUMP_TM = 0x20A; static const uint16_t APID_SRAM = 0x20B; static const uint16_t APID_NOR_DATA = 0x20C; static const uint16_t APID_DATA_LOGGER_DATA = 0x20D; @@ -137,8 +137,13 @@ static const uint8_t DATA_FIELD_OFFSET = 6; static const uint16_t LENGTH_EMPTY_TC = 2; // Only CRC will be transported with the data field /** This is the maximum length of a space packet as defined by the TAS ICD */ -static const size_t MAX_REPLY_SIZE = 1024; +//static const size_t MAX_REPLY_SIZE = 1024; static const size_t MAX_COMMAND_SIZE = 1024; +static const size_t MAX_DATA_CAPACITY = 1016; +/** This is the maximum size of a space packet for the supervisor */ +static const size_t MAX_PACKET_SIZE = 1024; + +static const uint8_t SPACE_PACKET_HEADER_LENGTH = 6; enum SequenceFlags { CONTINUED_PKT = 0b00, FIRST_PKT = 0b01, LAST_PKT = 0b10, STANDALONE_PKT = 0b11 @@ -1106,6 +1111,8 @@ public: * @param start Start address of the MRAM section to wipe or dump * @param stop End address of the MRAM section to wipe or dump * @param action Dump or wipe MRAM + * + * @note The content at the stop address is excluded from the dump or wipe operation. */ MramCmd(uint32_t start, uint32_t stop, MramAction action) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_IDLE_PACKET, diff --git a/tmtc b/tmtc index 1b1f26ac..6fcd52da 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 1b1f26ac3a948a320a29a16083613ea29789a378 +Subproject commit 6fcd52daa693040099cac85367863ad24e477f9a