diff --git a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h index 9c848160..348fed54 100644 --- a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -60,6 +60,7 @@ static const DeviceCommandId_t REQUEST_ADC_REPORT = 57; static const DeviceCommandId_t RESET_PL = 58; static const DeviceCommandId_t ENABLE_NVMS = 59; static const DeviceCommandId_t CONTINUE_UPDATE = 60; +static const DeviceCommandId_t MEMORY_CHECK = 61; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 100; @@ -267,8 +268,8 @@ static const uint32_t ADC_REPORT_SET_ID = ADC_REPORT; namespace recv_timeout { // Erase memory can require up to 60 seconds for execution -static const uint32_t ERASE_MEMORY = 60000; -static const uint32_t UPDATE_STATUS_REPORT = 70000; +static const uint32_t ERASE_MEMORY_TIMEOUT = 60000; +static const uint32_t UPDATE_STATUS_REPORT_TIMEOUT = 70000; } // namespace recv_timeout /** diff --git a/linux/devices/ploc/PlocSupervisorHandler.cpp b/linux/devices/ploc/PlocSupervisorHandler.cpp index 1ad77883..7bc78f61 100644 --- a/linux/devices/ploc/PlocSupervisorHandler.cpp +++ b/linux/devices/ploc/PlocSupervisorHandler.cpp @@ -132,6 +132,30 @@ ReturnValue_t PlocSupervisorHandler::executeAction(ActionId_t actionId, plocSupvHelperExecuting = true; return EXECUTION_FINISHED; } + case MEMORY_CHECK: { + size_t deserLen = 9; + uint8_t memId; + uint32_t startAddr; + uint32_t sizeToCheck; + result = + SerializeAdapter::deSerialize(&memId, &data, &deserLen, SerializeIF::Endianness::NETWORK); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::deSerialize(&startAddr, &data, &deserLen, + SerializeIF::Endianness::NETWORK); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::deSerialize(&sizeToCheck, &data, &deserLen, + SerializeIF::Endianness::NETWORK); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + supvHelper->performMemCheck(memId, startAddr, sizeToCheck); + plocSupvHelperExecuting = true; + return EXECUTION_FINISHED; + } case LOGGING_REQUEST_EVENT_BUFFERS: { if (size > config::MAX_PATH_SIZE) { return SupvReturnValuesIF::FILENAME_TOO_LONG; diff --git a/linux/devices/ploc/PlocSupvHelper.cpp b/linux/devices/ploc/PlocSupvHelper.cpp index a8858e25..f07acaef 100644 --- a/linux/devices/ploc/PlocSupvHelper.cpp +++ b/linux/devices/ploc/PlocSupvHelper.cpp @@ -57,6 +57,13 @@ ReturnValue_t PlocSupvHelper::performOperation(uint8_t operationCode) { internalState = InternalState::IDLE; break; } + case InternalState::CHECK_MEMORY: { + sif::info << "PlocSupvHelper::performUpdate: Memory Check" << std::endl; + result = handleCheckMemoryCommand(); + triggerEvent(SUPV_MEM_CHECK_STATUS, result); + internalState = InternalState::IDLE; + break; + } case InternalState::CONTINUE_UPDATE: { result = continueUpdate(); if (result == RETURN_OK) { @@ -143,6 +150,17 @@ ReturnValue_t PlocSupvHelper::performUpdate(std::string file, uint8_t memoryId, return result; } +ReturnValue_t PlocSupvHelper::performMemCheck(uint8_t memoryId, uint32_t startAddress, + size_t sizeToCheck) { + update.memoryId = memoryId; + update.startAddress = startAddress; + update.length = sizeToCheck; + internalState = InternalState::CHECK_MEMORY; + uartComIF->flushUartTxAndRxBuf(comCookie); + semaphore.release(); + return HasReturnvaluesIF::RETURN_OK; +} + void PlocSupvHelper::initiateUpdateContinuation() { internalState = InternalState::CONTINUE_UPDATE; semaphore.release(); @@ -260,19 +278,22 @@ ReturnValue_t PlocSupvHelper::writeUpdatePackets() { update.progressPercent = progPercent; if (progPercent % 5 == 0) { // Useful to allow restarting the update - triggerEvent(SUPV_UPDATE_PROGRESS, update.bytesWritten, update.sequenceCount); + triggerEvent(SUPV_UPDATE_PROGRESS, buildProgParams1(progPercent, update.sequenceCount), + update.bytesWritten); } } supv::WriteMemory packet(spParams); result = packet.buildPacket(seqFlags, update.sequenceCount, update.memoryId, update.startAddress + update.bytesWritten, dataLength, tempData); if (result != RETURN_OK) { - triggerEvent(WRITE_MEMORY_FAILED, update.bytesWritten, update.sequenceCount); + triggerEvent(WRITE_MEMORY_FAILED, buildProgParams1(progPercent, update.sequenceCount), + update.bytesWritten); return result; } result = handlePacketTransmission(packet); if (result != RETURN_OK) { - triggerEvent(WRITE_MEMORY_FAILED, update.bytesWritten, update.sequenceCount); + triggerEvent(WRITE_MEMORY_FAILED, buildProgParams1(progPercent, update.sequenceCount), + update.bytesWritten); return result; } update.sequenceCount++; @@ -286,6 +307,10 @@ ReturnValue_t PlocSupvHelper::writeUpdatePackets() { return result; } +uint32_t PlocSupvHelper::buildProgParams1(uint8_t percent, uint16_t seqCount) { + return (static_cast(percent) << 24) | static_cast(seqCount); +} + ReturnValue_t PlocSupvHelper::performEventBufferRequest() { using namespace supv; ReturnValue_t result = RETURN_OK; @@ -352,7 +377,7 @@ ReturnValue_t PlocSupvHelper::eraseMemory() { if (result != RETURN_OK) { return result; } - result = handlePacketTransmission(eraseMemory, supv::recv_timeout::ERASE_MEMORY); + result = handlePacketTransmission(eraseMemory, supv::recv_timeout::ERASE_MEMORY_TIMEOUT); if (result != RETURN_OK) { return result; } @@ -419,7 +444,7 @@ ReturnValue_t PlocSupvHelper::handleAck() { ReturnValue_t PlocSupvHelper::handleExe(uint32_t timeout) { ReturnValue_t result = RETURN_OK; - result = handleTmReception(supv::SIZE_EXE_REPORT, timeout); + result = handleTmReception(supv::SIZE_EXE_REPORT, tmBuf.data(), timeout); if (result != RETURN_OK) { triggerEvent(EXE_RECEPTION_FAILURE, result, static_cast(rememberApid)); sif::warning << "PlocSupvHelper::handleExe: Error in reception of execution report" @@ -443,13 +468,17 @@ ReturnValue_t PlocSupvHelper::handleExe(uint32_t timeout) { return RETURN_OK; } -ReturnValue_t PlocSupvHelper::handleTmReception(size_t remainingBytes, uint32_t timeout) { +ReturnValue_t PlocSupvHelper::handleTmReception(size_t remainingBytes, uint8_t* readBuf, + uint32_t timeout) { ReturnValue_t result = RETURN_OK; size_t readBytes = 0; size_t currentBytes = 0; Countdown countdown(timeout); + if (readBuf == nullptr) { + readBuf = tmBuf.data(); + } while (!countdown.hasTimedOut()) { - result = receive(tmBuf.data() + readBytes, ¤tBytes, remainingBytes); + result = receive(readBuf + readBytes, ¤tBytes, remainingBytes); if (result != RETURN_OK) { return result; } @@ -461,7 +490,7 @@ ReturnValue_t PlocSupvHelper::handleTmReception(size_t remainingBytes, uint32_t } if (remainingBytes != 0) { sif::warning << "PlocSupvHelper::handleTmReception: Failed to read " << std::dec - << remainingBytes << " bytes" << std::endl; + << remainingBytes << " remaining bytes" << std::endl; return RETURN_FAILED; } return result; @@ -549,6 +578,9 @@ ReturnValue_t PlocSupvHelper::calcImageCrc() { ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { ReturnValue_t result = RETURN_OK; resetSpParams(); + // Will hold status report for later processing + std::array statusReportBuf{}; + supv::UpdateStatusReport updateStatusReport(statusReportBuf.data(), statusReportBuf.size()); // Verification of update write procedure supv::CheckMemory packet(spParams); result = packet.buildPacket(update.memoryId, update.startAddress, update.length); @@ -564,42 +596,35 @@ ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() { return result; } - // Will hold status report for later processing - std::array statusReportBuf{}; - { - supv::UpdateStatusReport updateStatusReport(tmBuf.data(), tmBuf.size()); - result = handleTmReception(static_cast(updateStatusReport.getNominalSize()), - supv::recv_timeout::UPDATE_STATUS_REPORT); - if (result != RETURN_OK) { - sif::warning - << "PlocSupvHelper::handleCheckMemoryCommand: Failed to receive update status report" - << std::endl; - return result; - } - result = updateStatusReport.checkCrc(); - if (result != RETURN_OK) { - sif::warning << "PlocSupvHelper::handleTmReception: CRC check failed" << std::endl; - return result; - } - // We need to copy this into another buffer. Otherwise, it will be overwritten - // when reading the execution report. - std::memcpy(statusReportBuf.data(), tmBuf.data(), updateStatusReport.getNominalSize()); + result = + handleTmReception(static_cast(updateStatusReport.getNominalSize()), + statusReportBuf.data(), supv::recv_timeout::UPDATE_STATUS_REPORT_TIMEOUT); + if (result != RETURN_OK) { + sif::warning + << "PlocSupvHelper::handleCheckMemoryCommand: Failed to receive update status report" + << std::endl; + return result; + } + result = updateStatusReport.checkCrc(); + if (result != RETURN_OK) { + sif::warning << "PlocSupvHelper::handleTmReception: CRC check failed" << std::endl; + return result; } result = handleExe(CRC_EXECUTION_TIMEOUT); if (result != RETURN_OK) { return result; } + // Now process the status report - supv::UpdateStatusReport statusReportCopy(statusReportBuf.data(), statusReportBuf.size()); - result = statusReportCopy.parseDataField(); + result = updateStatusReport.parseDataField(); if (result != RETURN_OK) { return result; } - result = statusReportCopy.verifycrc(update.crc); + result = updateStatusReport.verifycrc(update.crc); if (result != RETURN_OK) { sif::warning << "PlocSupvHelper::handleCheckMemoryCommand: CRC failure. Expected CRC 0x" - << std::hex << update.crc << " but received CRC 0x" << statusReportCopy.getCrc() + << std::hex << update.crc << " but received CRC 0x" << updateStatusReport.getCrc() << std::endl; return result; } diff --git a/linux/devices/ploc/PlocSupvHelper.h b/linux/devices/ploc/PlocSupvHelper.h index d3bfc49c..ee745b54 100644 --- a/linux/devices/ploc/PlocSupvHelper.h +++ b/linux/devices/ploc/PlocSupvHelper.h @@ -84,14 +84,17 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha //! P2: Apid of command for which the reception of the execution report failed static const Event EXE_RECEPTION_FAILURE = MAKE_EVENT(18, severity::LOW); //! [EXPORT] : [COMMENT] Update procedure failed when sending packet. - //! P1: Bytes written, P2: Sequence Count + //! P1: First byte percent, Third and Fourht bytes Sequence Count, P2: Bytes written static const Event WRITE_MEMORY_FAILED = MAKE_EVENT(19, severity::LOW); static const Event SUPV_REPLY_SIZE_MISSMATCH = MAKE_EVENT(20, severity::LOW); static const Event SUPV_REPLY_CRC_MISSMATCH = MAKE_EVENT(21, severity::LOW); //! [EXPORT] : [COMMENT] Will be triggered every 5 percent of the update progress. - //! P1: Bytes written, P2: Sequence Count + //! P1: First byte percent, Third and Fourht bytes Sequence Count, P2: Bytes written static constexpr Event SUPV_UPDATE_PROGRESS = MAKE_EVENT(22, severity::INFO); + //! Status of memory check command + //! P1: Returncode, 0 for success, other value with returncode for failure + static constexpr Event SUPV_MEM_CHECK_STATUS = MAKE_EVENT(23, severity::INFO); PlocSupvHelper(object_id_t objectId); virtual ~PlocSupvHelper(); @@ -115,6 +118,7 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha size_t startBytesWritten, uint16_t initSeqCount); ReturnValue_t startUpdate(std::string file, uint8_t memoryId, uint32_t startAddress); + ReturnValue_t performMemCheck(uint8_t memoryId, uint32_t startAddress, size_t sizeToCheck); /** * @brief This initiate the continuation of a failed update. */ @@ -130,6 +134,8 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha */ void stopProcess(); + static uint32_t buildProgParams1(uint8_t percent, uint16_t seqCount); + private: static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_SUPV_HELPER; @@ -177,7 +183,7 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha EventBufferRequest eventBufferReq; - enum class InternalState { IDLE, UPDATE, CONTINUE_UPDATE, REQUEST_EVENT_BUFFER }; + enum class InternalState { IDLE, UPDATE, CONTINUE_UPDATE, REQUEST_EVENT_BUFFER, CHECK_MEMORY }; InternalState internalState = InternalState::IDLE; @@ -233,7 +239,8 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha * @note It can take up to 70 seconds until the supervisor replies with an acknowledgment * failure report. */ - ReturnValue_t handleTmReception(size_t remainingBytes, uint32_t timeout = 70000); + ReturnValue_t handleTmReception(size_t remainingBytes, uint8_t* readBuf = nullptr, + uint32_t timeout = 70000); ReturnValue_t checkReceivedTm(ploc::SpTmReader& reader); ReturnValue_t selectMemory(); diff --git a/tmtc b/tmtc index 57dbef74..b3f0c08b 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 57dbef741b225a023353d8dbf814727ba8b44895 +Subproject commit b3f0c08bd757c8b6616398eb6dbd64c9107d59bc