eive-obsw/linux/devices/ploc/PlocMPSoCHelper.cpp

354 lines
11 KiB
C++
Raw Normal View History

2022-01-06 18:05:21 +01:00
#include "PlocMPSoCHelper.h"
2022-03-16 09:01:36 +01:00
2022-01-06 18:05:21 +01:00
#include <filesystem>
2022-03-16 09:01:36 +01:00
#include <fstream>
2022-01-06 18:05:21 +01:00
2022-03-22 11:35:44 +01:00
#include "OBSWConfig.h"
#ifdef XIPHOS_Q7S
2022-09-16 11:53:33 +02:00
#include "bsp_q7s/fs/FilesystemHelper.h"
#endif
2022-03-16 09:01:36 +01:00
#include "mission/utility/Timestamp.h"
2022-01-06 18:05:21 +01:00
2022-08-15 18:34:26 +02:00
using namespace ploc;
PlocMPSoCHelper::PlocMPSoCHelper(object_id_t objectId) : SystemObject(objectId) {
spParams.buf = commandBuffer;
spParams.maxSize = sizeof(commandBuffer);
}
2022-01-06 18:05:21 +01:00
2022-03-16 09:01:36 +01:00
PlocMPSoCHelper::~PlocMPSoCHelper() {}
2022-01-06 18:05:21 +01:00
ReturnValue_t PlocMPSoCHelper::initialize() {
#ifdef XIPHOS_Q7S
2022-03-16 09:01:36 +01:00
sdcMan = SdCardManager::instance();
if (sdcMan == nullptr) {
sif::warning << "PlocMPSoCHelper::initialize: Invalid SD Card Manager" << std::endl;
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-03-16 09:01:36 +01:00
}
#endif
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-01-06 18:05:21 +01:00
}
ReturnValue_t PlocMPSoCHelper::performOperation(uint8_t operationCode) {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-03-16 09:01:36 +01:00
semaphore.acquire();
while (true) {
switch (internalState) {
case InternalState::IDLE: {
semaphore.acquire();
break;
}
case InternalState::FLASH_WRITE: {
result = performFlashWrite();
2022-08-24 17:27:47 +02:00
if (result == returnvalue::OK) {
2022-03-16 09:01:36 +01:00
triggerEvent(MPSOC_FLASH_WRITE_SUCCESSFUL);
} else {
triggerEvent(MPSOC_FLASH_WRITE_FAILED);
2022-01-06 18:05:21 +01:00
}
2022-03-16 09:01:36 +01:00
internalState = InternalState::IDLE;
break;
}
default:
sif::debug << "PlocMPSoCHelper::performOperation: Invalid state" << std::endl;
break;
2022-01-06 18:05:21 +01:00
}
2022-03-16 09:01:36 +01:00
}
2022-01-06 18:05:21 +01:00
}
ReturnValue_t PlocMPSoCHelper::setComIF(DeviceCommunicationIF* communicationInterface_) {
uartComIF = dynamic_cast<SerialComIF*>(communicationInterface_);
2022-03-16 09:01:36 +01:00
if (uartComIF == nullptr) {
sif::warning << "PlocMPSoCHelper::initialize: Invalid uart com if" << std::endl;
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-03-16 09:01:36 +01:00
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-01-06 18:05:21 +01:00
}
2022-03-16 09:01:36 +01:00
void PlocMPSoCHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; }
2022-01-06 18:05:21 +01:00
2022-01-11 12:56:02 +01:00
void PlocMPSoCHelper::setSequenceCount(SourceSequenceCounter* sequenceCount_) {
2022-03-16 09:01:36 +01:00
sequenceCount = sequenceCount_;
2022-01-06 18:05:21 +01:00
}
2022-03-22 11:35:44 +01:00
ReturnValue_t PlocMPSoCHelper::startFlashWrite(std::string obcFile, std::string mpsocFile) {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
#ifdef XIPHOS_Q7S
2022-03-26 20:47:25 +01:00
result = FilesystemHelper::checkPath(obcFile);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
return result;
}
2022-03-23 11:13:59 +01:00
result = FilesystemHelper::fileExists(mpsocFile);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
return result;
}
#endif
2022-03-22 11:35:44 +01:00
#ifdef TE0720_1CFA
if (not std::filesystem::exists(obcFile)) {
sif::warning << "PlocMPSoCHelper::startFlashWrite: File " << obcFile << "does not exist"
2022-03-26 20:47:25 +01:00
<< std::endl;
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-03-22 11:35:44 +01:00
}
#endif
flashWrite.obcFile = obcFile;
flashWrite.mpsocFile = mpsocFile;
2022-03-16 09:01:36 +01:00
internalState = InternalState::FLASH_WRITE;
2022-03-26 20:47:25 +01:00
result = resetHelper();
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-27 13:07:18 +02:00
return result;
2022-03-26 20:47:25 +01:00
}
return result;
}
ReturnValue_t PlocMPSoCHelper::resetHelper() {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-03-16 09:01:36 +01:00
semaphore.release();
2022-08-15 18:53:25 +02:00
spParams.buf = commandBuffer;
2022-03-16 09:01:36 +01:00
terminate = false;
2022-03-26 20:47:25 +01:00
result = uartComIF->flushUartRxBuffer(comCookie);
return result;
2022-03-16 09:01:36 +01:00
}
void PlocMPSoCHelper::stopProcess() { terminate = true; }
ReturnValue_t PlocMPSoCHelper::performFlashWrite() {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-03-16 12:36:05 +01:00
result = flashfopen();
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-26 20:47:25 +01:00
return result;
2022-03-16 12:36:05 +01:00
}
2022-03-16 09:01:36 +01:00
uint8_t tempData[mpsoc::MAX_DATA_SIZE];
2022-03-22 11:35:44 +01:00
std::ifstream file(flashWrite.obcFile, std::ifstream::binary);
2022-03-16 09:01:36 +01:00
// 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;
2022-03-26 20:47:25 +01:00
size_t bytesRead = 0;
2022-03-16 09:01:36 +01:00
while (remainingSize > 0) {
if (terminate) {
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-03-16 09:01:36 +01:00
}
if (remainingSize > mpsoc::MAX_DATA_SIZE) {
dataLength = mpsoc::MAX_DATA_SIZE;
} else {
dataLength = remainingSize;
}
2022-03-26 20:47:25 +01:00
if (file.is_open()) {
file.seekg(bytesRead, file.beg);
file.read(reinterpret_cast<char*>(tempData), dataLength);
bytesRead += dataLength;
remainingSize -= dataLength;
} else {
return FILE_CLOSED_ACCIDENTALLY;
}
2022-03-16 09:01:36 +01:00
(*sequenceCount)++;
2022-08-15 18:34:26 +02:00
mpsoc::TcFlashWrite tc(spParams, *sequenceCount);
result = tc.buildPacket(tempData, dataLength);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-08-15 18:34:26 +02:00
return result;
}
2022-03-26 20:47:25 +01:00
result = handlePacketTransmission(tc);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
return result;
}
}
2022-03-16 12:36:05 +01:00
result = flashfclose();
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-26 20:47:25 +01:00
return result;
2022-03-16 12:36:05 +01:00
}
2022-03-16 09:01:36 +01:00
return result;
2022-01-06 18:05:21 +01:00
}
2022-03-16 09:01:36 +01:00
ReturnValue_t PlocMPSoCHelper::flashfopen() {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-08-15 18:53:25 +02:00
spParams.buf = commandBuffer;
2022-03-16 09:01:36 +01:00
(*sequenceCount)++;
2022-08-15 18:34:26 +02:00
mpsoc::FlashFopen flashFopen(spParams, *sequenceCount);
2022-03-22 11:35:44 +01:00
result = flashFopen.createPacket(flashWrite.mpsocFile, mpsoc::FlashFopen::APPEND);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 12:36:05 +01:00
return result;
}
2022-03-26 20:47:25 +01:00
result = handlePacketTransmission(flashFopen);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-01-06 18:05:21 +01:00
return result;
2022-03-16 09:01:36 +01:00
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-01-06 18:05:21 +01:00
}
2022-03-16 12:36:05 +01:00
ReturnValue_t PlocMPSoCHelper::flashfclose() {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-08-15 18:53:25 +02:00
spParams.buf = commandBuffer;
2022-03-26 20:47:25 +01:00
(*sequenceCount)++;
2022-08-15 18:34:26 +02:00
mpsoc::FlashFclose flashFclose(spParams, *sequenceCount);
2022-03-26 20:47:25 +01:00
result = flashFclose.createPacket(flashWrite.mpsocFile);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-26 20:47:25 +01:00
return result;
}
result = handlePacketTransmission(flashFclose);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-26 20:47:25 +01:00
return result;
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-03-26 20:47:25 +01:00
}
2022-08-15 18:34:26 +02:00
ReturnValue_t PlocMPSoCHelper::handlePacketTransmission(ploc::SpTcBase& tc) {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-03-26 20:47:25 +01:00
result = sendCommand(tc);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-26 20:47:25 +01:00
return result;
}
result = handleAck();
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-26 20:47:25 +01:00
return result;
}
result = handleExe();
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-26 20:47:25 +01:00
return result;
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-03-16 12:36:05 +01:00
}
2022-03-16 09:01:36 +01:00
2022-08-15 18:34:26 +02:00
ReturnValue_t PlocMPSoCHelper::sendCommand(ploc::SpTcBase& tc) {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-08-15 18:34:26 +02:00
result = uartComIF->sendMessage(comCookie, tc.getFullPacket(), tc.getFullPacketLen());
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
sif::warning << "PlocMPSoCHelper::sendCommand: Failed to send command" << std::endl;
2022-04-10 18:46:39 +02:00
triggerEvent(MPSOC_SENDING_COMMAND_FAILED, result, static_cast<uint32_t>(internalState));
2022-01-06 18:05:21 +01:00
return result;
2022-03-16 09:01:36 +01:00
}
return result;
2022-01-06 18:05:21 +01:00
}
ReturnValue_t PlocMPSoCHelper::handleAck() {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-08-15 18:34:26 +02:00
result = handleTmReception(mpsoc::SIZE_ACK_REPORT);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
return result;
}
2022-08-15 18:34:26 +02:00
SpTmReader tmPacket(tmBuf.data(), tmBuf.size());
result = checkReceivedTm(tmPacket);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-08-15 18:34:26 +02:00
return result;
}
uint16_t apid = tmPacket.getApid();
2022-03-16 09:01:36 +01:00
if (apid != mpsoc::apid::ACK_SUCCESS) {
handleAckApidFailure(apid);
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-03-16 09:01:36 +01:00
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-01-06 18:05:21 +01:00
}
void PlocMPSoCHelper::handleAckApidFailure(uint16_t apid) {
2022-03-16 09:01:36 +01:00
if (apid == mpsoc::apid::ACK_FAILURE) {
2022-04-10 18:46:39 +02:00
triggerEvent(MPSOC_ACK_FAILURE_REPORT, static_cast<uint32_t>(internalState));
2022-03-16 09:01:36 +01:00
sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Received acknowledgement failure "
<< "report" << std::endl;
} else {
2022-04-10 18:46:39 +02:00
triggerEvent(MPSOC_ACK_INVALID_APID, apid, static_cast<uint32_t>(internalState));
2022-03-16 09:01:36 +01:00
sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Expected acknowledgement report "
<< "but received space packet with apid " << std::hex << apid << std::endl;
}
2022-01-06 18:05:21 +01:00
}
ReturnValue_t PlocMPSoCHelper::handleExe() {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-08-15 18:34:26 +02:00
result = handleTmReception(mpsoc::SIZE_EXE_REPORT);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-08-15 18:34:26 +02:00
return result;
}
ploc::SpTmReader tmPacket(tmBuf.data(), tmBuf.size());
result = checkReceivedTm(tmPacket);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
return result;
}
2022-08-15 18:34:26 +02:00
uint16_t apid = tmPacket.getApid();
2022-03-16 09:01:36 +01:00
if (apid != mpsoc::apid::EXE_SUCCESS) {
handleExeApidFailure(apid);
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-03-16 09:01:36 +01:00
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-01-06 18:05:21 +01:00
}
void PlocMPSoCHelper::handleExeApidFailure(uint16_t apid) {
2022-03-16 09:01:36 +01:00
if (apid == mpsoc::apid::EXE_FAILURE) {
2022-04-10 18:46:39 +02:00
triggerEvent(MPSOC_EXE_FAILURE_REPORT, static_cast<uint32_t>(internalState));
2022-03-16 09:01:36 +01:00
sif::warning << "PlocMPSoCHelper::handleExeApidFailure: Received execution failure "
<< "report" << std::endl;
} else {
2022-04-10 18:46:39 +02:00
triggerEvent(MPSOC_EXE_INVALID_APID, apid, static_cast<uint32_t>(internalState));
2022-03-26 20:47:25 +01:00
sif::warning << "PlocMPSoCHelper::handleExeApidFailure: Expected execution report "
2022-03-16 09:01:36 +01:00
<< "but received space packet with apid " << std::hex << apid << std::endl;
}
2022-01-06 18:05:21 +01:00
}
2022-08-15 18:34:26 +02:00
ReturnValue_t PlocMPSoCHelper::handleTmReception(size_t remainingBytes) {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-03-16 09:01:36 +01:00
size_t readBytes = 0;
2022-03-26 20:47:25 +01:00
size_t currentBytes = 0;
2022-03-16 09:01:36 +01:00
for (int retries = 0; retries < RETRIES; retries++) {
2022-08-15 18:34:26 +02:00
result = receive(tmBuf.data() + readBytes, &currentBytes, remainingBytes);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
return result;
}
2022-03-26 20:47:25 +01:00
readBytes += currentBytes;
remainingBytes = remainingBytes - currentBytes;
2022-03-16 09:01:36 +01:00
if (remainingBytes == 0) {
break;
}
}
if (remainingBytes != 0) {
sif::warning << "PlocMPSoCHelper::handleTmReception: Failed to receive reply" << std::endl;
2022-04-10 18:46:39 +02:00
triggerEvent(MPSOC_MISSING_EXE, remainingBytes, static_cast<uint32_t>(internalState));
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-03-16 09:01:36 +01:00
}
2022-08-15 18:34:26 +02:00
return result;
}
ReturnValue_t PlocMPSoCHelper::checkReceivedTm(SpTmReader& reader) {
ReturnValue_t result = reader.checkSize();
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-08-15 18:34:26 +02:00
sif::error << "PlocMPSoCHelper::handleTmReception: Size check on received TM failed"
<< std::endl;
triggerEvent(MPSOC_TM_SIZE_ERROR);
return result;
}
reader.checkCrc();
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
sif::warning << "PlocMPSoCHelper::handleTmReception: CRC check failed" << std::endl;
2022-08-15 18:34:26 +02:00
triggerEvent(MPSOC_TM_CRC_MISSMATCH, *sequenceCount);
2022-03-16 09:01:36 +01:00
return result;
}
2022-03-26 20:47:25 +01:00
(*sequenceCount)++;
2022-08-15 18:34:26 +02:00
uint16_t recvSeqCnt = reader.getSequenceCount();
2022-03-16 09:01:36 +01:00
if (recvSeqCnt != *sequenceCount) {
triggerEvent(MPSOC_HELPER_SEQ_CNT_MISMATCH, *sequenceCount, recvSeqCnt);
*sequenceCount = recvSeqCnt;
}
2022-08-24 17:27:47 +02:00
return returnvalue::OK;
2022-01-06 18:05:21 +01:00
}
ReturnValue_t PlocMPSoCHelper::receive(uint8_t* data, size_t* readBytes, size_t requestBytes) {
2022-08-24 17:27:47 +02:00
ReturnValue_t result = returnvalue::OK;
2022-03-26 20:47:25 +01:00
uint8_t* buffer = nullptr;
2022-03-16 09:01:36 +01:00
result = uartComIF->requestReceiveMessage(comCookie, requestBytes);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
sif::warning << "PlocMPSoCHelper::receive: Failed to request reply" << std::endl;
triggerEvent(MPSOC_HELPER_REQUESTING_REPLY_FAILED, result,
static_cast<uint32_t>(static_cast<uint32_t>(internalState)));
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-03-16 09:01:36 +01:00
}
2022-03-26 20:47:25 +01:00
result = uartComIF->readReceivedMessage(comCookie, &buffer, readBytes);
2022-08-24 17:27:47 +02:00
if (result != returnvalue::OK) {
2022-03-16 09:01:36 +01:00
sif::warning << "PlocMPSoCHelper::receive: Failed to read received message" << std::endl;
triggerEvent(MPSOC_HELPER_READING_REPLY_FAILED, result, static_cast<uint32_t>(internalState));
2022-08-24 17:27:47 +02:00
return returnvalue::FAILED;
2022-03-16 09:01:36 +01:00
}
2022-03-26 20:47:25 +01:00
if (*readBytes > 0) {
std::memcpy(data, buffer, *readBytes);
}
2022-03-16 09:01:36 +01:00
return result;
2022-01-06 18:05:21 +01:00
}