From 36d33711a7fe34fa32d9f1c0b32eeeff28e9a5c4 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Tue, 21 Dec 2021 15:46:09 +0100 Subject: [PATCH] flash write command --- bsp_q7s/core/ObjectFactory.cpp | 2 +- bsp_q7s/devices/startracker/CMakeLists.txt | 2 +- .../startracker/StarTrackerDefinitions.h | 2 +- .../startracker/StarTrackerHandler.cpp | 88 +++++++-- .../devices/startracker/StarTrackerHandler.h | 28 ++- .../{StrImageLoader.cpp => StrHelper.cpp} | 186 ++++++++++++++---- .../{StrImageLoader.h => StrHelper.h} | 121 +++++++++--- common/config/commonClassIds.h | 2 +- common/config/commonSubsystemIds.h | 2 +- tmtc | 2 +- 10 files changed, 339 insertions(+), 96 deletions(-) rename bsp_q7s/devices/startracker/{StrImageLoader.cpp => StrHelper.cpp} (57%) rename bsp_q7s/devices/startracker/{StrImageLoader.h => StrHelper.h} (57%) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 168f6de8..92600caf 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -1,6 +1,7 @@ #include #include "ObjectFactory.h" +#include "../devices/startracker/StrHelper.h" #include "bsp_q7s/devices/startracker/StarTrackerDefinitions.h" #include "OBSWConfig.h" #include "devConf.h" @@ -18,7 +19,6 @@ #include "bsp_q7s/devices/PlocSupervisorHandler.h" #include "bsp_q7s/devices/PlocUpdater.h" #include "bsp_q7s/devices/PlocMemoryDumper.h" -#include "bsp_q7s/devices/startracker/StrImageLoader.h" #include "bsp_q7s/devices/startracker/StarTrackerHandler.h" #include "bsp_q7s/callbacks/rwSpiCallback.h" #include "bsp_q7s/callbacks/gnssCallback.h" diff --git a/bsp_q7s/devices/startracker/CMakeLists.txt b/bsp_q7s/devices/startracker/CMakeLists.txt index 81f0492f..28704219 100644 --- a/bsp_q7s/devices/startracker/CMakeLists.txt +++ b/bsp_q7s/devices/startracker/CMakeLists.txt @@ -3,5 +3,5 @@ target_sources(${TARGET_NAME} PRIVATE StarTrackerJsonCommands.cpp ArcsecDatalinkLayer.cpp ArcsecJsonParamBase.cpp - StrImageLoader.cpp + StrHelper.cpp ) \ No newline at end of file diff --git a/bsp_q7s/devices/startracker/StarTrackerDefinitions.h b/bsp_q7s/devices/startracker/StarTrackerDefinitions.h index 425c69d0..22214cb0 100644 --- a/bsp_q7s/devices/startracker/StarTrackerDefinitions.h +++ b/bsp_q7s/devices/startracker/StarTrackerDefinitions.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "objects/systemObjectList.h" #include @@ -844,7 +845,6 @@ public: sif::info << "ContrastSet::printSet: BinD8: " << this->binD8 << std::endl; } }; - } #endif /* MISSION_STARTRACKER_DEFINITIONS_H_ */ diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp index 087d2bfa..6e0d54e0 100644 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.cpp +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.cpp @@ -14,14 +14,14 @@ extern "C" { } StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, - CookieIF * comCookie, StrImageLoader* strImageLoader) : + CookieIF * comCookie, StrHelper* strHelper) : DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this), versionSet(this), powerSet( this), interfaceSet(this), timeSet(this), solutionSet(this), histogramSet(this), - contrastSet(this), strImageLoader(strImageLoader) { + contrastSet(this), strHelper(strHelper) { if (comCookie == nullptr) { sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; } - if (strImageLoader == nullptr) { + if (strHelper == nullptr) { sif::error << "StarTrackerHandler: Invalid str image loader" << std::endl; } eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5); @@ -50,21 +50,21 @@ ReturnValue_t StarTrackerHandler::initialize() { return result; } result = manager->subscribeToEventRange(eventQueue->getId(), - event::getEventId(StrImageLoader::IMAGE_UPLOAD_FAILED), - event::getEventId(StrImageLoader::IMAGE_DOWNLOAD_SUCCESSFUL)); + event::getEventId(StrHelper::IMAGE_UPLOAD_FAILED), + event::getEventId(StrHelper::FLASH_READ_FAILED)); if (result != RETURN_OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "StarTrackerHandler::initialize: Failed to subscribe to events form image" - " loader" << std::endl; + sif::warning << "StarTrackerHandler::initialize: Failed to subscribe to events from " + " str helper" << std::endl; #endif return ObjectManagerIF::CHILD_INIT_FAILED; } - result = strImageLoader->setComIF(communicationInterface); + result = strHelper->setComIF(communicationInterface); if (result != RETURN_OK) { return ObjectManagerIF::CHILD_INIT_FAILED; } - strImageLoader->setComCookie(comCookie); + strHelper->setComCookie(comCookie); return RETURN_OK; } @@ -75,7 +75,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu switch(actionId) { case(StarTracker::STOP_IMAGE_LOADER): { - strImageLoader->stopProcess(); + strHelper->stopProcess(); return EXECUTION_FINISHED; } case(StarTracker::SET_JSON_FILE_NAME): { @@ -89,7 +89,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu break; } - if (imageLoaderExecuting == true) { + if (strHelperExecuting == true) { return IMAGE_LOADER_EXECUTING; } @@ -108,12 +108,12 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu if (size > MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; } - result = strImageLoader->startImageUpload( + result = strHelper->startImageUpload( std::string(reinterpret_cast(data), size)); if (result != RETURN_OK) { return result; } - imageLoaderExecuting = true; + strHelperExecuting = true; return EXECUTION_FINISHED; } case(StarTracker::DOWNLOAD_IMAGE): { @@ -124,19 +124,32 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu if (size > MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; } - result = strImageLoader->startImageDownload( + result = strHelper->startImageDownload( std::string(reinterpret_cast(data), size)); if (result != RETURN_OK) { return result; } - imageLoaderExecuting = true; + strHelperExecuting = true; + return EXECUTION_FINISHED; + } + case(StarTracker::WRITE): { + result = DeviceHandlerBase::acceptExternalDeviceCommands(); + if (result != RETURN_OK) { + return result; + } + result = executeWriteCommand(data, size); + if (result != RETURN_OK) { + return result; + } + + strHelperExecuting = true; return EXECUTION_FINISHED; } case(StarTracker::CHANGE_DOWNLOAD_FILE): { if (size > MAX_FILE_NAME) { return FILENAME_TOO_LONG; } - strImageLoader->setDownloadImageName( + strHelper->setDownloadImageName( std::string(reinterpret_cast(data), size)); return EXECUTION_FINISHED; } @@ -182,7 +195,7 @@ void StarTrackerHandler::doStartUp() { void StarTrackerHandler::doShutDown() { // If star tracker is shutdown also stop all running processes in the image loader task - strImageLoader->stopProcess(); + strHelper->stopProcess(); setMode(_MODE_POWER_DOWN); } @@ -751,7 +764,7 @@ size_t StarTrackerHandler::getNextReplyLength(DeviceCommandId_t commandId){ ReturnValue_t StarTrackerHandler::doSendReadHook() { // Prevent DHB from polling UART during commands executed by the image loader task - if(imageLoaderExecuting) { + if(strHelperExecuting) { return RETURN_FAILED; } return RETURN_OK; @@ -776,6 +789,10 @@ ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId) *foundId = StarTracker::PING_REQUEST; break; } + case (StarTracker::ID::WRITE): { + *foundId = StarTracker::WRITE; + break; + } case (StarTracker::ID::BOOT): { *foundId = StarTracker::BOOT; break; @@ -906,7 +923,7 @@ void StarTrackerHandler::handleEvent(EventMessage* eventMessage) { case objects::STR_IMG_LOADER: { // All events from image loader signal either that the operation was successful or that it // failed - imageLoaderExecuting = false; + strHelperExecuting = false; break; } default: @@ -916,6 +933,39 @@ void StarTrackerHandler::handleEvent(EventMessage* eventMessage) { } } +ReturnValue_t StarTrackerHandler::executeWriteCommand(const uint8_t* commandData, + size_t commandDataLen) { + ReturnValue_t result = RETURN_OK; + if (commandDataLen < WriteCmd::MIN_LENGTH) { + sif::warning << "StarTrackerHandler::executeWriteCommand: Command too short" << std::endl; + return COMMAND_TOO_SHORT; + } + uint8_t region = *(commandData); + uint32_t address; + size_t size = sizeof(address); + const uint8_t* addressPtr = commandData + WriteCmd::ADDRESS_OFFSET; + result = SerializeAdapter::deSerialize(&address, addressPtr, &size, + SerializeIF::Endianness::LITTLE); + if (result != RETURN_OK) { + sif::debug << "StarTrackerHandler::executeWriteCommand: Deserialization of address failed" + << std::endl; + return result; + } + if (commandDataLen - sizeof(address) - sizeof(region) > MAX_PATH_SIZE) { + sif::warning << "StarTrackerHandler::executeWriteCommand: Received command with invalid" + << " path and filename" << std::endl; + return FILE_PATH_TOO_LONG; + } + const uint8_t* filePtr = commandData + WriteCmd::FILE_OFFSET; + std::string fullname = std::string(reinterpret_cast(filePtr), + commandDataLen - sizeof(address) - sizeof(region)); + result = strHelper->startFlashWrite(fullname, region, address); + if (result != RETURN_OK) { + return result; + } + return result; +} + void StarTrackerHandler::prepareBootCommand() { uint32_t length = 0; struct BootActionRequest bootRequest = {BOOT_REGION_ID}; diff --git a/bsp_q7s/devices/startracker/StarTrackerHandler.h b/bsp_q7s/devices/startracker/StarTrackerHandler.h index e534f590..8761f1ce 100644 --- a/bsp_q7s/devices/startracker/StarTrackerHandler.h +++ b/bsp_q7s/devices/startracker/StarTrackerHandler.h @@ -6,10 +6,10 @@ #include "fsfw/timemanager/Countdown.h" #include "thirdparty/arcsec_star_tracker/common/SLIP.h" #include -#include "StrImageLoader.h" #include "ArcsecDataLinkLayer.h" #include "StarTrackerDefinitions.h" #include "ArcsecJsonParamBase.h" +#include "StrHelper.h" /** * @brief This is the device handler for the star tracker from arcsec. @@ -33,7 +33,7 @@ public: * to high to enable the device. */ StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie, - StrImageLoader* strImageLoader); + StrHelper* strHelper); virtual ~StarTrackerHandler(); ReturnValue_t initialize() override; @@ -115,6 +115,8 @@ private: static const ReturnValue_t TM_REPLY_ERROR = MAKE_RETURN_CODE(0xAE); //! [EXPORT] : [COMMENT] Status field of contrast reply signals error static const ReturnValue_t CONTRAST_REQ_FAILED = MAKE_RETURN_CODE(0xAE); + //! [EXPORT] : [COMMENT] Received command which is too short (some data is missing for proper execution) + static const ReturnValue_t COMMAND_TOO_SHORT = MAKE_RETURN_CODE(0xAF); static const size_t MAX_PATH_SIZE = 50; static const size_t MAX_FILE_NAME = 30; @@ -137,6 +139,14 @@ private: static const uint32_t MUTEX_TIMEOUT = 20; static const uint32_t BOOT_TIMEOUT = 1000; + class WriteCmd { + public: + static const uint8_t ADDRESS_OFFSET = 1; + static const uint8_t FILE_OFFSET = 5; + // Minimum length of a write command (region, address and filename) + static const size_t MIN_LENGTH = 7; + }; + MessageQueueIF* eventQueue = nullptr; ArcsecDatalinkLayer dataLinkLayer; @@ -151,7 +161,7 @@ private: StarTracker::ContrastSet contrastSet; // Pointer to object responsible for uploading and downloading images to/from the star tracker - StrImageLoader* strImageLoader = nullptr; + StrHelper* strHelper = nullptr; uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; @@ -187,7 +197,7 @@ private: StartupState startupState = StartupState::IDLE; - bool imageLoaderExecuting = false; + bool strHelperExecuting = false; /** * @brief Handles internal state @@ -225,6 +235,16 @@ private: */ void handleEvent(EventMessage* eventMessage); + /** + * @brief Executes the write command + * + * @param commandData Pointer to received command data + * @param commandDataLen Size of received command data + * + * @return RETURN_OK if start of execution was successful, otherwise error return value + */ + ReturnValue_t executeWriteCommand(const uint8_t* commandData, size_t commandDataLen); + /** * @brief Fills command buffer with data to boot image (works only when star tracker is * in bootloader mode). diff --git a/bsp_q7s/devices/startracker/StrImageLoader.cpp b/bsp_q7s/devices/startracker/StrHelper.cpp similarity index 57% rename from bsp_q7s/devices/startracker/StrImageLoader.cpp rename to bsp_q7s/devices/startracker/StrHelper.cpp index 495ec3a8..a3d28305 100644 --- a/bsp_q7s/devices/startracker/StrImageLoader.cpp +++ b/bsp_q7s/devices/startracker/StrHelper.cpp @@ -1,26 +1,27 @@ -#include "StrImageLoader.h" +#include "StrHelper.h" + #include "mission/utility/Timestamp.h" #include #include -StrImageLoader::StrImageLoader(object_id_t objectId) : SystemObject(objectId){ +StrHelper::StrHelper(object_id_t objectId) : SystemObject(objectId){ } -StrImageLoader::~StrImageLoader() { +StrHelper::~StrHelper() { } -ReturnValue_t StrImageLoader::initialize() { +ReturnValue_t StrHelper::initialize() { sdcMan = SdCardManager::instance(); if (sdcMan == nullptr) { - sif::warning << "StrImageLoader::initialize: Invalid SD Card Manager" << std::endl; + sif::warning << "StrHelper::initialize: Invalid SD Card Manager" << std::endl; return RETURN_FAILED; } return RETURN_OK; } -ReturnValue_t StrImageLoader::performOperation(uint8_t operationCode) { +ReturnValue_t StrHelper::performOperation(uint8_t operationCode) { ReturnValue_t result = RETURN_OK; semaphore.acquire(); while(true) { @@ -40,7 +41,7 @@ ReturnValue_t StrImageLoader::performOperation(uint8_t operationCode) { internalState = InternalState::IDLE; break; } - case InternalState::DOWNLOAD_IMAGE: + case InternalState::DOWNLOAD_IMAGE: { result = performImageDownload(); if (result == RETURN_OK){ triggerEvent(IMAGE_DOWNLOAD_SUCCESSFUL); @@ -51,23 +52,38 @@ ReturnValue_t StrImageLoader::performOperation(uint8_t operationCode) { internalState = InternalState::IDLE; break; } + case InternalState::FLASH_WRITE: { + result = performFlashWrite(); + if (result == RETURN_OK){ + triggerEvent(FLASH_WRITE_SUCCESSFUL); + } + else { + triggerEvent(FLASH_WRITE_FAILED); + } + internalState = InternalState::IDLE; + break; + } + default: + sif::debug << "StrHelper::performOperation: Invalid state" << std::endl; + break; + } } } -ReturnValue_t StrImageLoader::setComIF(DeviceCommunicationIF* communicationInterface_) { +ReturnValue_t StrHelper::setComIF(DeviceCommunicationIF* communicationInterface_) { uartComIF = dynamic_cast(communicationInterface_); if (uartComIF == nullptr) { - sif::warning << "StrImageLoader::initialize: Invalid uart com if" << std::endl; + sif::warning << "StrHelper::initialize: Invalid uart com if" << std::endl; return RETURN_FAILED; } return RETURN_OK; } -void StrImageLoader::setComCookie(CookieIF* comCookie_) { +void StrHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; } -ReturnValue_t StrImageLoader::startImageUpload(std::string uploadImage_) { +ReturnValue_t StrHelper::startImageUpload(std::string uploadImage_) { ReturnValue_t result = checkPath(uploadImage_); if (result != RETURN_OK) { return result; @@ -82,7 +98,7 @@ ReturnValue_t StrImageLoader::startImageUpload(std::string uploadImage_) { return RETURN_OK; } -ReturnValue_t StrImageLoader::startImageDownload(std::string downloadPath_) { +ReturnValue_t StrHelper::startImageDownload(std::string downloadPath_) { ReturnValue_t result = checkPath(downloadPath_); if (result != RETURN_OK) { return result; @@ -97,15 +113,31 @@ ReturnValue_t StrImageLoader::startImageDownload(std::string downloadPath_) { return RETURN_OK; } -void StrImageLoader::stopProcess() { +void StrHelper::stopProcess() { terminate = true; } -void StrImageLoader::setDownloadImageName(std::string image) { +void StrHelper::setDownloadImageName(std::string image) { downloadImage = image; } -ReturnValue_t StrImageLoader::performImageDownload() { +ReturnValue_t StrHelper::startFlashWrite(std::string flashWriteFile_, uint8_t region, + uint32_t flashWriteAddress) { + ReturnValue_t result = checkPath(flashWriteFile_); + if (result != RETURN_OK) { + return result; + } + flashWriteFile = flashWriteFile_; + if(not std::filesystem::exists(flashWriteFile)) { + return FILE_NOT_EXISTS; + } + internalState = InternalState::FLASH_WRITE; + semaphore.release(); + terminate = false; + return RETURN_OK; +} + +ReturnValue_t StrHelper::performImageDownload() { ReturnValue_t result; struct DownloadActionRequest downloadReq; uint32_t size = 0; @@ -161,7 +193,7 @@ ReturnValue_t StrImageLoader::performImageDownload() { return RETURN_OK; } -ReturnValue_t StrImageLoader::performImageUpload() { +ReturnValue_t StrHelper::performImageUpload() { ReturnValue_t result = RETURN_OK; uint32_t size = 0; uint32_t imageSize = 0; @@ -169,7 +201,7 @@ ReturnValue_t StrImageLoader::performImageUpload() { uploadReq.position = 0; std::memset(&uploadReq.data, 0, sizeof(uploadReq.data)); if (not std::filesystem::exists(uploadImage)) { - triggerEvent(IMAGE_FILE_NOT_EXISTS, uploadReq.position); + triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast(internalState)); internalState = InternalState::IDLE; return RETURN_FAILED; } @@ -213,7 +245,57 @@ ReturnValue_t StrImageLoader::performImageUpload() { return RETURN_OK; } -ReturnValue_t StrImageLoader::sendAndRead(size_t size, uint32_t position) { +ReturnValue_t StrHelper::performFlashWrite() { + ReturnValue_t result = RETURN_OK; + uint32_t size = 0; + uint32_t remainingBytes = 0; + uint32_t fileSize = 0; + struct WriteActionRequest req; + if (not std::filesystem::exists(flashWriteFile)) { + triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast(internalState)); + internalState = InternalState::IDLE; + return RETURN_FAILED; + } + std::ifstream file(flashWriteFile, std::ifstream::binary); + file.seekg(0, file.end); + fileSize = file.tellg(); + remainingBytes = fileSize; + req.region = flashWriteRegion; + req.address = flashWriteAddress; + req.length = MAX_FLASH_DATA; + while(remainingBytes >= MAX_FLASH_DATA) { + if (terminate) { + return RETURN_OK; + } + file.seekg(fileSize - remainingBytes, file.beg); + file.read(reinterpret_cast(req.data), MAX_FLASH_DATA); + arc_pack_write_action_req(&req, commandBuffer, &size); + result = sendAndRead(size, req.address); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + result = checkFlashWriteReply(req); + if (result != RETURN_OK) { + return result; + } + remainingBytes = remainingBytes - MAX_FLASH_DATA; + } + file.seekg(fileSize - remainingBytes, file.beg); + file.read(reinterpret_cast(req.data), remainingBytes); + file.close(); + arc_pack_write_action_req(&req, commandBuffer, &size); + result = sendAndRead(size, req.address); + if (result != RETURN_OK) { + return RETURN_FAILED; + } + result = checkFlashWriteReply(req); + if (result != RETURN_OK) { + return result; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::sendAndRead(size_t size, uint32_t parameter) { ReturnValue_t result = RETURN_OK; ReturnValue_t decResult = RETURN_OK; size_t receivedDataLen = 0; @@ -224,8 +306,8 @@ ReturnValue_t StrImageLoader::sendAndRead(size_t size, uint32_t position) { result = uartComIF->sendMessage(comCookie, datalinkLayer.getEncodedFrame(), datalinkLayer.getEncodedLength()); if (result != RETURN_OK) { - sif::warning << "StrImageLoader::sendAndRead: Failed to send packet" << std::endl; - triggerEvent(IMG_LOADER_SENDING_PACKET_FAILED, result, position); + sif::warning << "StrHelper::sendAndRead: Failed to send packet" << std::endl; + triggerEvent(STR_HELPER_SENDING_PACKET_FAILED, result, parameter); return RETURN_FAILED; } decResult = ArcsecDatalinkLayer::DEC_IN_PROGRESS; @@ -233,14 +315,14 @@ ReturnValue_t StrImageLoader::sendAndRead(size_t size, uint32_t position) { result = uartComIF->requestReceiveMessage(comCookie, StarTracker::MAX_FRAME_SIZE * 2 + 2); if (result != RETURN_OK) { - sif::warning << "StrImageLoader::sendAndRead: Failed to request reply" << std::endl; - triggerEvent(IMG_LOADER_REQUESTING_MSG_FAILED, result, position); + sif::warning << "StrHelper::sendAndRead: Failed to request reply" << std::endl; + triggerEvent(STR_HELPER_REQUESTING_MSG_FAILED, result, parameter); return RETURN_FAILED; } result = uartComIF->readReceivedMessage(comCookie, &receivedData, &receivedDataLen); if (result != RETURN_OK) { - sif::warning << "StrImageLoader::sendAndRead: Failed to read received message" << std::endl; - triggerEvent(IMG_LOADER_READING_REPLY_FAILED, result, position); + sif::warning << "StrHelper::sendAndRead: Failed to read received message" << std::endl; + triggerEvent(STR_HELPER_READING_REPLY_FAILED, result, parameter); return RETURN_FAILED; } if (receivedDataLen == 0 && missedReplies < MAX_POLLS) { @@ -248,7 +330,7 @@ ReturnValue_t StrImageLoader::sendAndRead(size_t size, uint32_t position) { continue; } else if ((receivedDataLen == 0) && (missedReplies >= MAX_POLLS)) { - triggerEvent(IMG_LOADER_NO_REPLY, position); + triggerEvent(STR_HELPER_NO_REPLY, parameter); return RETURN_FAILED; } else { @@ -257,22 +339,22 @@ ReturnValue_t StrImageLoader::sendAndRead(size_t size, uint32_t position) { decResult = datalinkLayer.decodeFrame(receivedData, receivedDataLen, &bytesLeft); if (bytesLeft != 0) { // This should never happen - sif::warning << "StrImageLoader::sendAndRead: Bytes left after decoding" << std::endl; - triggerEvent(IMG_LOADER_COM_ERROR, result, position); + sif::warning << "StrHelper::sendAndRead: Bytes left after decoding" << std::endl; + triggerEvent(STR_HELPER_COM_ERROR, result, parameter); return RETURN_FAILED; } } if (decResult != RETURN_OK) { - triggerEvent(IMG_LOADER_DEC_ERROR, decResult, position); + triggerEvent(STR_HELPER_DEC_ERROR, decResult, parameter); return RETURN_FAILED; } return RETURN_OK; } -ReturnValue_t StrImageLoader::checkReply() { +ReturnValue_t StrHelper::checkReply() { uint8_t type = datalinkLayer.getReplyFrameType(); if (type != TMTC_ACTIONREPLY) { - sif::warning << "StrImageLoader::checkReply: Received reply with invalid type ID" + sif::warning << "StrHelper::checkReply: Received reply with invalid type ID" << std::endl; triggerEvent(INVALID_TYPE_ID); return RETURN_FAILED; @@ -280,13 +362,13 @@ ReturnValue_t StrImageLoader::checkReply() { uint8_t status = datalinkLayer.getStatusField(); if (status != ArcsecDatalinkLayer::STATUS_OK) { triggerEvent(STATUS_ERROR); - sif::warning << "StrImageLoader::checkReply: Status failure" << std::endl; + sif::warning << "StrHelper::checkReply: Status failure" << std::endl; return RETURN_FAILED; } return RETURN_OK; } -ReturnValue_t StrImageLoader::checkReplyPosition(uint32_t expectedPosition) { +ReturnValue_t StrHelper::checkReplyPosition(uint32_t expectedPosition) { uint32_t receivedPosition = 0; std::memcpy(&receivedPosition, datalinkLayer.getReply() + POS_OFFSET, sizeof(receivedPosition)); if (receivedPosition != expectedPosition) { @@ -296,17 +378,51 @@ ReturnValue_t StrImageLoader::checkReplyPosition(uint32_t expectedPosition) { return RETURN_OK; } -ReturnValue_t StrImageLoader::checkPath(std::string name) { +ReturnValue_t StrHelper::checkFlashWriteReply(struct WriteActionRequest& req) { + ReturnValue_t result = RETURN_OK; + const uint8_t* data = datalinkLayer.getReply(); + uint8_t region = *(data + REGION_OFFSET); + uint32_t address; + const uint8_t* addressData = data + ADDRESS_OFFSET; + size_t size = sizeof(address); + result = SerializeAdapter::deSerialize(&address, &addressData, &size, + SerializeIF::Endianness::LITTLE); + if (result != RETURN_OK) { + sif::warning << "StrHelper::checkFlashWriteReply: Deserialization of address failed" + << std::endl; + } + uint16_t length; + size = sizeof(length); + const uint8_t* lengthData = data + LENGTH_OFFSET; + result = SerializeAdapter::deSerialize(&length, lengthData, &size, + SerializeIF::Endianness::LITTLE); + if (result != RETURN_OK) { + sif::warning << "StrHelper::checkFlashWriteReply: Deserialization of length failed" + << std::endl; + } + if (region != req.region) { + return REGION_MISMATCH; + } + if (address != req.address) { + return ADDRESS_MISMATCH; + } + if (region != req.length) { + return LENGTH_MISMATCH; + } + return RETURN_OK; +} + +ReturnValue_t StrHelper::checkPath(std::string name) { if (name.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { - sif::warning << "StrImageLoader::checkPath: SD card 0 not mounted" << std::endl; + sif::warning << "StrHelper::checkPath: SD card 0 not mounted" << std::endl; return SD_NOT_MOUNTED; } } else if (name.substr(0, sizeof(SdCardManager::SD_1_MOUNT_POINT)) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { if (!sdcMan->isSdCardMounted(sd::SLOT_0)) { - sif::warning << "StrImageLoader::checkPath: SD card 1 not mounted" << std::endl; + sif::warning << "StrHelper::checkPath: SD card 1 not mounted" << std::endl; return SD_NOT_MOUNTED; } } diff --git a/bsp_q7s/devices/startracker/StrImageLoader.h b/bsp_q7s/devices/startracker/StrHelper.h similarity index 57% rename from bsp_q7s/devices/startracker/StrImageLoader.h rename to bsp_q7s/devices/startracker/StrHelper.h index 50fe3e92..f7a994b4 100644 --- a/bsp_q7s/devices/startracker/StrImageLoader.h +++ b/bsp_q7s/devices/startracker/StrHelper.h @@ -1,5 +1,5 @@ -#ifndef BSP_Q7S_DEVICES_STRIMAGELOADER_H_ -#define BSP_Q7S_DEVICES_STRIMAGELOADER_H_ +#ifndef BSP_Q7S_DEVICES_STRHELPER_H_ +#define BSP_Q7S_DEVICES_STRHELPER_H_ #include #include "ArcsecDatalinkLayer.h" @@ -17,15 +17,12 @@ extern "C" { } /** - * @brief An object of this class runs in a separate task and is responsible for uploading and - * downloading images to/from the star tracker. This is required because uploading and - * downloading via the star tracker handler takes a lot of time because each upload or - * download packet can transport a maximum of 1024 bytes. + * @brief Helper class for the star tracker handler to accelerate large data transfers. */ -class StrImageLoader: public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { +class StrHelper: public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { public: - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_IMAGE_LOADER; + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HELPER; //! [EXPORT] : [COMMENT] Image upload failed static const Event IMAGE_UPLOAD_FAILED = MAKE_EVENT(0, severity::LOW); @@ -35,41 +32,50 @@ public: static const Event IMAGE_UPLOAD_SUCCESSFUL = MAKE_EVENT(2, severity::LOW); //! [EXPORT] : [COMMENT] Image download was successful static const Event IMAGE_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(3, severity::LOW); + //! [EXPORT] : [COMMENT] Finished flash write procedure successfully + static const Event FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(4, severity::LOW); + //! [EXPORT] : [COMMENT] Finished flash read procedure successfully + static const Event FLASH_READ_SUCCESSFUL = MAKE_EVENT(5, severity::LOW); + //! [EXPORT] : [COMMENT] Flash write procedure failed + static const Event FLASH_WRITE_FAILED = MAKE_EVENT(6, severity::LOW); + //! [EXPORT] : [COMMENT] Flash read procedure failed + static const Event FLASH_READ_FAILED = MAKE_EVENT(7, severity::LOW); //! [EXPORT] : [COMMENT] Failed to read communication interface reply data //!P1: Return code of failed communication interface read call //!P1: Upload/download position for which the read call failed - static const Event IMG_LOADER_READING_REPLY_FAILED = MAKE_EVENT(4, severity::LOW); + static const Event STR_HELPER_READING_REPLY_FAILED = MAKE_EVENT(8, severity::LOW); //! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence //!P1: Return code of failed communication interface read call //!P1: Upload/download position for which the read call failed - static const Event IMG_LOADER_COM_ERROR = MAKE_EVENT(5, severity::LOW); + static const Event STR_HELPER_COM_ERROR = MAKE_EVENT(9, severity::LOW); //! [EXPORT] : [COMMENT] Star tracker did not send replies (maybe device is powered off) //!P1: Position of upload or download packet for which no reply was sent - static const Event IMG_LOADER_NO_REPLY = MAKE_EVENT(6, severity::LOW); + static const Event STR_HELPER_NO_REPLY = MAKE_EVENT(10, severity::LOW); //! [EXPORT] : [COMMENT] Received reply with invalid type ID - static const Event INVALID_TYPE_ID = MAKE_EVENT(7, severity::LOW); + static const Event INVALID_TYPE_ID = MAKE_EVENT(11, severity::LOW); //! [EXPORT] : [COMMENT] Status field in reply signals error - static const Event STATUS_ERROR = MAKE_EVENT(8, severity::LOW); + static const Event STATUS_ERROR = MAKE_EVENT(12, severity::LOW); //! [EXPORT] : [COMMENT] Error during decoding of received reply occurred //P1: Return value of decoding function - //P2: Position of upload/download packet for which reply decoding failed - static const Event IMG_LOADER_DEC_ERROR = MAKE_EVENT(9, severity::LOW); + //P2: Position of upload/download packet, or address of flash write/read request + static const Event STR_HELPER_DEC_ERROR = MAKE_EVENT(13, severity::LOW); //! [EXPORT] : [COMMENT] Position mismatch //! P1: The expected position and thus the position for which the image upload/download failed - static const Event POSITION_MISMATCH = MAKE_EVENT(10, severity::LOW); - //! [EXPORT] : [COMMENT] Try to upload image but specified image does not exist - static const Event IMAGE_FILE_NOT_EXISTS = MAKE_EVENT(11, severity::LOW); - //! [EXPORT] : [COMMENT] Sending packet (download or upload) to star tracker failed + static const Event POSITION_MISMATCH = MAKE_EVENT(14, severity::LOW); + //! [EXPORT] : [COMMENT] Specified file does not exist + //!P1: Internal state of str helper + static const Event STR_HELPER_FILE_NOT_EXISTS = MAKE_EVENT(15, severity::LOW); + //! [EXPORT] : [COMMENT] Sending packet to star tracker failed //!P1: Return code of communication interface sendMessage function - //!P2: Position of upload/download packet for which the transmission failed - static const Event IMG_LOADER_SENDING_PACKET_FAILED = MAKE_EVENT(12, severity::LOW); + //!P2: Position of upload/download packet, or address of flash write/read request for which sending failed + static const Event STR_HELPER_SENDING_PACKET_FAILED = MAKE_EVENT(16, severity::LOW); //! [EXPORT] : [COMMENT] Communication interface requesting reply failed //!P1: Return code of failed request - //!P1: Upload/download position for which the request failed - static const Event IMG_LOADER_REQUESTING_MSG_FAILED = MAKE_EVENT(13, severity::LOW); + //!P1: Upload/download position, or address of flash write/read request for which transmission failed + static const Event STR_HELPER_REQUESTING_MSG_FAILED = MAKE_EVENT(17, severity::LOW); - StrImageLoader(object_id_t objectId); - virtual ~StrImageLoader(); + StrHelper(object_id_t objectId); + virtual ~StrHelper(); ReturnValue_t initialize() override; ReturnValue_t performOperation(uint8_t operationCode = 0) override; @@ -93,7 +99,17 @@ public: ReturnValue_t startImageDownload(std::string downloadPath_); /** - * @brief Can be used to interrupt a running upload or download process. + * @brief Starts the flash write procedure + * + * @param flashWriteFile_ Full name including absolute path of file to write to flash + * @param region Region ID of flash region to write to + * @param flashWriteAddress Start address of flash write procedure + */ + ReturnValue_t startFlashWrite(std::string flashWriteFile_, uint8_t region, + uint32_t flashWriteAddress); + + /** + * @brief Can be used to interrupt a running data transfer. */ void stopProcess(); @@ -104,7 +120,7 @@ public: private: - static const uint8_t INTERFACE_ID = CLASS_ID::STR_IMG_LOADER; + static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER; //! [EXPORT] : [COMMENT] SD card specified in path string not mounted static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA0); @@ -112,8 +128,14 @@ private: static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1); //! [EXPORT] : [COMMENT] Specified path does not exist static const ReturnValue_t PATH_NOT_EXISTS = MAKE_RETURN_CODE(0xA2); - //! [EXPORT] : [COMMENT] Failed to create download file + //! [EXPORT] : [COMMENT] Failed to create download image or read flash file static const ReturnValue_t FILE_CREATION_FAILED = MAKE_RETURN_CODE(0xA3); + //! [EXPORT] : [COMMENT] Region in flash write/read reply does not match expected region + static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xA4); + //! [EXPORT] : [COMMENT] Address in flash write/read reply does not match expected address + static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xA5); + //! [EXPORT] : [COMMENT] Length in flash write/read reply does not match expected length + static const ReturnValue_t LENGTH_MISMATCH = MAKE_RETURN_CODE(0xA6); // Size of one image part which can be sent per action request static const size_t SIZE_IMAGE_PART = 1024; @@ -124,13 +146,19 @@ private: static const uint8_t POS_OFFSET = 2; static const uint8_t DATA_OFFSET = 5; + static const uint8_t REGION_OFFSET = 2; + static const uint8_t ADDRESS_OFFSET = 3; + static const uint8_t LENGTH_OFFSET = 7; static const size_t IMAGE_DATA_SIZE = 1024; + static const size_t MAX_FLASH_DATA = 1024; static const size_t CONFIG_MAX_DOWNLOAD_RETRIES = 3; enum class InternalState { IDLE, UPLOAD_IMAGE, - DOWNLOAD_IMAGE + DOWNLOAD_IMAGE, + FLASH_WRITE, + FLASH_READ }; InternalState internalState = InternalState::IDLE; @@ -143,9 +171,20 @@ private: std::string uploadImage; // Path where the downloaded image will be stored std::string downloadPath; + // File which contains data to write when executing the flash write command + std::string flashWriteFile; + // Path where the file containing the read data will be stored + std::string flashReadFilePath = ""; // Default name of downloaded image, can be changed via command std::string downloadImage = "image"; + // Default name of file containing the data read from flash, can be changed via command + std::string flashReadImage = "flashread"; + // Will be set with the flash write command + uint8_t flashWriteRegion = 0; + // Will be set with the flash write command and specifies the start address where to write the + // flash data to + uint32_t flashWriteAddress = 0; SdCardManager* sdcMan = nullptr; @@ -179,13 +218,23 @@ private: */ ReturnValue_t performImageDownload(); + /** + * @brief Handles flash write procedure + * + * @return RETURN_OK if successful, otherwise RETURN_FAILED + */ + ReturnValue_t performFlashWrite(); + /** * @brief Sends packet to the star tracker and reads reply by using the communication * interface * + * @param size Size of data beforehand written to the commandBuffer + * @param parameter Parameter 2 of trigger event function + * * @return RETURN_OK if successful, otherwise RETURN_FAILED */ - ReturnValue_t sendAndRead(size_t size, uint32_t position); + ReturnValue_t sendAndRead(size_t size, uint32_t parameter); /** * @brief Checks the reply header (type id and status fields) @@ -195,7 +244,7 @@ private: ReturnValue_t checkReply(); /** - * @brief Checks the position field in a star tracker reply. + * @brief Checks the position field in a star tracker upload/download reply. * * @param expectedPosition Value of expected position * @@ -203,6 +252,14 @@ private: */ ReturnValue_t checkReplyPosition(uint32_t expectedPosition); + /** + * @brief Checks the region, address and length value of a flash write reply. + * + * @return RETURN_OK if values match expected values, otherwise appropriate error return + * value. + */ + ReturnValue_t checkFlashWriteReply(struct WriteActionRequest& req); + /** * @brief Checks if a path points to an sd card and whether the SD card is monuted. * @@ -211,4 +268,4 @@ private: ReturnValue_t checkPath(std::string name); }; -#endif /* BSP_Q7S_DEVICES_STRIMAGELOADER_H_ */ +#endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */ diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index fc2bffb2..4c769260 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -19,7 +19,7 @@ enum commonClassIds: uint8_t { CCSDS_IP_CORE_BRIDGE, //IPCI PTME, //PTME PLOC_UPDATER, //PLUD - STR_IMG_LOADER, //STRIMGL + STR_HELPER, //STRHLP GOM_SPACE_HANDLER, //GOMS PLOC_MEMORY_DUMPER, //PLMEMDUMP PDEC_HANDLER, //PDEC diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 2bb216a5..55a4bed4 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -18,7 +18,7 @@ enum: uint8_t { PLOC_UPDATER = 117, PLOC_MEMORY_DUMPER = 118, PDEC_HANDLER = 119, - STR_IMAGE_LOADER = 120, + STR_HELPER = 120, COMMON_SUBSYSTEM_ID_END }; } diff --git a/tmtc b/tmtc index 02b6304e..8a235097 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 02b6304eba009ee620bfe5f9684262acb0cc4bae +Subproject commit 8a2350971db7a7edd491540820a763e30d2dda3c