From 4a4da86060fcce85faf27b1b5faa5cf1730c972c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 11 Apr 2024 16:23:09 +0200 Subject: [PATCH] leave the old stuff untouched --- bsp_q7s/objectFactory.cpp | 4 +- linux/payload/CMakeLists.txt | 1 + linux/payload/FreshMpsocHandler.cpp | 5 +- linux/payload/PlocMpsocHandler.cpp | 16 +- linux/payload/PlocMpsocHandler.h | 9 +- linux/payload/PlocMpsocSpecialComHelper.h | 3 - .../PlocMpsocSpecialComHelperLegacy.cpp | 545 ++++++++++++++++++ .../payload/PlocMpsocSpecialComHelperLegacy.h | 200 +++++++ 8 files changed, 762 insertions(+), 21 deletions(-) create mode 100644 linux/payload/PlocMpsocSpecialComHelperLegacy.cpp create mode 100644 linux/payload/PlocMpsocSpecialComHelperLegacy.h diff --git a/bsp_q7s/objectFactory.cpp b/bsp_q7s/objectFactory.cpp index 0f61a51d..76053538 100644 --- a/bsp_q7s/objectFactory.cpp +++ b/bsp_q7s/objectFactory.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -628,7 +628,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit new SerialCookie(objects::PLOC_MPSOC_HANDLER, q7s::UART_PLOC_MPSOC_DEV, serial::PLOC_MPSOC_BAUD, mpsoc::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); mpsocCookie->setNoFixedSizeReply(); - auto plocMpsocHelper = new PlocMpsocSpecialComHelper(objects::PLOC_MPSOC_HELPER); + auto plocMpsocHelper = new PlocMpsocSpecialComHelperLegacy(objects::PLOC_MPSOC_HELPER); auto* mpsocHandler = new PlocMpsocHandler( objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocCookie, plocMpsocHelper, Gpio(gpioIds::ENABLE_MPSOC_UART, gpioComIF), objects::PLOC_SUPERVISOR_HANDLER); diff --git a/linux/payload/CMakeLists.txt b/linux/payload/CMakeLists.txt index 9b52b9e5..fc51cd6d 100644 --- a/linux/payload/CMakeLists.txt +++ b/linux/payload/CMakeLists.txt @@ -6,6 +6,7 @@ target_sources( SerialCommunicationHelper.cpp FreshMpsocHandler.cpp FreshSupvHandler.cpp + PlocMpsocSpecialComHelperLegacy.cpp PlocMpsocSpecialComHelper.cpp plocMpsocHelpers.cpp PlocSupvUartMan.cpp diff --git a/linux/payload/FreshMpsocHandler.cpp b/linux/payload/FreshMpsocHandler.cpp index 9e16a339..7e5a9bad 100644 --- a/linux/payload/FreshMpsocHandler.cpp +++ b/linux/payload/FreshMpsocHandler.cpp @@ -1,4 +1,3 @@ - #include "FreshMpsocHandler.h" #include "fsfw/action/CommandActionHelper.h" @@ -9,11 +8,11 @@ #include "linux/payload/plocSupvDefs.h" FreshMpsocHandler::FreshMpsocHandler(DhbConfig cfg, MpsocCommunication& comInterface, - PlocMpsocSpecialComHelper* plocMPSoCHelper, + PlocMpsocSpecialComHelper* specialComHelper, Gpio uartIsolatorSwitch, object_id_t supervisorHandler) : FreshDeviceHandlerBase(cfg), comInterface(comInterface), - specialComHelper(plocMPSoCHelper), + specialComHelper(specialComHelper), commandActionHelper(this), uartIsolatorSwitch(uartIsolatorSwitch), hkReport(this) { diff --git a/linux/payload/PlocMpsocHandler.cpp b/linux/payload/PlocMpsocHandler.cpp index 6df5a59b..a8fb8a0e 100644 --- a/linux/payload/PlocMpsocHandler.cpp +++ b/linux/payload/PlocMpsocHandler.cpp @@ -2,15 +2,15 @@ #include #include -#include - #include "OBSWConfig.h" #include "fsfw/datapool/PoolReadGuard.h" #include "fsfw/globalfunctions/CRC.h" +#include "fsfw/ipc/QueueFactory.h" #include "fsfw/parameters/HasParametersIF.h" PlocMpsocHandler::PlocMpsocHandler(object_id_t objectId, object_id_t uartComIFid, - CookieIF* comCookie, PlocMpsocSpecialComHelper* plocMPSoCHelper, + CookieIF* comCookie, + PlocMpsocSpecialComHelperLegacy* plocMPSoCHelper, Gpio uartIsolatorSwitch, object_id_t supervisorHandler) : DeviceHandlerBase(objectId, uartComIFid, comCookie), hkReport(this), @@ -54,24 +54,26 @@ ReturnValue_t PlocMpsocHandler::initialize() { return result; } result = manager->subscribeToEvent( - eventQueue->getId(), event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_WRITE_FAILED)); + eventQueue->getId(), + event::getEventId(PlocMpsocSpecialComHelperLegacy::MPSOC_FLASH_WRITE_FAILED)); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } result = manager->subscribeToEvent( eventQueue->getId(), - event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_WRITE_SUCCESSFUL)); + event::getEventId(PlocMpsocSpecialComHelperLegacy::MPSOC_FLASH_WRITE_SUCCESSFUL)); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } result = manager->subscribeToEvent( eventQueue->getId(), - event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_READ_SUCCESSFUL)); + event::getEventId(PlocMpsocSpecialComHelperLegacy::MPSOC_FLASH_READ_SUCCESSFUL)); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } result = manager->subscribeToEvent( - eventQueue->getId(), event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_READ_FAILED)); + eventQueue->getId(), + event::getEventId(PlocMpsocSpecialComHelperLegacy::MPSOC_FLASH_READ_FAILED)); if (result != returnvalue::OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } diff --git a/linux/payload/PlocMpsocHandler.h b/linux/payload/PlocMpsocHandler.h index e31e40aa..a5eec028 100644 --- a/linux/payload/PlocMpsocHandler.h +++ b/linux/payload/PlocMpsocHandler.h @@ -1,18 +1,15 @@ #ifndef BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ #define BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ -#include +#include #include #include #include #include -#include - #include "fsfw/action/CommandActionHelper.h" #include "fsfw/action/CommandsActionsIF.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h" -#include "fsfw/ipc/QueueFactory.h" #include "fsfw/tmtcservices/SourceSequenceCounter.h" #include "fsfw_hal/linux/gpio/Gpio.h" #include "fsfw_hal/linux/serial/SerialComIF.h" @@ -48,7 +45,7 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF { * @param supervisorHandler Object ID of the supervisor handler */ PlocMpsocHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF* comCookie, - PlocMpsocSpecialComHelper* plocMPSoCHelper, Gpio uartIsolatorSwitch, + PlocMpsocSpecialComHelperLegacy* plocMPSoCHelper, Gpio uartIsolatorSwitch, object_id_t supervisorHandler); virtual ~PlocMpsocHandler(); virtual ReturnValue_t initialize() override; @@ -171,7 +168,7 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF { SerialComIF* uartComIf = nullptr; - PlocMpsocSpecialComHelper* specialComHelper = nullptr; + PlocMpsocSpecialComHelperLegacy* specialComHelper = nullptr; Gpio uartIsolatorSwitch; object_id_t supervisorHandler = 0; CommandActionHelper commandActionHelper; diff --git a/linux/payload/PlocMpsocSpecialComHelper.h b/linux/payload/PlocMpsocSpecialComHelper.h index 18071e8d..9772584e 100644 --- a/linux/payload/PlocMpsocSpecialComHelper.h +++ b/linux/payload/PlocMpsocSpecialComHelper.h @@ -6,14 +6,11 @@ #include -#include "OBSWConfig.h" -#include "fsfw/devicehandlers/CookieIF.h" #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/osal/linux/BinarySemaphore.h" #include "fsfw/returnvalues/returnvalue.h" #include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/tmtcservices/SourceSequenceCounter.h" -#include "fsfw_hal/linux/serial/SerialComIF.h" #include "linux/payload/MpsocCommunication.h" #ifdef XIPHOS_Q7S #include "bsp_q7s/fs/SdCardManager.h" diff --git a/linux/payload/PlocMpsocSpecialComHelperLegacy.cpp b/linux/payload/PlocMpsocSpecialComHelperLegacy.cpp new file mode 100644 index 00000000..5dcaeb18 --- /dev/null +++ b/linux/payload/PlocMpsocSpecialComHelperLegacy.cpp @@ -0,0 +1,545 @@ +#include +#include +#include +#include + +#include +#include + +#ifdef XIPHOS_Q7S +#include "bsp_q7s/fs/FilesystemHelper.h" +#endif + +#include "mission/utility/Timestamp.h" + +using namespace ploc; + +PlocMpsocSpecialComHelperLegacy::PlocMpsocSpecialComHelperLegacy(object_id_t objectId) + : SystemObject(objectId) { + spParams.buf = commandBuffer; + spParams.maxSize = sizeof(commandBuffer); +} + +PlocMpsocSpecialComHelperLegacy::~PlocMpsocSpecialComHelperLegacy() {} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::initialize() { +#ifdef XIPHOS_Q7S + sdcMan = SdCardManager::instance(); + if (sdcMan == nullptr) { + sif::warning << "PlocMPSoCHelper::initialize: Invalid SD Card Manager" << std::endl; + return returnvalue::FAILED; + } +#endif + return returnvalue::OK; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::performOperation(uint8_t operationCode) { + ReturnValue_t result = returnvalue::OK; + semaphore.acquire(); + while (true) { +#if OBSW_THREAD_TRACING == 1 + trace::threadTrace(opCounter, "PLOC MPSOC Helper"); +#endif + switch (internalState) { + case InternalState::IDLE: { + semaphore.acquire(); + break; + } + case InternalState::FLASH_WRITE: { + result = performFlashWrite(); + if (result == returnvalue::OK) { + triggerEvent(MPSOC_FLASH_WRITE_SUCCESSFUL, sequenceCount->get()); + } else { + triggerEvent(MPSOC_FLASH_WRITE_FAILED, sequenceCount->get()); + } + internalState = InternalState::IDLE; + break; + } + case InternalState::FLASH_READ: { + result = performFlashRead(); + if (result == returnvalue::OK) { + triggerEvent(MPSOC_FLASH_READ_SUCCESSFUL, sequenceCount->get()); + } else { + triggerEvent(MPSOC_FLASH_READ_FAILED, sequenceCount->get()); + } + internalState = InternalState::IDLE; + break; + } + default: + sif::debug << "PlocMPSoCHelper::performOperation: Invalid state" << std::endl; + break; + } + } +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::setComIF( + DeviceCommunicationIF* communicationInterface_) { + uartComIF = dynamic_cast(communicationInterface_); + if (uartComIF == nullptr) { + sif::warning << "PlocMPSoCHelper::initialize: Invalid uart com if" << std::endl; + return returnvalue::FAILED; + } + return returnvalue::OK; +} + +void PlocMpsocSpecialComHelperLegacy::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; } + +void PlocMpsocSpecialComHelperLegacy::setSequenceCount(SourceSequenceCounter* sequenceCount_) { + sequenceCount = sequenceCount_; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::startFlashWrite(std::string obcFile, + std::string mpsocFile) { + if (internalState != InternalState::IDLE) { + return returnvalue::FAILED; + } + ReturnValue_t result = startFlashReadOrWriteBase(std::move(obcFile), std::move(mpsocFile)); + if (result != returnvalue::OK) { + return result; + } + internalState = InternalState::FLASH_WRITE; + return semaphore.release(); +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::startFlashRead(std::string obcFile, + std::string mpsocFile, + size_t readFileSize) { + if (internalState != InternalState::IDLE) { + return returnvalue::FAILED; + } + ReturnValue_t result = startFlashReadOrWriteBase(std::move(obcFile), std::move(mpsocFile)); + if (result != returnvalue::OK) { + return result; + } + flashReadAndWrite.totalReadSize = readFileSize; + internalState = InternalState::FLASH_READ; + return semaphore.release(); +} + +void PlocMpsocSpecialComHelperLegacy::resetHelper() { + spParams.buf = commandBuffer; + terminate = false; + uartComIF->flushUartRxBuffer(comCookie); +} + +void PlocMpsocSpecialComHelperLegacy::stopProcess() { terminate = true; } + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::performFlashWrite() { + ReturnValue_t result = returnvalue::OK; + std::ifstream file(flashReadAndWrite.obcFile, std::ifstream::binary); + if (file.bad()) { + return returnvalue::FAILED; + } + result = flashfopen(mpsoc::FileAccessModes::WRITE | mpsoc::FileAccessModes::OPEN_ALWAYS); + if (result != returnvalue::OK) { + return result; + } + // Set position of next character to end of file input stream + file.seekg(0, file.end); + // tellg returns position of character in input stream + size_t remainingSize = file.tellg(); + size_t dataLength = 0; + size_t bytesRead = 0; + while (remainingSize > 0) { + if (terminate) { + return returnvalue::OK; + } + // The minus 4 is necessary for unknown reasons. Maybe some bug in the ILH software? + if (remainingSize > mpsoc::MAX_FLASH_WRITE_DATA_SIZE - 4) { + dataLength = mpsoc::MAX_FLASH_WRITE_DATA_SIZE - 4; + } else { + dataLength = remainingSize; + } + if (file.bad() or not file.is_open()) { + return FILE_WRITE_ERROR; + } + file.seekg(bytesRead, file.beg); + file.read(reinterpret_cast(fileBuf.data()), dataLength); + bytesRead += dataLength; + remainingSize -= dataLength; + mpsoc::TcFlashWrite tc(spParams, *sequenceCount); + result = tc.setPayload(fileBuf.data(), dataLength); + if (result != returnvalue::OK) { + return result; + } + result = tc.finishPacket(); + if (result != returnvalue::OK) { + return result; + } + (*sequenceCount)++; + result = handlePacketTransmissionNoReply(tc); + if (result != returnvalue::OK) { + return result; + } + } + result = flashfclose(); + if (result != returnvalue::OK) { + return result; + } + return result; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::performFlashRead() { + std::error_code e; + std::ofstream ofile(flashReadAndWrite.obcFile, std::ios::trunc | std::ios::binary); + if (ofile.bad()) { + return returnvalue::FAILED; + } + ReturnValue_t result = flashfopen(mpsoc::FileAccessModes::READ); + if (result != returnvalue::OK) { + std::filesystem::remove(flashReadAndWrite.obcFile, e); + return result; + } + size_t readSoFar = 0; + size_t nextReadSize = mpsoc::MAX_FLASH_READ_DATA_SIZE; + while (readSoFar < flashReadAndWrite.totalReadSize) { + if (terminate) { + std::filesystem::remove(flashReadAndWrite.obcFile, e); + return returnvalue::OK; + } + nextReadSize = mpsoc::MAX_FLASH_READ_DATA_SIZE; + if (flashReadAndWrite.totalReadSize - readSoFar < mpsoc::MAX_FLASH_READ_DATA_SIZE) { + nextReadSize = flashReadAndWrite.totalReadSize - readSoFar; + } + if (ofile.bad() or not ofile.is_open()) { + std::filesystem::remove(flashReadAndWrite.obcFile, e); + return FILE_READ_ERROR; + } + mpsoc::TcFlashRead flashReadRequest(spParams, *sequenceCount); + result = flashReadRequest.setPayload(nextReadSize); + if (result != returnvalue::OK) { + std::filesystem::remove(flashReadAndWrite.obcFile, e); + return result; + } + result = flashReadRequest.finishPacket(); + if (result != returnvalue::OK) { + std::filesystem::remove(flashReadAndWrite.obcFile, e); + return result; + } + (*sequenceCount)++; + result = handlePacketTransmissionFlashRead(flashReadRequest, ofile, nextReadSize); + if (result != returnvalue::OK) { + std::filesystem::remove(flashReadAndWrite.obcFile, e); + return result; + } + readSoFar += nextReadSize; + } + result = flashfclose(); + if (result != returnvalue::OK) { + return result; + } + return result; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::flashfopen(uint8_t mode) { + spParams.buf = commandBuffer; + mpsoc::FlashFopen flashFopen(spParams, *sequenceCount); + ReturnValue_t result = flashFopen.setPayload(flashReadAndWrite.mpsocFile, mode); + if (result != returnvalue::OK) { + return result; + } + result = flashFopen.finishPacket(); + if (result != returnvalue::OK) { + return result; + } + (*sequenceCount)++; + result = handlePacketTransmissionNoReply(flashFopen); + if (result != returnvalue::OK) { + return result; + } + return returnvalue::OK; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::flashfclose() { + spParams.buf = commandBuffer; + mpsoc::FlashFclose flashFclose(spParams, *sequenceCount); + ReturnValue_t result = flashFclose.finishPacket(); + if (result != returnvalue::OK) { + return result; + } + (*sequenceCount)++; + result = handlePacketTransmissionNoReply(flashFclose); + if (result != returnvalue::OK) { + return result; + } + return result; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::handlePacketTransmissionFlashRead( + mpsoc::TcFlashRead& tc, std::ofstream& ofile, size_t expectedReadLen) { + ReturnValue_t result = sendCommand(tc); + if (result != returnvalue::OK) { + return result; + } + result = handleAck(); + if (result != returnvalue::OK) { + return result; + } + result = handleTmReception(); + if (result != returnvalue::OK) { + return result; + } + + // We have the nominal case where the flash read report appears first, or the case where we + // get an EXE failure immediately. + if (spReader.getApid() == mpsoc::apid::TM_FLASH_READ_REPORT) { + result = handleFlashReadReply(ofile, expectedReadLen); + if (result != returnvalue::OK) { + return result; + } + return handleExe(); + } else if (spReader.getApid() == mpsoc::apid::EXE_FAILURE) { + handleExeFailure(); + } else { + triggerEvent(MPSOC_EXE_INVALID_APID, spReader.getApid(), static_cast(internalState)); + sif::warning << "PLOC MPSoC: Expected execution report " + << "but received space packet with apid " << std::hex << spReader.getApid() + << std::endl; + } + return returnvalue::FAILED; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::handlePacketTransmissionNoReply(ploc::SpTcBase& tc) { + ReturnValue_t result = sendCommand(tc); + if (result != returnvalue::OK) { + return result; + } + result = handleAck(); + if (result != returnvalue::OK) { + return result; + } + return handleExe(); +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::sendCommand(ploc::SpTcBase& tc) { + ReturnValue_t result = returnvalue::OK; + result = uartComIF->sendMessage(comCookie, tc.getFullPacket(), tc.getFullPacketLen()); + if (result != returnvalue::OK) { + sif::warning << "PlocMPSoCHelper::sendCommand: Failed to send command" << std::endl; + triggerEvent(MPSOC_SENDING_COMMAND_FAILED, result, static_cast(internalState)); + return result; + } + return result; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::handleAck() { + ReturnValue_t result = returnvalue::OK; + result = handleTmReception(); + if (result != returnvalue::OK) { + return result; + } + result = checkReceivedTm(); + if (result != returnvalue::OK) { + return result; + } + uint16_t apid = spReader.getApid(); + if (apid != mpsoc::apid::ACK_SUCCESS) { + handleAckApidFailure(spReader); + return returnvalue::FAILED; + } + return returnvalue::OK; +} + +void PlocMpsocSpecialComHelperLegacy::handleAckApidFailure(const ploc::SpTmReader& reader) { + uint16_t apid = reader.getApid(); + if (apid == mpsoc::apid::ACK_FAILURE) { + uint16_t status = mpsoc::getStatusFromRawData(reader.getFullData()); + sif::warning << "PLOC MPSoC ACK Failure: " << mpsoc::getStatusString(status) << std::endl; + triggerEvent(MPSOC_ACK_FAILURE_REPORT, static_cast(internalState), status); + } else { + triggerEvent(MPSOC_ACK_INVALID_APID, apid, static_cast(internalState)); + sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Expected acknowledgement report " + << "but received space packet with apid " << std::hex << apid << std::endl; + } +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::handleExe() { + ReturnValue_t result = returnvalue::OK; + + result = handleTmReception(); + if (result != returnvalue::OK) { + return result; + } + result = checkReceivedTm(); + if (result != returnvalue::OK) { + return result; + } + uint16_t apid = spReader.getApid(); + if (apid == mpsoc::apid::EXE_FAILURE) { + handleExeFailure(); + return returnvalue::FAILED; + } else if (apid != mpsoc::apid::EXE_SUCCESS) { + triggerEvent(MPSOC_EXE_INVALID_APID, apid, static_cast(internalState)); + sif::warning << "PLOC MPSoC: Expected execution report " + << "but received space packet with apid " << std::hex << apid << std::endl; + } + return returnvalue::OK; +} + +void PlocMpsocSpecialComHelperLegacy::handleExeFailure() { + uint16_t status = mpsoc::getStatusFromRawData(spReader.getFullData()); + sif::warning << "PLOC MPSoC EXE Failure: " << mpsoc::getStatusString(status) << std::endl; + triggerEvent(MPSOC_EXE_FAILURE_REPORT, static_cast(internalState)); +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::handleTmReception() { + ReturnValue_t result = returnvalue::OK; + tmCountdown.resetTimer(); + size_t readBytes = 0; + size_t currentBytes = 0; + uint32_t usleepDelay = 5; + size_t fullPacketLen = 0; + while (true) { + if (tmCountdown.hasTimedOut()) { + triggerEvent(MPSOC_READ_TIMEOUT, tmCountdown.getTimeoutMs()); + return returnvalue::FAILED; + } + result = receive(tmBuf.data() + readBytes, 6, ¤tBytes); + if (result != returnvalue::OK) { + return result; + } + spReader.setReadOnlyData(tmBuf.data(), tmBuf.size()); + fullPacketLen = spReader.getFullPacketLen(); + readBytes += currentBytes; + if (readBytes == 6) { + break; + } + usleep(usleepDelay); + if (usleepDelay < 200000) { + usleepDelay *= 4; + } + } + while (true) { + if (tmCountdown.hasTimedOut()) { + triggerEvent(MPSOC_READ_TIMEOUT, tmCountdown.getTimeoutMs()); + return returnvalue::FAILED; + } + result = receive(tmBuf.data() + readBytes, fullPacketLen - readBytes, ¤tBytes); + readBytes += currentBytes; + if (fullPacketLen == readBytes) { + break; + } + usleep(usleepDelay); + if (usleepDelay < 200000) { + usleepDelay *= 4; + } + } + // arrayprinter::print(tmBuf.data(), readBytes); + return result; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::handleFlashReadReply(std::ofstream& ofile, + size_t expectedReadLen) { + ReturnValue_t result = checkReceivedTm(); + if (result != returnvalue::OK) { + return result; + } + uint16_t apid = spReader.getApid(); + if (apid != mpsoc::apid::TM_FLASH_READ_REPORT) { + triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_APID_ERROR); + sif::warning << "PLOC MPSoC Flash Read: Unexpected APID" << std::endl; + return result; + } + const uint8_t* packetData = spReader.getPacketData(); + size_t deserDummy = spReader.getPacketDataLen() - mpsoc::CRC_SIZE; + uint32_t receivedReadLen = 0; + // I think this is buggy, weird stuff in the short name field. + // std::string receivedShortName = std::string(reinterpret_cast(packetData), 12); + // if (receivedShortName != flashReadAndWrite.mpsocFile.substr(0, 11)) { + // sif::warning << "PLOC MPSoC Flash Read: Missmatch between request file name and " + // "received file name" + // << std::endl; + // triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_FILENAME_ERROR); + // return returnvalue::FAILED; + // } + packetData += 12; + result = SerializeAdapter::deSerialize(&receivedReadLen, &packetData, &deserDummy, + SerializeIF::Endianness::NETWORK); + if (result != returnvalue::OK) { + return result; + } + if (receivedReadLen != expectedReadLen) { + sif::warning << "PLOC MPSoC Flash Read: Missmatch between request read length and " + "received read length" + << std::endl; + triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_READLEN_ERROR); + return returnvalue::FAILED; + } + ofile.write(reinterpret_cast(packetData), receivedReadLen); + return returnvalue::OK; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::fileCheck(std::string obcFile) { +#ifdef XIPHOS_Q7S + ReturnValue_t result = FilesystemHelper::checkPath(obcFile); + if (result != returnvalue::OK) { + return result; + } +#elif defined(TE0720_1CFA) + if (not std::filesystem::exists(obcFile)) { + sif::warning << "PlocMPSoCHelper::startFlashWrite: File " << obcFile << "does not exist" + << std::endl; + return returnvalue::FAILED; + } +#endif + return returnvalue::OK; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::startFlashReadOrWriteBase(std::string obcFile, + std::string mpsocFile) { + ReturnValue_t result = fileCheck(obcFile); + if (result != returnvalue::OK) { + return result; + } + + flashReadAndWrite.obcFile = std::move(obcFile); + flashReadAndWrite.mpsocFile = std::move(mpsocFile); + resetHelper(); + return returnvalue::OK; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::checkReceivedTm() { + ReturnValue_t result = spReader.checkSize(); + if (result != returnvalue::OK) { + sif::error << "PLOC MPSoC: Size check on received TM failed" << std::endl; + triggerEvent(MPSOC_TM_SIZE_ERROR); + return result; + } + result = spReader.checkCrc(); + if (result != returnvalue::OK) { + sif::warning << "PLOC MPSoC: CRC check failed" << std::endl; + triggerEvent(MPSOC_TM_CRC_MISSMATCH, *sequenceCount); + return result; + } + uint16_t recvSeqCnt = spReader.getSequenceCount(); + if (recvSeqCnt != *sequenceCount) { + triggerEvent(MPSOC_HELPER_SEQ_CNT_MISMATCH, *sequenceCount, recvSeqCnt); + *sequenceCount = recvSeqCnt; + } + // This sequence count ping pong does not make any sense but it is how the MPSoC expects it. + (*sequenceCount)++; + return returnvalue::OK; +} + +ReturnValue_t PlocMpsocSpecialComHelperLegacy::receive(uint8_t* data, size_t requestBytes, + size_t* readBytes) { + ReturnValue_t result = returnvalue::OK; + uint8_t* buffer = nullptr; + result = uartComIF->requestReceiveMessage(comCookie, requestBytes); + if (result != returnvalue::OK) { + sif::warning << "PlocMPSoCHelper::receive: Failed to request reply" << std::endl; + triggerEvent(MPSOC_HELPER_REQUESTING_REPLY_FAILED, result, + static_cast(static_cast(internalState))); + return returnvalue::FAILED; + } + result = uartComIF->readReceivedMessage(comCookie, &buffer, readBytes); + if (result != returnvalue::OK) { + sif::warning << "PlocMPSoCHelper::receive: Failed to read received message" << std::endl; + triggerEvent(MPSOC_HELPER_READING_REPLY_FAILED, result, static_cast(internalState)); + return returnvalue::FAILED; + } + if (*readBytes > 0) { + std::memcpy(data, buffer, *readBytes); + } + return result; +} diff --git a/linux/payload/PlocMpsocSpecialComHelperLegacy.h b/linux/payload/PlocMpsocSpecialComHelperLegacy.h new file mode 100644 index 00000000..e3d5370f --- /dev/null +++ b/linux/payload/PlocMpsocSpecialComHelperLegacy.h @@ -0,0 +1,200 @@ +#ifndef BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_ +#define BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_ + +#include +#include + +#include + +#include "OBSWConfig.h" +#include "fsfw/devicehandlers/CookieIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/osal/linux/BinarySemaphore.h" +#include "fsfw/returnvalues/returnvalue.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/tmtcservices/SourceSequenceCounter.h" +#include "fsfw_hal/linux/serial/SerialComIF.h" +#ifdef XIPHOS_Q7S +#include "bsp_q7s/fs/SdCardManager.h" +#endif + +/** + * @brief Helper class for MPSoC of PLOC intended to accelerate large data transfers between + * MPSoC and OBC. + * @author J. Meier + */ +class PlocMpsocSpecialComHelperLegacy : public SystemObject, public ExecutableObjectIF { + public: + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HELPER; + + //! [EXPORT] : [COMMENT] Flash write fails + static const Event MPSOC_FLASH_WRITE_FAILED = MAKE_EVENT(0, severity::LOW); + //! [EXPORT] : [COMMENT] Flash write successful + static const Event MPSOC_FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(1, severity::INFO); + //! [EXPORT] : [COMMENT] Communication interface returned failure when trying to send the command + //! to the MPSoC + //! P1: Return value returned by the communication interface sendMessage function + //! P2: Internal state of MPSoC helper + static const Event MPSOC_SENDING_COMMAND_FAILED = MAKE_EVENT(2, severity::LOW); + //! [EXPORT] : [COMMENT] Request receive message of communication interface failed + //! P1: Return value returned by the communication interface requestReceiveMessage function + //! P2: Internal state of MPSoC helper + static const Event MPSOC_HELPER_REQUESTING_REPLY_FAILED = MAKE_EVENT(3, severity::LOW); + //! [EXPORT] : [COMMENT] Reading receive message of communication interface failed + //! P1: Return value returned by the communication interface readingReceivedMessage function + //! P2: Internal state of MPSoC helper + static const Event MPSOC_HELPER_READING_REPLY_FAILED = MAKE_EVENT(4, severity::LOW); + //! [EXPORT] : [COMMENT] Did not receive acknowledgment report + //! P1: Number of bytes missing + //! P2: Internal state of MPSoC helper + static const Event MPSOC_MISSING_ACK = MAKE_EVENT(5, severity::LOW); + //! [EXPORT] : [COMMENT] Did not receive execution report + //! P1: Number of bytes missing + //! P2: Internal state of MPSoC helper + static const Event MPSOC_MISSING_EXE = MAKE_EVENT(6, severity::LOW); + //! [EXPORT] : [COMMENT] Received acknowledgment failure report + //! P1: Internal state of MPSoC + static const Event MPSOC_ACK_FAILURE_REPORT = MAKE_EVENT(7, severity::LOW); + //! [EXPORT] : [COMMENT] Received execution failure report + //! P1: Internal state of MPSoC + static const Event MPSOC_EXE_FAILURE_REPORT = MAKE_EVENT(8, severity::LOW); + //! [EXPORT] : [COMMENT] Expected acknowledgment report but received space packet with other apid + //! P1: Apid of received space packet + //! P2: Internal state of MPSoC + static const Event MPSOC_ACK_INVALID_APID = MAKE_EVENT(9, severity::LOW); + //! [EXPORT] : [COMMENT] Expected execution report but received space packet with other apid + //! P1: Apid of received space packet + //! P2: Internal state of MPSoC + static const Event MPSOC_EXE_INVALID_APID = MAKE_EVENT(10, severity::LOW); + //! [EXPORT] : [COMMENT] Received sequence count does not match expected sequence count + //! P1: Expected sequence count + //! P2: Received sequence count + static const Event MPSOC_HELPER_SEQ_CNT_MISMATCH = MAKE_EVENT(11, severity::LOW); + static const Event MPSOC_TM_SIZE_ERROR = MAKE_EVENT(12, severity::LOW); + static const Event MPSOC_TM_CRC_MISSMATCH = MAKE_EVENT(13, severity::LOW); + static const Event MPSOC_FLASH_READ_PACKET_ERROR = MAKE_EVENT(14, severity::LOW); + static const Event MPSOC_FLASH_READ_FAILED = MAKE_EVENT(15, severity::LOW); + static const Event MPSOC_FLASH_READ_SUCCESSFUL = MAKE_EVENT(16, severity::INFO); + static const Event MPSOC_READ_TIMEOUT = MAKE_EVENT(17, severity::LOW); + + enum FlashReadErrorType : uint32_t { + FLASH_READ_APID_ERROR = 0, + FLASH_READ_FILENAME_ERROR = 1, + FLASH_READ_READLEN_ERROR = 2 + }; + + PlocMpsocSpecialComHelperLegacy(object_id_t objectId); + virtual ~PlocMpsocSpecialComHelperLegacy(); + + ReturnValue_t initialize() override; + ReturnValue_t performOperation(uint8_t operationCode = 0) override; + + ReturnValue_t setComIF(DeviceCommunicationIF* communicationInterface_); + void setComCookie(CookieIF* comCookie_); + + /** + * @brief Starts flash write sequence + * + * @param obcFile File where to read from the data + * @param mpsocFile The file of the MPSoC where should be written to + * + * @return returnvalue::OK if successful, otherwise error return value + */ + ReturnValue_t startFlashWrite(std::string obcFile, std::string mpsocFile); + /** + * + * @param obcFile Full target file name on OBC + * @param mpsocFile The file on the MPSoC which should be copied ot the OBC + * @param readFileSize The size of the file on the MPSoC. + * @return + */ + ReturnValue_t startFlashRead(std::string obcFile, std::string mpsocFile, size_t readFileSize); + + /** + * @brief Can be used to interrupt a running data transfer. + */ + void stopProcess(); + + /** + * @brief Sets the sequence count object responsible for the sequence count handling + */ + void setSequenceCount(SourceSequenceCounter* sequenceCount_); + + private: + static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MPSOC_HELPER; + + //! [EXPORT] : [COMMENT] File error occured for file transfers from OBC to the MPSoC. + static const ReturnValue_t FILE_WRITE_ERROR = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] File error occured for file transfers from MPSoC to OBC. + static const ReturnValue_t FILE_READ_ERROR = MAKE_RETURN_CODE(0xA1); + + // Maximum number of times the communication interface retries polling data from the reply + // buffer + static const int RETRIES = 10000; + + struct FlashInfo { + std::string obcFile; + std::string mpsocFile; + }; + + struct FlashRead : public FlashInfo { + size_t totalReadSize = 0; + }; + + struct FlashRead flashReadAndWrite; +#if OBSW_THREAD_TRACING == 1 + uint32_t opCounter = 0; +#endif + + enum class InternalState { IDLE, FLASH_WRITE, FLASH_READ }; + + InternalState internalState = InternalState::IDLE; + + BinarySemaphore semaphore; +#ifdef XIPHOS_Q7S + SdCardManager* sdcMan = nullptr; +#endif + uint8_t commandBuffer[mpsoc::MAX_COMMAND_SIZE]; + SpacePacketCreator creator; + ploc::SpTcParams spParams = ploc::SpTcParams(creator); + + Countdown tmCountdown = Countdown(5000); + + std::array fileBuf{}; + std::array tmBuf{}; + + bool terminate = false; + + /** + * Communication interface of MPSoC responsible for low level access. Must be set by the + * MPSoC Handler. + */ + SerialComIF* uartComIF = nullptr; + // Communication cookie. Must be set by the MPSoC Handler + CookieIF* comCookie = nullptr; + // Sequence count, must be set by Ploc MPSoC Handler + SourceSequenceCounter* sequenceCount = nullptr; + ploc::SpTmReader spReader; + + void resetHelper(); + ReturnValue_t performFlashWrite(); + ReturnValue_t performFlashRead(); + ReturnValue_t flashfopen(uint8_t accessMode); + ReturnValue_t flashfclose(); + ReturnValue_t handlePacketTransmissionNoReply(ploc::SpTcBase& tc); + ReturnValue_t handlePacketTransmissionFlashRead(mpsoc::TcFlashRead& tc, std::ofstream& ofile, + size_t expectedReadLen); + ReturnValue_t handleFlashReadReply(std::ofstream& ofile, size_t expectedReadLen); + ReturnValue_t sendCommand(ploc::SpTcBase& tc); + ReturnValue_t receive(uint8_t* data, size_t requestBytes, size_t* readBytes); + ReturnValue_t handleAck(); + ReturnValue_t handleExe(); + ReturnValue_t startFlashReadOrWriteBase(std::string obcFile, std::string mpsocFile); + ReturnValue_t fileCheck(std::string obcFile); + void handleAckApidFailure(const ploc::SpTmReader& reader); + void handleExeFailure(); + ReturnValue_t handleTmReception(); + ReturnValue_t checkReceivedTm(); +}; + +#endif /* BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_ */