From c4616e36336f2f496882e5fcdae3496a905607fd Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sat, 24 Jul 2021 13:57:05 +0200 Subject: [PATCH 001/116] get boot status report wip --- mission/devices/PlocSupervisorHandler.cpp | 68 ++++++++++++++++++- mission/devices/PlocSupervisorHandler.h | 7 ++ .../PlocSupervisorDefinitions.h | 59 +++++++++++++--- tmtc | 2 +- 4 files changed, 125 insertions(+), 11 deletions(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 21310248..6e5edee4 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -6,7 +6,7 @@ #include PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF * comCookie) : - DeviceHandlerBase(objectId, uartComIFid, comCookie), hkset(this) { + DeviceHandlerBase(objectId, uartComIFid, comCookie), hkset(this), bootStatusReport(this) { if (comCookie == NULL) { sif::error << "PlocSupervisorHandler: Invalid com cookie" << std::endl; } @@ -106,6 +106,11 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( result = RETURN_OK; break; } + case(PLOC_SPV::GET_BOOT_STATUS_REPORT): { + prepareEmptyCmd(PLOC_SPV::APID_GET_BOOT_STATUS_RPT); + result = RETURN_OK; + break; + } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" << std::endl; @@ -134,6 +139,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::RESET_MPSOC); this->insertInCommandMap(PLOC_SPV::SET_TIME_REF); this->insertInCommandMap(PLOC_SPV::DISABLE_PERIOIC_HK_TRANSMISSION); + this->insertInCommandMap(PLOC_SPV::GET_BOOT_STATUS_REPORT); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, nullptr, PLOC_SPV::SIZE_HK_REPORT); @@ -191,6 +197,10 @@ ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id, result = handleHkReport(packet); break; } + case (PLOC_SPV::BOOT_STATUS_REPORT): { + result = handleBootStatusReport(packet); + break; + } case (PLOC_SPV::EXE_REPORT): { result = handleExecutionReport(packet); break; @@ -228,6 +238,15 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool localDataPoolMap.emplace(PLOC_SPV::CPULOAD, new PoolEntry( { 0 })); localDataPoolMap.emplace(PLOC_SPV::AVAILABLEHEAP, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::BOOT_SIGNAL, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::RESET_COUNTER, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::BOOT_AFTER_MS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::BOOT_TIMEOUT_MS, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::ACTIVE_NVM, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::BP0_STATE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::BP1_STATE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::BP2_STATE, new PoolEntry( { 0 })); + return HasReturnvaluesIF::RETURN_OK; } @@ -408,6 +427,53 @@ ReturnValue_t PlocSupervisorHandler::handleHkReport(const uint8_t* data) { return result; } +ReturnValue_t PlocSupervisorHandler::handleBootStatusReport(const uint8_t* data) { + + ReturnValue_t result = RETURN_OK; + + result = verifyPacket(data, PLOC_SPV::SIZE_BOOT_STATUS_REPORT); + + if(result == CRC_FAILURE) { + sif::error << "PlocSupervisorHandler::handleBootStatusReport: Boot status report has invalid" + " crc" << std::endl; + return result; + } + + uint16_t offset = PLOC_SPV::DATA_FIELD_OFFSET; + bootStatusReport.bootSignal = *(data + offset); + offest += 1; + bootStatusReport.resetCounter = *(data + offset); + offest += 1; + bootStatusReport.bootAfterMs = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offest += 4; + bootStatusReport.bootTimeoutMs = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offest += 4; + bootStatusReport.activeNvm = *(data + offset); + offest += 1; + bootStatusReport.bp0State = *(data + offset); + offest += 1; + bootStatusReport.bp1State = *(data + offset); + offest += 1; + bootStatusReport.bp2State = *(data + offset); + + nextReplyId = PLOC_SPV::EXE_REPORT; + +#if OBSW_VERBOSE_LEVEL >= 1 && PLOC_SUPERVISOR_DEBUG == 1 + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Boot signal: " << static_cast(bootStatusReport.bootSignal.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Reset counter: " << static_cast(bootStatusReport.resetCounter.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootAfterMs: " << bootStatusReport.bootAfterMs << " ms" << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootTimeoutMs: " << bootStatusReport.bootTimeoutMs << " ms" << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Active NVM: " << static_cast(bootStatusReport.activeNvm.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP0: " << static_cast(bootStatusReport.bp0State) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP1: " << static_cast(bootStatusReport.bp1State) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP2: " << static_cast(bootStatusReport.bp2State) << std::endl; +#endif + + return result; +} + ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command, uint8_t expectedReplies, bool useAlternateId, DeviceCommandId_t alternateReplyID) { diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index e91fb1e4..bd1c6cc0 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -100,6 +100,7 @@ private: DeviceCommandId_t nextReplyId = PLOC_SPV::NONE; PLOC_SPV::HkSet hkset; + PLOC_SPV::BootStatusReport bootStatusReport; UartComIF* uartComIf = nullptr; @@ -141,6 +142,12 @@ private: */ ReturnValue_t handleHkReport(const uint8_t* data); + /** + * @brief This function calls the function to check the CRC of the received boot status report + * and fills the associated dataset with the boot status information. + */ + ReturnValue_t handleBootStatusReport(const uint8_t* data); + /** * @brief Depending on the current active command, this function sets the reply id of the * next reply after a successful acknowledgment report has been received. This is diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index dd4f875b..4e07d964 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -20,15 +20,18 @@ static const DeviceCommandId_t SET_MAX_RESTART_TRIES = 7; static const DeviceCommandId_t RESET_MPSOC = 8; static const DeviceCommandId_t SET_TIME_REF = 9; static const DeviceCommandId_t DISABLE_PERIOIC_HK_TRANSMISSION = 10; +static const DeviceCommandId_t GET_BOOT_STATUS_REPORT = 11; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; static const DeviceCommandId_t EXE_REPORT = 51; static const DeviceCommandId_t HK_REPORT = 52; +static const DeviceCommandId_t BOOT_STATUS_REPORT = 5§; static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14; static const uint16_t SIZE_HK_REPORT = 48; +static const uint16_t SIZE_BOOT_STATUS_REPORT = 22; /** * SpacePacket apids of telemetry packets @@ -100,12 +103,22 @@ enum PoolIds TEMP_SUP, UPTIME, CPULOAD, - AVAILABLEHEAP + AVAILABLEHEAP, + BOOT_SIGNAL, + RESET_COUNTER, + BOOT_AFTER_MS, + BOOT_TIMEOUT_MS, + ACTIVE_NVM, + BP0_STATE, + BP1_STATE, + BP2_STATE }; static const uint8_t HK_SET_ENTRIES = 13; +static const uint8_t BOOT_REPORT_SET_ENTRIES = 8; static const uint32_t HK_SET_ID = HK_REPORT; +static const uint32_t BOOT_REPORT_SET_ID = APID_BOOT_STATUS_REPORT; /** * @brief With this class a space packet can be created which does not contain any data. @@ -363,7 +376,7 @@ private: }; /** - * @brief This dataset to store the housekeeping data of the supervisor. + * @brief This dataset stores the housekeeping data of the supervisor. */ class HkSet: public StaticLocalDataSet { public: @@ -376,21 +389,49 @@ public: StaticLocalDataSet(sid_t(objectId, HK_SET_ID)) { } - lp_var_t numTms = lp_var_t(sid.objectId, PoolIds::NUM_TMS, this); lp_var_t tempPs = lp_var_t(sid.objectId, PoolIds::TEMP_PS, this); lp_var_t tempPl = lp_var_t(sid.objectId, PoolIds::TEMP_PS, this); + lp_var_t tempSup = lp_var_t(sid.objectId, PoolIds::TEMP_SUP, this); + lp_var_t uptime = lp_var_t(sid.objectId, PoolIds::UPTIME, this); + lp_var_t cpuLoad = lp_var_t(sid.objectId, PoolIds::CPULOAD, this); + lp_var_t availableHeap = lp_var_t(sid.objectId, PoolIds::AVAILABLEHEAP, + this); + lp_var_t numTcs = lp_var_t(sid.objectId, PoolIds::NUM_TCS, this); + lp_var_t numTms = lp_var_t(sid.objectId, PoolIds::NUM_TMS, this); lp_var_t socState = lp_var_t(sid.objectId, PoolIds::SOC_STATE, this); lp_var_t nvm0_1_state = lp_var_t(sid.objectId, PoolIds::NVM0_1_STATE, this); lp_var_t nvm3_state = lp_var_t(sid.objectId, PoolIds::NVM3_STATE, this); lp_var_t missionIoState = lp_var_t(sid.objectId, PoolIds::MISSION_IO_STATE, this); lp_var_t fmcState = lp_var_t(sid.objectId, PoolIds::FMC_STATE, this); - lp_var_t numTcs = lp_var_t(sid.objectId, PoolIds::NUM_TCS, this); - lp_var_t tempSup = lp_var_t(sid.objectId, PoolIds::TEMP_SUP, this); - lp_var_t uptime = lp_var_t(sid.objectId, PoolIds::UPTIME, this); - lp_var_t cpuLoad = lp_var_t(sid.objectId, PoolIds::CPULOAD, this); - lp_var_t availableHeap = lp_var_t(sid.objectId, PoolIds::AVAILABLEHEAP, - this); +}; + +/** + * @brief This dataset stores the boot status report of the supervisor. + */ +class BootStatusReport: public StaticLocalDataSet { +public: + + BootStatusReport(HasLocalDataPoolIF* owner) : + StaticLocalDataSet(owner, BOOT_REPORT_SET_ID) { + } + + BootStatusReport(object_id_t objectId) : + StaticLocalDataSet(sid_t(objectId, BOOT_REPORT_SET_ID)) { + } + + /** Information about boot status of MPSoC */ + lp_var_t bootSignal = lp_var_t(sid.objectId, PoolIds::BOOT_SIGNAL, this); + lp_var_t resetCounter = lp_var_t(sid.objectId, PoolIds::RESET_COUNTER, this); + /** Time the MPSoC needs for last boot */ + lp_var_t bootAfterMs = lp_var_t(sid.objectId, PoolIds::BOOT_AFTER_MS, this); + /** The currently set boot timeout */ + lp_var_t bootTimeoutMs = lp_var_t(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this); + lp_var_t activeNvm = lp_var_t(sid.objectId, PoolIds::ACTIVE_NVM, this); + /** States of the boot partition pins */ + lp_var_t bp0State = lp_var_t(sid.objectId, PoolIds::BP0_STATE, this); + lp_var_t bp1State = lp_var_t(sid.objectId, PoolIds::BP1_STATE, this); + lp_var_t bp2State = lp_var_t(sid.objectId, PoolIds::BP2_STATE, this); }; } diff --git a/tmtc b/tmtc index 941f4640..e552a92d 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 941f46401e13fb6ee5fc653875eebff8496133ec +Subproject commit e552a92db4800cec4e81af75c33ee0e7f739c460 -- 2.43.0 From 0e3b67383df70be94a816ac77d2ffed38681f778 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Jul 2021 15:29:15 +0200 Subject: [PATCH 002/116] arcsec_star_tracker --- thirdparty/arcsec_star_tracker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/arcsec_star_tracker b/thirdparty/arcsec_star_tracker index f596c533..65dfee81 160000 --- a/thirdparty/arcsec_star_tracker +++ b/thirdparty/arcsec_star_tracker @@ -1 +1 @@ -Subproject commit f596c53315f1f81facb28faec3150612a5ad2ca0 +Subproject commit 65dfee8191cd0254d4988b08c9607024389e2b08 -- 2.43.0 From 733a89a97aa6577735951237d204dc63572fa7a5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Jul 2021 15:30:34 +0200 Subject: [PATCH 003/116] arcsec star tracker update --- thirdparty/arcsec_star_tracker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/arcsec_star_tracker b/thirdparty/arcsec_star_tracker index 65dfee81..c468400a 160000 --- a/thirdparty/arcsec_star_tracker +++ b/thirdparty/arcsec_star_tracker @@ -1 +1 @@ -Subproject commit 65dfee8191cd0254d4988b08c9607024389e2b08 +Subproject commit c468400aaf8470a31e393f53c858d2bf2c361273 -- 2.43.0 From 07f531a044fdb2b7cd9f018ab0e859921de99863 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Jul 2021 17:08:26 +0200 Subject: [PATCH 004/116] update core controller --- bsp_q7s/core/CoreController.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index dddc4c97..a46c74f1 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -269,7 +269,8 @@ ReturnValue_t CoreController::incrementAllocationFailureCount() { ReturnValue_t CoreController::versionFileInit() { std::string unameFileName = "/tmp/uname_version.txt"; - std::string unameCmd = "uname -a > " + unameFileName; + // TODO: No -v flag for now. If the kernel version is used, need to cut off first few letters + std::string unameCmd = "uname -mnrso > " + unameFileName; int result = std::system(unameCmd.c_str()); if(result != 0) { utility::handleSystemError(result, "CoreController::versionFileInit"); -- 2.43.0 From bbc8a3eeefde8e9bf3139705bfbab5a9624bc005 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 24 Jul 2021 17:20:39 +0200 Subject: [PATCH 005/116] README update --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 26adb303..89e2514a 100644 --- a/README.md +++ b/README.md @@ -773,7 +773,10 @@ EIVE implementation - Mount point `/mnt/sd0` created for SD card 0. Created with `mkdir` - Mount point `/mnt/sd1` created for SD card 1. Created with `mkdir` - Folder `scripts` in `/home/root` folder. -- `scripts` folder currently contains `update_main_components.sh` script +- `scripts` folder currently contains a few shell helper scripts +- Folder `profile.d` in `/etc` folder which contains the `path-set.sh` script + which is sourced at software startup +- Library `libwire.so` in `/usr/lib` folder ### SD Cards -- 2.43.0 From f6d43cdf468d6833d23f7785dc3175949460fda1 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sun, 25 Jul 2021 16:24:10 +0200 Subject: [PATCH 006/116] typo in PlocSupervisorDefinitions.h --- mission/devices/devicedefinitions/PlocSupervisorDefinitions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 4e07d964..53cdd2ff 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -26,7 +26,7 @@ static const DeviceCommandId_t GET_BOOT_STATUS_REPORT = 11; static const DeviceCommandId_t ACK_REPORT = 50; static const DeviceCommandId_t EXE_REPORT = 51; static const DeviceCommandId_t HK_REPORT = 52; -static const DeviceCommandId_t BOOT_STATUS_REPORT = 5§; +static const DeviceCommandId_t BOOT_STATUS_REPORT = 53; static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14; -- 2.43.0 From 0cd814db76b83c109db0163c277bfd22eb519c57 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sun, 25 Jul 2021 20:42:24 +0200 Subject: [PATCH 007/116] ploc supervisor update available command, wip --- fsfw | 2 +- mission/devices/PlocSupervisorHandler.cpp | 82 +++++++++++++++---- .../PlocSupervisorDefinitions.h | 71 +++++++++++++++- tmtc | 2 +- 4 files changed, 134 insertions(+), 23 deletions(-) diff --git a/fsfw b/fsfw index c5b4b013..b8325959 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c5b4b0136217219a4443d858f42c368af9b15f27 +Subproject commit b83259592a1f0ae5af20b00d1aef813fa26cd350 diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 6e5edee4..b43bc744 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -110,7 +110,12 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( prepareEmptyCmd(PLOC_SPV::APID_GET_BOOT_STATUS_RPT); result = RETURN_OK; break; - } + } + case(PLOC_SPV::UPDATE_AVAILABLE): { + prepareUpdateAvailableCmd(); + result = RETURN_OK; + break; + } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" << std::endl; @@ -142,7 +147,9 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::GET_BOOT_STATUS_REPORT); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); - this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, nullptr, PLOC_SPV::SIZE_HK_REPORT); + this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); + this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &bootStatusReport, + PLOC_SPV::SIZE_BOOT_STATUS_REPORT); } ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t *start, @@ -441,34 +448,42 @@ ReturnValue_t PlocSupervisorHandler::handleBootStatusReport(const uint8_t* data) uint16_t offset = PLOC_SPV::DATA_FIELD_OFFSET; bootStatusReport.bootSignal = *(data + offset); - offest += 1; + offset += 1; bootStatusReport.resetCounter = *(data + offset); - offest += 1; + offset += 1; bootStatusReport.bootAfterMs = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 | *(data + offset + 3); - offest += 4; + offset += 4; bootStatusReport.bootTimeoutMs = *(data + offset) << 24 | *(data + offset + 1) << 16 | *(data + offset + 2) << 8 | *(data + offset + 3); - offest += 4; + offset += 4; bootStatusReport.activeNvm = *(data + offset); - offest += 1; + offset += 1; bootStatusReport.bp0State = *(data + offset); - offest += 1; + offset += 1; bootStatusReport.bp1State = *(data + offset); - offest += 1; + offset += 1; bootStatusReport.bp2State = *(data + offset); nextReplyId = PLOC_SPV::EXE_REPORT; #if OBSW_VERBOSE_LEVEL >= 1 && PLOC_SUPERVISOR_DEBUG == 1 - sif::info << "PlocSupervisorHandler::handleBootStatusReport: Boot signal: " << static_cast(bootStatusReport.bootSignal.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: Reset counter: " << static_cast(bootStatusReport.resetCounter.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootAfterMs: " << bootStatusReport.bootAfterMs << " ms" << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootTimeoutMs: " << bootStatusReport.bootTimeoutMs << " ms" << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: Active NVM: " << static_cast(bootStatusReport.activeNvm.value) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP0: " << static_cast(bootStatusReport.bp0State) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP1: " << static_cast(bootStatusReport.bp1State) << std::endl; - sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP2: " << static_cast(bootStatusReport.bp2State) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Boot signal: " + << static_cast(bootStatusReport.bootSignal.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Reset counter: " + << static_cast(bootStatusReport.resetCounter.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootAfterMs: " + << bootStatusReport.bootAfterMs << " ms" << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BootTimeoutMs: " + << bootStatusReport.bootTimeoutMs << " ms" << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: Active NVM: " + << static_cast(bootStatusReport.activeNvm.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP0: " + << static_cast(bootStatusReport.bp0State.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP1: " + << static_cast(bootStatusReport.bp1State.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleBootStatusReport: BP2: " + << static_cast(bootStatusReport.bp2State.value) << std::endl; #endif return result; @@ -493,6 +508,16 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite } break; } + case PLOC_SPV::GET_BOOT_STATUS_REPORT: { + enabledReplies = 3; + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC_SPV::BOOT_STATUS_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " + << PLOC_SPV::BOOT_STATUS_REPORT << " not in replyMap" << std::endl; + } + break; + } case PLOC_SPV::RESTART_MPSOC: case PLOC_SPV::START_MPSOC: case PLOC_SPV::SHUTDOWN_MPSOC: @@ -650,6 +675,29 @@ void PlocSupervisorHandler::prepareRestartTriesCmd(const uint8_t * commandData) nextReplyId = PLOC_SPV::ACK_REPORT; } +void PlocSupervisorHandler::prepareUpdateAvailableCmd(const uint8_t * commandData) { + uint8_t offset = 0; + uint8_t imageSelect = *(commandData + offset); + offset += 1; + uint8_t imagePartition = *(commandData + offset); + offset += 1; + uint32_t imageSize = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 + | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); + offset += 4; + uint32_t imageCrc = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 + | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); + offset += 4; + uint32_t numberOfPackets = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 + | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); + + PLOC_SPV::UpdateAvailable packet(imageSelect, imagePartition, imageSize, imageCrc, + numberOfPackets); + memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); + rawPacket = commandBuffer; + rawPacketLen = packet.getFullSize(); + nextReplyId = PLOC_SPV::ACK_REPORT; +} + void PlocSupervisorHandler::disableAllReplies() { DeviceReplyMap::iterator iter; diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 53cdd2ff..d4a21240 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -21,6 +21,8 @@ static const DeviceCommandId_t RESET_MPSOC = 8; static const DeviceCommandId_t SET_TIME_REF = 9; static const DeviceCommandId_t DISABLE_PERIOIC_HK_TRANSMISSION = 10; static const DeviceCommandId_t GET_BOOT_STATUS_REPORT = 11; +/** Notifies the supervisor that a new update is available for the MPSoC */ +static const DeviceCommandId_t UPDATE_AVAILABLE = 12; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; @@ -427,12 +429,73 @@ public: lp_var_t bootAfterMs = lp_var_t(sid.objectId, PoolIds::BOOT_AFTER_MS, this); /** The currently set boot timeout */ lp_var_t bootTimeoutMs = lp_var_t(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this); - lp_var_t activeNvm = lp_var_t(sid.objectId, PoolIds::ACTIVE_NVM, this); + lp_var_t activeNvm = lp_var_t(sid.objectId, PoolIds::ACTIVE_NVM, this); /** States of the boot partition pins */ - lp_var_t bp0State = lp_var_t(sid.objectId, PoolIds::BP0_STATE, this); - lp_var_t bp1State = lp_var_t(sid.objectId, PoolIds::BP1_STATE, this); - lp_var_t bp2State = lp_var_t(sid.objectId, PoolIds::BP2_STATE, this); + lp_var_t bp0State = lp_var_t(sid.objectId, PoolIds::BP0_STATE, this); + lp_var_t bp1State = lp_var_t(sid.objectId, PoolIds::BP1_STATE, this); + lp_var_t bp2State = lp_var_t(sid.objectId, PoolIds::BP2_STATE, this); }; } +/** + * @brief This class packages the command to notify the supervisor that a new update for the + * MPSoC is available. + */ +class UpdateAvailable: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param imageSelect + * @param imagePartition + * @param imageSize + * @param imageCrc + * @param numberOfPackets + */ + UpdateAvailable(uint8_t imageSelect, uint8_t imagePartition, uint32_t imageSize, + uint32_t imageCrc, uint32_t numberOfPackets) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SEL_MPSOC_BOOT_IMAGE, + DEFAULT_SEQUENCE_COUNT), imageSelect(imageSelect), imagePartition( + imagePartition), imageSize(imageSize), imageCrc(imageCrc), numberOfPackets( + numberOfPackets) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 16; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t imageSelect = 0; + uint8_t imagePartition = 0; + uint32_t imageSize = 0; + uint32_t imageCrc = 0; + uint32_t numberOfPackets = 0; + + void initPacket() { + uint8_t offset = 0; + uint8_t* data_field_start = this->localData.fields.buffer; + std::memcpy(data_field_start + offset, &imageSelect, sizeof(imageSelect)); + offset += 1; + std::memcpy(data_field_start + offset, &imagePartition, sizeof(imagePartition)); + offset += 1; + std::memcpy(data_field_start + offset, &imageSize, sizeof(imageSize)); + offset += 4; + std::memcpy(data_field_start + offset, &imageCrc, sizeof(imageCrc)); + offset += 4; + std::memcpy(data_field_start + offset, &numberOfPackets, sizeof(numberOfPackets)); + + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + /* Add crc to packet data field of space packet */ + size_t serializedSize = 0; + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ */ diff --git a/tmtc b/tmtc index 2e942ec2..6352a6f2 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 2e942ec21e47485b9ab6416a0341b9ab8ec30543 +Subproject commit 6352a6f272b3138257831fcd1f5d9ffcd4902681 -- 2.43.0 From 9b2ab66c0a608c08eabbb9f337822ea0966e4d6f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 00:42:33 +0200 Subject: [PATCH 008/116] readme update --- README.md | 600 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 354 insertions(+), 246 deletions(-) diff --git a/README.md b/README.md index 89e2514a..21ee5e40 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,23 @@ EIVE On-Board Software ====== -# General information +# Index + +1. [General](#general) +2. [Prerequisites](#prereq) +3. [Building the Software](#build) +4. [Useful and Common Host Commands](#host-commands) +5. [Setting up Prerequisites](#set-up-prereq) +6. [Remote Debugging](#remote-debugging) +7. [Direct Debugging](#direct-debugging) +8. [Transfering Files to the Q7S](#file-transfer) +9. [Q7S OBC](#q7s) +10. [Static Code Analysis](#static-code-analysis) +11. [Eclipse](#eclipse) +12. [Running the OBSW on a Raspberry Pi](#rpi) +13. [FSFW](#fsfw) + +# General information Target systems: @@ -36,16 +52,169 @@ The CMake build system can be used to generate build systems as well (see helper - Linux Host: Uses the `bsp_hosted` BSP folder and the CMake Unix Makefiles generator. - Windows Host: Uses the `bsp_hosted` BSP folder, the CMake MinGW Makefiles generator and MSYS2. -# Setting up development environment +# Prerequisites -## Installing Vivado the the Xilinx development tools +There is a separate [prerequisites](#set-up-prereq) which specifies how to set up all +prerequisites. + +## Building the OBSW and flashing it on the Q7S + +1. ARM cross-compiler installed, either as part of [Vivado 2018.2 installation](#vivado) or + as a [separate download](#arm-toolchain) +2. [Q7S sysroot](#q7s-sysroot) on local development machine +3. Recommended: Eclipse or [Vivado 2018.2 SDK](#vivado) for OBSW development +3. [TCF agent] running on Q7S + +## Hardware Design + +1. [Vivado 2018.2](#vivado) for programmable logic design + +# Building the software + +## CMake + +When using Windows, run theses steps in MSYS2. + +1. Clone the repository with + + ```sh + git clone https://egit.irs.uni-stuttgart.de/eive/eive_obsw.git + ``` + +2. Update all the submodules + + ```sh + git submodule init + git submodule sync + git submodule update + ``` + +3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version`. + It is recommended to set up a shell script which takes care of setting up the environment + for convenience or to set up the + [PATH and the CROSS_COMPILE variable permanently](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path) + in the `.profile` file. + +4. Run the CMake configuration to create the build system in a `build-Debug-Q7S` folder. + Add `-G "MinGW Makefiles` in MinGW64 on Windows. + + ```sh + mkdir build-Debug-Q7S && cd build-Debug-Q7S + cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DOS_FSFW=linux .. + cmake --build . -j + ``` + + You can also use provided shell scripts to perform these commands + + ```sh + cd cmake/scripts/Q7S + ./make_debug_cfg.sh + cd ../../.. + ``` + + This will invoke a Python script which in turn invokes CMake with the correct + arguments to configure CMake for Q7S cross-compilation. + + You can build the hosted variant of the OBSW by replacing `-DOS_FSFW=linux` with + `-DOS_FSFW=host`. There are also different values for `-DTGT_BSP` to build for the Raspberry Pi + or the Beagle Bone Black: `arm/raspberrypi` and `arm/beagleboneblack`. + +5. Build the software with + ```sh + cd build-Debug-Q7S + cmake --build . -j + ``` + +## Building in Xilinx SDK 2018.2 + +1. Open Xilinx SDK 2018.2 +2. Import project + * File → Import → C/C++ → Existing Code as Makefile Project +3. Set build command. Replace \ with either debug or release. + * When on Linux right click project → Properties → C/C++ Build → Set build command to `make -j` + * -j causes the compiler to use all available cores + * The target is used to either compile the debug or the optimized release build. + * On windows create a make target additionally (Windows → Show View → Make Target) + * Right click eive_obsw → New + * Target name: all + * Uncheck "Same as the target name" + * Uncheck "Use builder settings" + * As build command type: `cmake --build .` + * In the Behaviour tab, you can enable build acceleration +4. Run build command by double clicking the created target or by right clicking + the project folder and selecting Build Project. + +# Useful and Common Commands (Host) + +## Connect to EIVE flatsat + +### DNS + +```sh +ssh eive@flatsat.eive.absatvirt.lw +``` + +### IPv6 +```sh +ssh eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 +``` + +### IPv4 + +```sh +ssh eive@192.168.199.227 +``` + +## Port forwarding for connection to TCF agent + +This is a required step to connect to the `tcf-agent` on the Q7S, which is required for convenient +remote debugging. Assuming the IPv6 + +```sh +ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +``` + +You then need to connect to `localhost` with port `1534`. + +## Port forwarding for file transfers with `scp` + +```sh +ssh -L 1535:192.168.133.10:22 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +``` + +You then need to run `scp` with the `-P 1535` flag with `localhost` as the target IP address. + +## Port forwarding for TMTC commanding + +This requires using the TCP on sender side (Python client) and receiver side (OBSW TMTC TCP server). + +```sh +ssh -L 1536:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +``` + +## Set up all port forwarding at once + +You can specify the `-L` option multiple times to set up all port forwarding at once + +```sh +ssh -L 1534:192.168.133.10:1534 \ + -L 1535:192.168.133.10:22 \ + -L 1536:192.168.133.10:7301 \ + eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ + -t /bin/bash +``` + +# Setting up prerequisites + +## Installing Vivado the the Xilinx development tools It's also possible to perform debugging with a normal Eclipse installation by installing the TCF plugin and downloading the cross-compiler as specified in the section below. However, if you want to generate the `*.xdi` files necessary to update the firmware, you need to installed Vivado with the SDK core tools. -* Install Vivado 2018.2 and Xilinx SDK from https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive.html. +* Install Vivado 2018.2 and + [Xilinx SDK](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive.html). Install the Vivado Design Suite - HLx Editions - 2018.2 Full Product Installation instead of the updates. It is recommended to use the installer. @@ -85,7 +254,7 @@ For Linux, you can also download a more recent version of the [Linaro 8.3.0 cross-compiler](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads) from [here](https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz?revision=e09a1c45-0ed3-4a8e-b06b-db3978fd8d56&la=en&hash=93ED4444B8B3A812B893373B490B90BBB28FD2E3) -## Installing toolchain without Vivado +## Installing toolchain without Vivado You can download the toolchains for Windows and Linux [from the EIVE cloud](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files?dir=/EIVE_IRS/Software/tools&fileid=831898). @@ -136,7 +305,7 @@ wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/2Fp2ag6NGnbtAsK/downloa sudo apt-get install cmake ```` -## Getting the Q7S system root +## Getting the Q7S system root It is necessary to copy the Q7S system root to your local development machine for libraries like `libgpio`. You can find the system root for the Q7S, the Raspberry Pi and the @@ -151,102 +320,58 @@ wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/agnJGYeRf6fw2ci/downloa Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path. -# Building the software with CMake +## Setting up UNIX environment for real-time functionalities -When using Windows, run theses steps in MSYS2. +Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities +used by the UNIX pthread module are restricted, which will lead to permission errors when creating +these tasks and configuring real-time properites like scheduling priorities. -1. Clone the repository with +To solve this issues, try following steps: + +1. Edit the /etc/security/limits.conf +file and add following lines at the end: +```sh + hard rtprio 99 + soft rtprio 99 +``` +The soft limit can also be set in the console with `ulimit -Sr` if the hard +limit has been increased, but it is recommended to add it to the file as well for convenience. +If adding the second line is not desired for security reasons, +the soft limit needs to be set for each session. If using an IDE like eclipse +in that case, the IDE needs to be started from the console after setting +the soft limit higher there. After adding the two lines to the file, +the computer needs to be restarted. + +It is also recommended to perform the following change so that the unlockRealtime +script does not need to be run anymore each time. The following steps +raise the maximum allowed message queue length to a higher number permanently, which is +required for some framework components. The recommended values for the new message +length is 130. + +2. Edit the /etc/sysctl.conf file ```sh - git clone https://egit.irs.uni-stuttgart.de/eive/eive_obsw.git + sudo nano /etc/sysctl.conf ``` -2. Update all the submodules - + Append at end: ```sh - git submodule init - git submodule sync - git submodule update - ``` - -3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version`. - It is recommended to run the shell script `win_path_helper_xilinx_tools.sh` in `cmake/scripts/Q7S` - or to set up the [PATH and the CROSS_COMPILE variable permanently](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path) - in the `.profile` file. - -4. Run the CMake configuration to create the build system in a `build-Debug-Q7S` folder. - Add `-G "MinGW Makefiles` in MinGW64 on Windows. - - ```sh - mkdir build-Debug-Q7S && cd build-Debug-Q7S - cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DOS_FSFW=linux .. - cmake --build . -j - ``` - - You can also use provided shell scripts to perform these commands - - ```sh - cd cmake/scripts/Q7S - ./make_debug_cfg.sh - cd ../../.. - ``` - - This will invoke a Python script which in turn invokes CMake with the correct - arguments to configure CMake for Q7S cross-compilation. - - You can build the hosted variant of the OBSW by replacing `-DOS_FSFW=linux` with - `-DOS_FSFW=host`. There are also different values for `-DTGT_BSP` to build for the Raspberry Pi - or the Beagle Bone Black: `arm/raspberrypi` and `arm/beagleboneblack`. - -5. Build the software with - ```sh - cd Debug - cmake --build . -j + fs/mqueue/msg_max = ``` -## Setting up default Eclipse for Q7S projects - TCF agent + Apply changes with: + ```sh + sudo sysctl -p + ``` -The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debugging on the Q7S. + A possible solution which only persists for the current session is + ```sh + echo | sudo tee /proc/sys/fs/mqueue/msg_max + ``` -1. Install the TCF agent plugin in Eclipse from the [releases](https://www.eclipse.org/tcf/downloads.php). Go to Help → Install New Software and use the download page, for example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it. +## TCF-Agent -2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**. - Here, the Q7S should show up if the local port forwarding was set up as explained previously. Please note that you have to connect to `localhost` and port `1534` with port forwaring set up. - -3. A launch configuration was provided, but it might be necessary to adapt it for your own needs. Alternatively: - - - Create a new **TCF Remote Application** by pressing the cogs button at the top or going to Run → Debug Configurations → Remote Application and creating a new one there. - - - Set up the correct image in the main tab (it might be necessary to send the image to the Q7S manually once) and file transfer properties - - - It is also recommended to link the correct Eclipse project. - -After that, comfortable remote debugging should be possible with the Debug button. - -A build configuration and a shell helper script has been provided to set up the path variables and -build the Q7S binary on Windows, but a launch configuration needs to be newly created because the -IP address and path settings differ from machine to machine. - -## Building in Xilinx SDK 2018.2 - -1. Open Xilinx SDK 2018.2 -2. Import project - * File → Import → C/C++ → Existing Code as Makefile Project -3. Set build command. Replace \ with either debug or release. - * When on Linux right click project → Properties → C/C++ Build → Set build command to `make -j` - * -j causes the compiler to use all available cores - * The target is used to either compile the debug or the optimized release build. - * On windows create a make target additionally (Windows → Show View → Make Target) - * Right click eive_obsw → New - * Target name: all - * Uncheck "Same as the target name" - * Uncheck "Use builder settings" - * As build command type: `cmake --build .` - * In the Behaviour tab, you can enable build acceleration -4. Run build command by double clicking the created target or by right clicking - the project folder and selecting Build Project. - -## TCF-Agent +Most of the steps specified here were already automated 1. On reboot, some steps have to be taken on the Q7S. Set static IP address and netmask @@ -264,7 +389,7 @@ IP address and path settings differ from machine to machine. You can run it manually there. To perform auto-start on boot, have a look at the start-up application section. -# Debugging the software via Flatsat PC +# Remote Debugging Open SSH connection to flatsat PC: @@ -298,6 +423,7 @@ console of the Q7S like this to set it picocom -b 115200 /dev/ttyUSB0 ``` +The flatsat has the aliases and shell scripts `q7s_ssh` and `q7s_serial` for this task as well. If the serial port is blocked for some reason, you can kill the process using it with `q7s_kill`. @@ -325,13 +451,68 @@ ssh -L 1534:192.168.133.10:1534 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t bash ``` This forwards any requests to localhost:1534 to the port 1534 of the Q7S with the IP address -192.168.133.10. -This needs to be done every time, so it is recommended to create an alias to do this quickly. +192.168.133.10. This needs to be done every time, so it is recommended to create an +alias or shell script to do this quickly. Note: When now setting up a debug session in the Xilinx SDK or Eclipse, the host must be set to localhost instead of the IP address of the Q7S. -# Transfering files via SCP +# Direct Debugging + +1. Assign static IP address to Q7S + * Open serial console of Q7S (Accessible via the micro-USB of the PIM, see also Q7S user + manual chapter 10.3) + * Baudrate 115200 + * Login to Q7S: + * user: root + * pw: root + +2. Connect Q7S to workstation via ethernet +3. Make sure the netmask of the ehternet interface of the workstation matches the netmask of the Q7S + * When IP address is set to 192.168.133.10 and the netmask is 255.255.255.0, an example IP address for the workstation + is 192.168.133.2 + +4. Run tcf-agent on Q7S + + * Tcf-agent is not yet integrated in the rootfs of the Q7S. Therefore build tcf-agent manually + + ```sh + git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git + cd org.eclipse.tcf.agent/agent + make CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld MACHINE=arm NO_SSL=1 NO_UUID=1 + ``` + + * Transfer executable agent from org.eclipse.tcf.agent/agent/obj/GNU/Linux/arm/Debug to /tmp of Q7S + + ```sh + cd obj/GNU/Linux/arm/Debug + scp agent root@192.168.133.10:/tmp + ``` + + * On Q7S + ```sh + cd /tmp + chmod +x agent + ``` + + * Run agent + ```sh + ./agent + ``` + +5. In Xilinx SDK 2018.2 right click on project → Debug As → Debug Configurations +6. Right click Xilinx C/C++ applicaton (System Debugger) → New → +7. Set Debug Type to Linux Application Debug and Connectin to Linux Agent +8. Click New +9. Give connection a name +10. Set Host to static IP address of Q7S. e.g. 192.168.133.10 +11. Test connection (This ensures the TCF Agent is running on the Q7S) +12. Select Application tab + * Project Name: eive_obsw + * Local File Path: Path to eiveobsw-linux.elf (in `_bin\linux\devel`) + * Remote File Path: `/tmp/eive_obsw.elf` + +# Transfering Files to the Q7S To transfer files from the local machine to the Q7S, use port forwarding @@ -355,7 +536,11 @@ From a windows machine files can be copied with putty tools (note: use IPv4 addr pscp -scp -P 22 eive@192.168.199.227:/example-file ```` -# Launching an application at start-up +More detailed information about the used q7s commands can be found in the Q7S user manual. + +# Q7S + +## Launching an application at start-up Load the root partiton from the flash memory (there are to nor-flash memories and each flash holds two xdi images). Note: It is not possible to modify the currently loaded root partition, e.g. @@ -420,58 +605,7 @@ creating directories. To do this, the parition needs to be mounted. systemctl status example ``` -More detailed information about the used q7s commands can be found in the Q7S user manual. - -## Setting up UNIX environment for real-time functionalities - -Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities -used by the UNIX pthread module are restricted, which will lead to permission errors when creating -these tasks and configuring real-time properites like scheduling priorities. - -To solve this issues, try following steps: - -1. Edit the /etc/security/limits.conf -file and add following lines at the end: -```sh - hard rtprio 99 - soft rtprio 99 -``` -The soft limit can also be set in the console with `ulimit -Sr` if the hard -limit has been increased, but it is recommended to add it to the file as well for convenience. -If adding the second line is not desired for security reasons, -the soft limit needs to be set for each session. If using an IDE like eclipse -in that case, the IDE needs to be started from the console after setting -the soft limit higher there. After adding the two lines to the file, -the computer needs to be restarted. - -It is also recommended to perform the following change so that the unlockRealtime -script does not need to be run anymore each time. The following steps -raise the maximum allowed message queue length to a higher number permanently, which is -required for some framework components. The recommended values for the new message -length is 130. - -2. Edit the /etc/sysctl.conf file - - ```sh - sudo nano /etc/sysctl.conf - ``` - - Append at end: - ```sh - fs/mqueue/msg_max = - ``` - - Apply changes with: - ```sh - sudo sysctl -p - ``` - - A possible solution which only persists for the current session is - ```sh - echo | sudo tee /proc/sys/fs/mqueue/msg_max - ``` - -# PCDU +## PCDU Connect to serial console of P60 Dock ```` @@ -496,102 +630,6 @@ p60-dock # param get out_en[0] GET out_en[0] = 1 ```` -# Debugging the software (when workstation is directly conncected to Q7S) - -1. Assign static IP address to Q7S - * Open serial console of Q7S (Accessible via the micro-USB of the PIM, see also Q7S user - manual chapter 10.3) - * Baudrate 115200 - * Login to Q7S: - * user: root - * pw: root - -2. Connect Q7S to workstation via ethernet -3. Make sure the netmask of the ehternet interface of the workstation matches the netmask of the Q7S - * When IP address is set to 192.168.133.10 and the netmask is 255.255.255.0, an example IP address for the workstation - is 192.168.133.2 - -4. Run tcf-agent on Q7S - - * Tcf-agent is not yet integrated in the rootfs of the Q7S. Therefore build tcf-agent manually - - ```sh - git clone git://git.eclipse.org/gitroot/tcf/org.eclipse.tcf.agent.git - cd org.eclipse.tcf.agent/agent - make CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld MACHINE=arm NO_SSL=1 NO_UUID=1 - ``` - - * Transfer executable agent from org.eclipse.tcf.agent/agent/obj/GNU/Linux/arm/Debug to /tmp of Q7S - - ```sh - cd obj/GNU/Linux/arm/Debug - scp agent root@192.168.133.10:/tmp - ``` - - * On Q7S - ```sh - cd /tmp - chmod +x agent - ``` - - * Run agent - ```sh - ./agent - ``` - -5. In Xilinx SDK 2018.2 right click on project → Debug As → Debug Configurations -6. Right click Xilinx C/C++ applicaton (System Debugger) → New → -7. Set Debug Type to Linux Application Debug and Connectin to Linux Agent -8. Click New -9. Give connection a name -10. Set Host to static IP address of Q7S. e.g. 192.168.133.10 -11. Test connection (This ensures the TCF Agent is running on the Q7S) -12. Select Application tab - * Project Name: eive_obsw - * Local File Path: Path to eiveobsw-linux.elf (in `_bin\linux\devel`) - * Remote File Path: `/tmp/eive_obsw.elf` - -# Running cppcheck on the Software - -Static code analysis can be useful to find bugs. -`cppcheck` can be used for this purpose. On Windows you can use MinGW64 to do this. - -```sh -pacman -S mingw-w64-x86_64-cppcheck -``` - -On Ubuntu, install with - -```sh -sudo apt-get install cppcheck -``` - -You can use the Eclipse integration or you can perform the scanning manually from the command line. -CMake will be used for this. - -Run the CMake build generation commands specified above but supply -`-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` to the build generation. Invoking the build command will -generate a `compile_commands.json` file which can be used by cppcheck. - -```sh -cppcheck --project=compile_commands.json --xml 2> report.xml -``` - -Finally, you can convert the generated `.xml` file to HTML with the following command - -```sh -cppcheck-htmlreport --file=report.xml --report-dir=cppcheck --source-dir=.. -``` - -# Special notes on Eclipse - -When using Eclipse, there are two special build variables in the project properties -→ C/C++ Build → Build Variables called `Q7S_SYSROOT` or `RPI_SYSROOT`. You can set -the sysroot path in those variables to get any additional includes like `gpiod.h` in the -Eclipse indexer. - -# Q7S Utilities and Troubleshooting - ## Core commands Display currently running image: @@ -786,7 +824,76 @@ EIVE implementation - Folder `tm` for telemetry - Folder `xdi` for XDI components (e.g. for firmware or device tree updates) -# Running the EIVE OBSW on a Raspberry Pi +# Running cppcheck on the Software + +Static code analysis can be useful to find bugs. +`cppcheck` can be used for this purpose. On Windows you can use MinGW64 to do this. + +```sh +pacman -S mingw-w64-x86_64-cppcheck +``` + +On Ubuntu, install with + +```sh +sudo apt-get install cppcheck +``` + +You can use the Eclipse integration or you can perform the scanning manually from the command line. +CMake will be used for this. + +Run the CMake build generation commands specified above but supply +`-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` to the build generation. Invoking the build command will +generate a `compile_commands.json` file which can be used by cppcheck. + +```sh +cppcheck --project=compile_commands.json --xml 2> report.xml +``` + +Finally, you can convert the generated `.xml` file to HTML with the following command + +```sh +cppcheck-htmlreport --file=report.xml --report-dir=cppcheck --source-dir=.. +``` + +# Eclipse + +When using Eclipse, there are two special build variables in the project properties +→ C/C++ Build → Build Variables called `Q7S_SYSROOT` or `RPI_SYSROOT`. You can set +the sysroot path in those variables to get any additional includes like `gpiod.h` in the +Eclipse indexer. + +## Setting up default Eclipse for Q7S projects - TCF agent + +The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debugging on the Q7S. + +1. Install the TCF agent plugin in Eclipse from + the [releases](https://www.eclipse.org/tcf/downloads.php). Go to + Help → Install New Software and use the download page, for + example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it. + +2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**. + Here, the Q7S should show up if the local port forwarding was set up as explained previously. + Please note that you have to connect to `localhost` and port `1534` with port forwaring set up. + +3. A launch configuration was provided, but it might be necessary to adapt it for your own needs. + Alternatively: + + - Create a new **TCF Remote Application** by pressing the cogs button at the top or going to + Run → Debug Configurations → Remote Application and creating a new one there. + + - Set up the correct image in the main tab (it might be necessary to send the image to the + Q7S manually once) and file transfer properties + + - It is also recommended to link the correct Eclipse project. + +After that, comfortable remote debugging should be possible with the Debug button. + +A build configuration and a shell helper script has been provided to set up the path variables and +build the Q7S binary on Windows, but a launch configuration needs to be newly created because the +IP address and path settings differ from machine to machine. + +# Running the EIVE OBSW on a Raspberry Pi Special section for running the EIVE OBSW on the Raspberry Pi. The Raspberry Pi build uses the `bsp_rpi` BSP folder, and a very similar cross-compiler. @@ -802,7 +909,7 @@ sudo apt-get install gpiod libgpiod-dev to install the required GPIO libraries before cloning the system root folder. -# Flight Software Framework (FSFW) +# Flight Software Framework (FSFW) An EIVE fork of the FSFW is submodules into this repository. To add the master upstream branch and merge changes and updates from it @@ -819,4 +926,5 @@ After that, an update can be merged by running git merge upstream/master ``` -Alternatively, changes from other upstreams (forks) and branches can be merged like that in the same way. +Alternatively, changes from other upstreams (forks) and branches can be merged like that +in the same way. -- 2.43.0 From 4b4b75085cc3bb902d0078faf9e680d011a2d7ec Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 00:45:52 +0200 Subject: [PATCH 009/116] added helper script --- q7s-port.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100755 q7s-port.sh diff --git a/q7s-port.sh b/q7s-port.sh new file mode 100755 index 00000000..a4042fd6 --- /dev/null +++ b/q7s-port.sh @@ -0,0 +1,11 @@ +#!/bin/bash +echo "Setting up all Q7S ports" +echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" +echo "-L 1535:192.168.133.10:22 for file transfers" +echo "-L 1536:192.168.133.10:7301 to TMTC commanding using TCP" + +ssh -L 1534:192.168.133.10:1534 \ + -L 1535:192.168.133.10:22 \ + -L 1536:192.168.133.10:7301 \ + eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ + -t /bin/bash -- 2.43.0 From 4645b8d35b9cc45b7679533ada303c8f3f8c5d1e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 00:47:55 +0200 Subject: [PATCH 010/116] added script folder --- q7s-port.sh => scripts/q7s-port.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename q7s-port.sh => scripts/q7s-port.sh (100%) diff --git a/q7s-port.sh b/scripts/q7s-port.sh similarity index 100% rename from q7s-port.sh rename to scripts/q7s-port.sh -- 2.43.0 From 474054f4d83d341939e1d345be4a95316a7fc3bb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 01:21:37 +0200 Subject: [PATCH 011/116] updated cp script --- scripts/q7s-cp.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100755 scripts/q7s-cp.py diff --git a/scripts/q7s-cp.py b/scripts/q7s-cp.py new file mode 100755 index 00000000..9de9d661 --- /dev/null +++ b/scripts/q7s-cp.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +import argparse +import os + + +def main(): + args = handle_args() + cmd = build_cmd(args) + # Run the command + print(f'Running command: {cmd}') + os.system(cmd) + + +def handle_args(): + help_string = 'This script copies files to the Q7S as long as port forwarding is active.\n' + help_string += 'You can set up port forwarding with ' \ + '"ssh -L 1535:192.168.133.10:22 " -t /bin/bash' + parser = argparse.ArgumentParser( + description=help_string + ) + # Optional arguments + parser.add_argument('-r', '--recursive', dest='recursive', default=False, action='store_true') + parser.add_argument('-t', '--target', help='Target destination', default='/tmp') + parser.add_argument('-P', '--port', help='Target port', default=1535) + # Positional argument(s) + parser.add_argument('source', help='Source files to copy') + return parser.parse_args() + + +def build_cmd(args): + # Build run command + cmd = 'scp ' + if args.recursive: + cmd += '-r ' + cmd += f'-P {args.port} {args.source} root@localhost:' + if args.target: + cmd += args.target + return cmd + + +if __name__ == "__main__": + main() -- 2.43.0 From 0ff837baa14fe2bdd750f4c9987275628d255126 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 10:15:44 +0200 Subject: [PATCH 012/116] updated port script --- scripts/q7s-port.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/q7s-port.sh b/scripts/q7s-port.sh index a4042fd6..4bbf17e9 100755 --- a/scripts/q7s-port.sh +++ b/scripts/q7s-port.sh @@ -8,4 +8,4 @@ ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ -L 1536:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ - -t /bin/bash + -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' -- 2.43.0 From 7ff133687eeb38e1c6ea8f8fa27d411f8ea40ccd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 10:46:50 +0200 Subject: [PATCH 013/116] README update --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 21ee5e40..512fa7b9 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,34 @@ ssh eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 ssh eive@192.168.199.227 ``` +## Connecting to the serial console or ssh console + +A serial console session is up permanently in a `tmux` session + +### Serial console + +You can check whether the sessions exist with `tmux ls` + +```sh +tmux a -t q7s-serial +``` + +If the session does not exist, you can create it like this + +```sh +tmux new -s q7s-serial +/bin/bash +q7s_serial +``` + +### SSH console + +You can use the following command to connect to the Q7S with `ssh`: + +```sh +q7s_ssh +``` + ## Port forwarding for connection to TCF agent This is a required step to connect to the `tcf-agent` on the Q7S, which is required for convenient -- 2.43.0 From 84ce7d22bf429765227117fb8302cf64badf1590 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:04:56 +0200 Subject: [PATCH 014/116] added logo --- README.md | 2 ++ doc/img/eive-logo.png | Bin 0 -> 106723 bytes 2 files changed, 2 insertions(+) create mode 100644 doc/img/eive-logo.png diff --git a/README.md b/README.md index 512fa7b9..d3fbb0b3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + + EIVE On-Board Software ====== diff --git a/doc/img/eive-logo.png b/doc/img/eive-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0ce27fef6914207f1d5969e7793fbe7a258803d3 GIT binary patch literal 106723 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 Date: Mon, 26 Jul 2021 11:05:43 +0200 Subject: [PATCH 015/116] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3fbb0b3..a7283fb2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - + EIVE On-Board Software ====== -- 2.43.0 From 10507904e8f628c5aa75e934812e1a50b030da45 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:07:41 +0200 Subject: [PATCH 016/116] small update --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a7283fb2..f0f759b5 100644 --- a/README.md +++ b/README.md @@ -231,9 +231,11 @@ ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ -L 1536:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ - -t /bin/bash + -t 'export CONSOLE_PREFIX="[Q7S Tunnel] /bin/bash' ``` +There is also a shell script called `q7s-port.sh` which can be used to achieve the same. + # Setting up prerequisites ## Installing Vivado the the Xilinx development tools -- 2.43.0 From be6ae6b7ae605389e909011a26d26791be6d02c7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:33:38 +0200 Subject: [PATCH 017/116] added TCP support --- bsp_hosted/InitMission.cpp | 4 ++-- bsp_hosted/ObjectFactory.cpp | 6 +++--- bsp_linux_board/InitMission.cpp | 4 ++-- bsp_linux_board/ObjectFactory.cpp | 6 +++--- bsp_q7s/core/InitMission.cpp | 17 +++++++++-------- bsp_q7s/core/ObjectFactory.cpp | 20 ++++++++++++++++---- common/config/commonConfig.h.in | 1 - common/config/commonObjects.h | 4 ++-- linux/fsfwconfig/OBSWConfig.h.in | 5 +++++ scripts/q7s-port-tcp.sh | 11 +++++++++++ scripts/{q7s-port.sh => q7s-port-udp.sh} | 2 +- 11 files changed, 54 insertions(+), 26 deletions(-) create mode 100755 scripts/q7s-port-tcp.sh rename scripts/{q7s-port.sh => q7s-port-udp.sh} (84%) diff --git a/bsp_hosted/InitMission.cpp b/bsp_hosted/InitMission.cpp index 2743aa36..8ef40d06 100644 --- a/bsp_hosted/InitMission.cpp +++ b/bsp_hosted/InitMission.cpp @@ -72,13 +72,13 @@ void initmission::initTasks() { /* UDP bridge */ PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); + result = udpBridgeTask->addComponent(objects::TMTC_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Unix Bridge failed" << std::endl; } PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); + result = udpPollingTask->addComponent(objects::TMTC_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Polling failed" << std::endl; } diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index acc0be37..0933df5b 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -28,7 +28,7 @@ void Factory::setStaticFrameworkObjectIds(){ CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - TmFunnel::downlinkDestination = objects::UDP_BRIDGE; + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; // No storage object for now. TmFunnel::storageDestination = objects::NO_OBJECT; @@ -40,7 +40,7 @@ void ObjectFactory::produce(void* args){ Factory::setStaticFrameworkObjectIds(); ObjectFactory::produceGenericObjects(); - new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); - new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); + new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); } diff --git a/bsp_linux_board/InitMission.cpp b/bsp_linux_board/InitMission.cpp index 9e7abd94..68423216 100644 --- a/bsp_linux_board/InitMission.cpp +++ b/bsp_linux_board/InitMission.cpp @@ -66,13 +66,13 @@ void initmission::initTasks() { /* UDP bridge */ PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); + result = udpBridgeTask->addComponent(objects::TMTC_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Unix Bridge failed" << std::endl; } PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); + result = udpPollingTask->addComponent(objects::TMTC_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Polling failed" << std::endl; } diff --git a/bsp_linux_board/ObjectFactory.cpp b/bsp_linux_board/ObjectFactory.cpp index 4f7dd59a..0d3e8ce5 100644 --- a/bsp_linux_board/ObjectFactory.cpp +++ b/bsp_linux_board/ObjectFactory.cpp @@ -45,7 +45,7 @@ void Factory::setStaticFrameworkObjectIds() { CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - TmFunnel::downlinkDestination = objects::UDP_BRIDGE; + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; // No storage object for now. TmFunnel::storageDestination = objects::NO_OBJECT; @@ -59,8 +59,8 @@ void ObjectFactory::produce(void* args){ Factory::setStaticFrameworkObjectIds(); ObjectFactory::produceGenericObjects(); - new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); - new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); + new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF); GpioCookie* gpioCookie = nullptr; diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 712cf9c8..a619da5a 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -82,19 +82,20 @@ void initmission::initTasks() { } /* UDP bridge */ - PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( + PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); + result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); + initmission::printAddObjectError("UDP_BRIDGE", objects::TMTC_BRIDGE); } - PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( + PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); + result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { - initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); + initmission::printAddObjectError("UDP_POLLING", objects::TMTC_POLLING_TASK); } + // FS task, task interval does not matter because it runs in permanent loop, priority low // because it is a non-essential background task PeriodicTaskIF* fsTask = factory->createPeriodicTask( @@ -133,8 +134,8 @@ void initmission::initTasks() { sif::info << "Starting tasks.." << std::endl; tmTcDistributor->startTask(); - udpBridgeTask->startTask(); - udpPollingTask->startTask(); + tmtcBridgeTask->startTask(); + tmtcPollingTask->startTask(); coreController->startTask(); taskStarter(pstTasks, "PST task vector"); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 3e36e63d..53da02c5 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -63,9 +63,16 @@ #include "fsfw/tmtcservices/PusServiceBase.h" #include "fsfw/tmtcpacket/pus/tm.h" -/* UDP server includes */ +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 +// UDP server includes #include "fsfw/osal/common/UdpTmTcBridge.h" #include "fsfw/osal/common/UdpTcPollingTask.h" +#else +// TCP server includes +#include "fsfw/osal/common/TcpTmTcBridge.h" +#include "fsfw/osal/common/TcpTmTcServer.h" +#endif + #include "linux/boardtest/SpiTestClass.h" #if TEST_LIBGPIOD == 1 @@ -83,7 +90,7 @@ void Factory::setStaticFrameworkObjectIds() { CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR; CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; - TmFunnel::downlinkDestination = objects::UDP_BRIDGE; + TmFunnel::downlinkDestination = objects::TMTC_BRIDGE; // No storage object for now. TmFunnel::storageDestination = objects::NO_OBJECT; @@ -131,8 +138,13 @@ void ObjectFactory::produce(void* args){ createReactionWheelComponents(gpioComIF); #endif /* TE7020 != 0 */ - new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); - new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 + new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); +#else + new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); +#endif /* Test Task */ #if OBSW_ADD_TEST_CODE == 1 diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index 6c5cb4c4..3d741bcf 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -3,5 +3,4 @@ #define OBSW_ADD_LWGPS_TEST 0 - #endif /* COMMON_CONFIG_COMMONCONFIG_H_ */ diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 0505e570..8c9a83b9 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -8,8 +8,8 @@ enum commonObjects: uint32_t { /* First Byte 0x50-0x52 reserved for PUS Services **/ CCSDS_PACKET_DISTRIBUTOR = 0x50000100, PUS_PACKET_DISTRIBUTOR = 0x50000200, - UDP_BRIDGE = 0x50000300, - UDP_POLLING_TASK = 0x50000400, + TMTC_BRIDGE = 0x50000300, + TMTC_POLLING_TASK = 0x50000400, FILE_SYSTEM_HANDLER = 0x50000500, /* 0x43 ('C') for Controllers */ diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index ab55537d..e58261f1 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -17,6 +17,11 @@ /* These defines should be disabled for mission code but are useful for debugging. */ #define OBSW_VERBOSE_LEVEL 1 + +// Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally +// because UDP packets are not allowed in the VPN +#define OBSW_USE_TMTC_TCP_BRIDGE 1 + #define OBSW_PRINT_MISSED_DEADLINES 1 #define OBSW_ADD_TEST_CODE 1 #define OBSW_ADD_TEST_PST 1 diff --git a/scripts/q7s-port-tcp.sh b/scripts/q7s-port-tcp.sh new file mode 100755 index 00000000..9a1cf3cd --- /dev/null +++ b/scripts/q7s-port-tcp.sh @@ -0,0 +1,11 @@ +#!/bin/bash +echo "Setting up all Q7S ports" +echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" +echo "-L 1535:192.168.133.10:22 for file transfers" +echo "-L 1536:192.168.133.10:7303 to TMTC commanding using TCP" + +ssh -L 1534:192.168.133.10:1534 \ + -L 1535:192.168.133.10:22 \ + -L 1536:192.168.133.10:7303 \ + eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ + -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' diff --git a/scripts/q7s-port.sh b/scripts/q7s-port-udp.sh similarity index 84% rename from scripts/q7s-port.sh rename to scripts/q7s-port-udp.sh index 4bbf17e9..21393083 100755 --- a/scripts/q7s-port.sh +++ b/scripts/q7s-port-udp.sh @@ -2,7 +2,7 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 1536:192.168.133.10:7301 to TMTC commanding using TCP" +echo "-L 1536:192.168.133.10:7301 to TMTC commanding using UDP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ -- 2.43.0 From 2a5f8241615a15a3aeaec82fd99206872eb7eb4f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:47:45 +0200 Subject: [PATCH 018/116] UDP remains default for now --- bsp_q7s/core/CoreController.cpp | 20 +++++++++++++++++++- bsp_q7s/core/CoreController.h | 1 + fsfw | 2 +- linux/fsfwconfig/OBSWConfig.h.in | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index a46c74f1..b72bbf62 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -1,9 +1,14 @@ #include "CoreController.h" -#include "q7sConfig.h" +#include "OBSWConfig.h" #include "OBSWVersion.h" #include "fsfw/FSFWVersion.h" #include "fsfw/serviceinterface/ServiceInterface.h" +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 +#include "fsfw/osal/common/UdpTmTcBridge.h" +#else +#include "fsfw/osal/common/TcpTmTcBridge.h" +#endif #include "bsp_q7s/memory/scratchApi.h" #include "bsp_q7s/memory/SdCardManager.h" @@ -188,6 +193,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; } + initPrint(); return result; } @@ -349,3 +355,15 @@ ReturnValue_t CoreController::versionFileInit() { return HasReturnvaluesIF::RETURN_OK; } + +void CoreController::initPrint() { +#if OBSW_VERBOSE_LEVEL >= 1 +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 + sif::info << "Created UDP server for TMTC commanding with listener port " << + TcpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl; +#else + sif::info << "Created TCP server for TMTC commanding with listener port " << + TcpTmTcBridge::DEFAULT_TCP_SERVER_PORT << std::endl; +#endif +#endif +} diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index d815f302..88415949 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -41,6 +41,7 @@ private: SdCardManager::SdStatusPair& statusPair); ReturnValue_t versionFileInit(); + void initPrint(); }; diff --git a/fsfw b/fsfw index c5b4b013..1f6a5e63 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c5b4b0136217219a4443d858f42c368af9b15f27 +Subproject commit 1f6a5e635fcd6bd812e262cc65a15a8a054f7ecf diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index e58261f1..7a798717 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -20,7 +20,7 @@ debugging. */ // Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally // because UDP packets are not allowed in the VPN -#define OBSW_USE_TMTC_TCP_BRIDGE 1 +#define OBSW_USE_TMTC_TCP_BRIDGE 0 #define OBSW_PRINT_MISSED_DEADLINES 1 #define OBSW_ADD_TEST_CODE 1 -- 2.43.0 From 3f509ce47258cf825b6872992245050dc417dd17 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:56:39 +0200 Subject: [PATCH 019/116] updated port forwarding scripts --- scripts/q7s-port-tcp.sh | 4 ++-- scripts/q7s-port-udp.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/q7s-port-tcp.sh b/scripts/q7s-port-tcp.sh index 9a1cf3cd..7688380b 100755 --- a/scripts/q7s-port-tcp.sh +++ b/scripts/q7s-port-tcp.sh @@ -2,10 +2,10 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 1536:192.168.133.10:7303 to TMTC commanding using TCP" +echo "-L 7303:192.168.133.10:7303 to TMTC commanding using TCP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 1536:192.168.133.10:7303 \ + -L 7303:192.168.133.10:7303 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' diff --git a/scripts/q7s-port-udp.sh b/scripts/q7s-port-udp.sh index 21393083..26003c44 100755 --- a/scripts/q7s-port-udp.sh +++ b/scripts/q7s-port-udp.sh @@ -2,10 +2,10 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 1536:192.168.133.10:7301 to TMTC commanding using UDP" +echo "-L 7301:192.168.133.10:7301 to TMTC commanding using UDP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 1536:192.168.133.10:7301 \ + -L 7301:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' -- 2.43.0 From 4093b2cff22c0e53ae473955b100d52f6ccba907 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 11:58:28 +0200 Subject: [PATCH 020/116] updating README --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a7283fb2..6deaa770 100644 --- a/README.md +++ b/README.md @@ -216,20 +216,27 @@ You then need to run `scp` with the `-P 1535` flag with `localhost` as the targe ## Port forwarding for TMTC commanding -This requires using the TCP on sender side (Python client) and receiver side (OBSW TMTC TCP server). +If you are using the UDP communication interface, you can use: ```sh -ssh -L 1536:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +ssh -L 7301:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +``` + +For TCP, you can use + +```sh +ssh -L 7303:192.168.133.10:7303 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash ``` ## Set up all port forwarding at once -You can specify the `-L` option multiple times to set up all port forwarding at once +You can specify the `-L` option multiple times to set up all port forwarding at once. +Example for using the UDP communication interface: ```sh ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 1536:192.168.133.10:7301 \ + -L 7301:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t /bin/bash ``` -- 2.43.0 From 5b99199b6c2dd8a873de5194ab0b204febbdc0d5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 12:02:40 +0200 Subject: [PATCH 021/116] changed back some configuration --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7ed6a814..fc218749 100644 --- a/README.md +++ b/README.md @@ -219,15 +219,19 @@ You then need to run `scp` with the `-P 1535` flag with `localhost` as the targe If you are using the UDP communication interface, you can use: ```sh -ssh -L 7301:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +ssh -L 1536:192.168.133.10:7301 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash ``` +This forwards UDP TMTC packets on port `1536` of localhost to the TMTC reception port of the Q7S. + For TCP, you can use ```sh -ssh -L 7303:192.168.133.10:7303 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash +ssh -L 1537:192.168.133.10:7303 eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 -t /bin/bash ``` +This forwards TCP TMTC packets on port `1537` of localhost to the TMTC reception port of the Q7S. + ## Set up all port forwarding at once You can specify the `-L` option multiple times to set up all port forwarding at once. @@ -236,7 +240,7 @@ Example for using the UDP communication interface: ```sh ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 7301:192.168.133.10:7301 \ + -L 1536:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'export CONSOLE_PREFIX="[Q7S Tunnel] /bin/bash' ``` -- 2.43.0 From 9878b8defcd0ea5a12cda6bb916c2a465baa3f4e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 12:03:17 +0200 Subject: [PATCH 022/116] updated shell scripts --- scripts/q7s-port-tcp.sh | 4 ++-- scripts/q7s-port-udp.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/q7s-port-tcp.sh b/scripts/q7s-port-tcp.sh index 7688380b..9d370670 100755 --- a/scripts/q7s-port-tcp.sh +++ b/scripts/q7s-port-tcp.sh @@ -2,10 +2,10 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 7303:192.168.133.10:7303 to TMTC commanding using TCP" +echo "-L 1537:192.168.133.10:7303 to TMTC commanding using TCP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 7303:192.168.133.10:7303 \ + -L 1537:192.168.133.10:7303 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' diff --git a/scripts/q7s-port-udp.sh b/scripts/q7s-port-udp.sh index 26003c44..21393083 100755 --- a/scripts/q7s-port-udp.sh +++ b/scripts/q7s-port-udp.sh @@ -2,10 +2,10 @@ echo "Setting up all Q7S ports" echo "-L 1534:192.168.133.10:1534 for connection to TCF agent" echo "-L 1535:192.168.133.10:22 for file transfers" -echo "-L 7301:192.168.133.10:7301 to TMTC commanding using UDP" +echo "-L 1536:192.168.133.10:7301 to TMTC commanding using UDP" ssh -L 1534:192.168.133.10:1534 \ -L 1535:192.168.133.10:22 \ - -L 7301:192.168.133.10:7301 \ + -L 1536:192.168.133.10:7301 \ eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ -t 'CONSOLE_PREFIX="[Q7S Tunnel]" /bin/bash' -- 2.43.0 From 01a02f896f47ab0abcc42a69f6f92632dadaf194 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Mon, 26 Jul 2021 12:08:38 +0200 Subject: [PATCH 023/116] ploc supervisor update available cmd, wip --- mission/devices/PlocSupervisorHandler.cpp | 11 +- mission/devices/PlocSupervisorHandler.h | 6 + .../PlocSupervisorDefinitions.h | 182 +++++++++--------- 3 files changed, 108 insertions(+), 91 deletions(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index b43bc744..5af3693b 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -112,7 +112,7 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( break; } case(PLOC_SPV::UPDATE_AVAILABLE): { - prepareUpdateAvailableCmd(); + prepareUpdateAvailableCmd(commandData); result = RETURN_OK; break; } @@ -148,7 +148,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); - this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &bootStatusReport, + this->insertInReplyMap(PLOC_SPV::BOOT_STATUS_REPORT, 3, &bootStatusReport, PLOC_SPV::SIZE_BOOT_STATUS_REPORT); } @@ -172,6 +172,10 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t *start, *foundLen = PLOC_SPV::SIZE_HK_REPORT; *foundId = PLOC_SPV::HK_REPORT; break; + case(PLOC_SPV::APID_BOOT_STATUS_REPORT): + *foundLen = PLOC_SPV::SIZE_BOOT_STATUS_REPORT; + *foundId = PLOC_SPV::BOOT_STATUS_REPORT; + break; case(PLOC_SPV::APID_EXE_SUCCESS): *foundLen = PLOC_SPV::SIZE_EXE_REPORT; *foundId = PLOC_SPV::EXE_REPORT; @@ -559,6 +563,9 @@ void PlocSupervisorHandler::setNextReplyId() { case PLOC_SPV::GET_HK_REPORT: nextReplyId = PLOC_SPV::HK_REPORT; break; + case PLOC_SPV::GET_BOOT_STATUS_REPORT: + nextReplyId = PLOC_SPV::BOOT_STATUS_REPORT; + break; default: /* If no telemetry is expected the next reply is always the execution report */ nextReplyId = PLOC_SPV::EXE_REPORT; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index bd1c6cc0..d4ad811c 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -194,6 +194,12 @@ private: void prepareRestartTriesCmd(const uint8_t * commandData); + /** + * @brief This function fills the command buffer with the packet to notify the supervisor + * about the availability of an update for the MPSoC + */ + void prepareUpdateAvailableCmd(const uint8_t * commandData); + /** * @brief In case an acknowledgment failure reply has been received this function disables * all previously enabled commands and resets the exepected replies variable of an diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index d4a21240..87153978 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -342,6 +342,99 @@ private: } }; +/** + * @brief This dataset stores the boot status report of the supervisor. + */ +class BootStatusReport: public StaticLocalDataSet { +public: + + BootStatusReport(HasLocalDataPoolIF* owner) : + StaticLocalDataSet(owner, BOOT_REPORT_SET_ID) { + } + + BootStatusReport(object_id_t objectId) : + StaticLocalDataSet(sid_t(objectId, BOOT_REPORT_SET_ID)) { + } + + /** Information about boot status of MPSoC */ + lp_var_t bootSignal = lp_var_t(sid.objectId, PoolIds::BOOT_SIGNAL, this); + lp_var_t resetCounter = lp_var_t(sid.objectId, PoolIds::RESET_COUNTER, this); + /** Time the MPSoC needs for last boot */ + lp_var_t bootAfterMs = lp_var_t(sid.objectId, PoolIds::BOOT_AFTER_MS, this); + /** The currently set boot timeout */ + lp_var_t bootTimeoutMs = lp_var_t(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this); + lp_var_t activeNvm = lp_var_t(sid.objectId, PoolIds::ACTIVE_NVM, this); + /** States of the boot partition pins */ + lp_var_t bp0State = lp_var_t(sid.objectId, PoolIds::BP0_STATE, this); + lp_var_t bp1State = lp_var_t(sid.objectId, PoolIds::BP1_STATE, this); + lp_var_t bp2State = lp_var_t(sid.objectId, PoolIds::BP2_STATE, this); +}; + +/** + * @brief This class packages the command to notify the supervisor that a new update for the + * MPSoC is available. + */ +class UpdateAvailable: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param imageSelect + * @param imagePartition + * @param imageSize + * @param imageCrc + * @param numberOfPackets + */ + UpdateAvailable(uint8_t imageSelect, uint8_t imagePartition, uint32_t imageSize, + uint32_t imageCrc, uint32_t numberOfPackets) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_UPDATE_AVAILABLE, + DEFAULT_SEQUENCE_COUNT), imageSelect(imageSelect), imagePartition( + imagePartition), imageSize(imageSize), imageCrc(imageCrc), numberOfPackets( + numberOfPackets) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 16; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t imageSelect = 0; + uint8_t imagePartition = 0; + uint32_t imageSize = 0; + uint32_t imageCrc = 0; + uint32_t numberOfPackets = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&imageSelect, &data_field_ptr, &serializedSize, + sizeof(imageSelect), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&imagePartition, &data_field_ptr, &serializedSize, + sizeof(imagePartition), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&imageSize, &data_field_ptr, &serializedSize, + sizeof(imageSize), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&imageCrc, &data_field_ptr, &serializedSize, + sizeof(imageCrc), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&numberOfPackets, &data_field_ptr, &serializedSize, + sizeof(numberOfPackets), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + serializedSize = 0; + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + /** * @brief With this class the space packet can be generated to disable to periodic transmission * of housekeeping data. Normally, this will be disabled by default. However, adding this @@ -407,95 +500,6 @@ public: this); lp_var_t fmcState = lp_var_t(sid.objectId, PoolIds::FMC_STATE, this); }; - -/** - * @brief This dataset stores the boot status report of the supervisor. - */ -class BootStatusReport: public StaticLocalDataSet { -public: - - BootStatusReport(HasLocalDataPoolIF* owner) : - StaticLocalDataSet(owner, BOOT_REPORT_SET_ID) { - } - - BootStatusReport(object_id_t objectId) : - StaticLocalDataSet(sid_t(objectId, BOOT_REPORT_SET_ID)) { - } - - /** Information about boot status of MPSoC */ - lp_var_t bootSignal = lp_var_t(sid.objectId, PoolIds::BOOT_SIGNAL, this); - lp_var_t resetCounter = lp_var_t(sid.objectId, PoolIds::RESET_COUNTER, this); - /** Time the MPSoC needs for last boot */ - lp_var_t bootAfterMs = lp_var_t(sid.objectId, PoolIds::BOOT_AFTER_MS, this); - /** The currently set boot timeout */ - lp_var_t bootTimeoutMs = lp_var_t(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this); - lp_var_t activeNvm = lp_var_t(sid.objectId, PoolIds::ACTIVE_NVM, this); - /** States of the boot partition pins */ - lp_var_t bp0State = lp_var_t(sid.objectId, PoolIds::BP0_STATE, this); - lp_var_t bp1State = lp_var_t(sid.objectId, PoolIds::BP1_STATE, this); - lp_var_t bp2State = lp_var_t(sid.objectId, PoolIds::BP2_STATE, this); -}; } -/** - * @brief This class packages the command to notify the supervisor that a new update for the - * MPSoC is available. - */ -class UpdateAvailable: public SpacePacket { -public: - - /** - * @brief Constructor - * - * @param imageSelect - * @param imagePartition - * @param imageSize - * @param imageCrc - * @param numberOfPackets - */ - UpdateAvailable(uint8_t imageSelect, uint8_t imagePartition, uint32_t imageSize, - uint32_t imageCrc, uint32_t numberOfPackets) : - SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SEL_MPSOC_BOOT_IMAGE, - DEFAULT_SEQUENCE_COUNT), imageSelect(imageSelect), imagePartition( - imagePartition), imageSize(imageSize), imageCrc(imageCrc), numberOfPackets( - numberOfPackets) { - initPacket(); - } - -private: - - static const uint16_t DATA_FIELD_LENGTH = 16; - static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; - - static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; - - uint8_t imageSelect = 0; - uint8_t imagePartition = 0; - uint32_t imageSize = 0; - uint32_t imageCrc = 0; - uint32_t numberOfPackets = 0; - - void initPacket() { - uint8_t offset = 0; - uint8_t* data_field_start = this->localData.fields.buffer; - std::memcpy(data_field_start + offset, &imageSelect, sizeof(imageSelect)); - offset += 1; - std::memcpy(data_field_start + offset, &imagePartition, sizeof(imagePartition)); - offset += 1; - std::memcpy(data_field_start + offset, &imageSize, sizeof(imageSize)); - offset += 4; - std::memcpy(data_field_start + offset, &imageCrc, sizeof(imageCrc)); - offset += 4; - std::memcpy(data_field_start + offset, &numberOfPackets, sizeof(numberOfPackets)); - - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - /* Add crc to packet data field of space packet */ - size_t serializedSize = 0; - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), - SerializeIF::Endianness::BIG); - } -}; - #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ */ -- 2.43.0 From dc73036c7a2f80c86bb36616aa15434e95a682e1 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Mon, 26 Jul 2021 12:24:21 +0200 Subject: [PATCH 024/116] udp server port in UpdTmTcBridge --- bsp_q7s/core/CoreController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index b72bbf62..1285a56b 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -360,7 +360,7 @@ void CoreController::initPrint() { #if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_USE_TMTC_TCP_BRIDGE == 0 sif::info << "Created UDP server for TMTC commanding with listener port " << - TcpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl; + UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl; #else sif::info << "Created TCP server for TMTC commanding with listener port " << TcpTmTcBridge::DEFAULT_TCP_SERVER_PORT << std::endl; -- 2.43.0 From 590d5e11e1e89ceb4185a0e4fa60620ce25809aa Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 13:41:45 +0200 Subject: [PATCH 025/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 6352a6f2..2e942ec2 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6352a6f272b3138257831fcd1f5d9ffcd4902681 +Subproject commit 2e942ec21e47485b9ab6416a0341b9ab8ec30543 -- 2.43.0 From 261fc8b58f746bb64cbb0bff9692240622bf0660 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 13:51:00 +0200 Subject: [PATCH 026/116] moved config flag to cmmon config --- bsp_hosted/InitMission.cpp | 14 +++++++------- bsp_hosted/ObjectFactory.cpp | 21 +++++++++++++++++---- bsp_q7s/core/CoreController.cpp | 4 ++-- common/config/commonConfig.h.in | 4 ++++ fsfw | 2 +- linux/fsfwconfig/OBSWConfig.h.in | 4 ---- 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/bsp_hosted/InitMission.cpp b/bsp_hosted/InitMission.cpp index 8ef40d06..ed6b8820 100644 --- a/bsp_hosted/InitMission.cpp +++ b/bsp_hosted/InitMission.cpp @@ -70,15 +70,15 @@ void initmission::initTasks() { } /* UDP bridge */ - PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); - result = udpBridgeTask->addComponent(objects::TMTC_BRIDGE); + PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask( + "TMTC_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); + result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Unix Bridge failed" << std::endl; } - PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( + PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = udpPollingTask->addComponent(objects::TMTC_POLLING_TASK); + result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Polling failed" << std::endl; } @@ -142,8 +142,8 @@ void initmission::initTasks() { sif::info << "Starting tasks.." << std::endl; tmTcDistributor->startTask(); - udpBridgeTask->startTask(); - udpPollingTask->startTask(); + tmtcBridgeTask->startTask(); + tmtcPollingTask->startTask(); pusVerification->startTask(); pusEvents->startTask(); diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 0933df5b..c5b9ded7 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -1,6 +1,5 @@ #include "ObjectFactory.h" - -#include +#include "OBSWConfig.h" #include #include #include @@ -11,8 +10,13 @@ #include #include -#include -#include +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 +#include "fsfw/osal/common/UdpTcPollingTask.h" +#include "fsfw/osal/common/UdpTmTcBridge.h" +#else +#include "fsfw/osal/common/TcpTmTcBridge.h" +#include "fsfw/osal/common/TcpTmTcServer.h" +#endif #include @@ -40,7 +44,16 @@ void ObjectFactory::produce(void* args){ Factory::setStaticFrameworkObjectIds(); ObjectFactory::produceGenericObjects(); +#if OBSW_USE_TMTC_TCP_BRIDGE == 0 + sif::info << "Setting up UDP TMTC bridge with listener port " << + UdpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); +#else + sif::info << "Setting up TCP TMTC bridge with listener port " << + TcpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; + new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); + new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); +#endif } diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 1285a56b..2351c9be 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -360,10 +360,10 @@ void CoreController::initPrint() { #if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_USE_TMTC_TCP_BRIDGE == 0 sif::info << "Created UDP server for TMTC commanding with listener port " << - UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl; + UdpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; #else sif::info << "Created TCP server for TMTC commanding with listener port " << - TcpTmTcBridge::DEFAULT_TCP_SERVER_PORT << std::endl; + TcpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; #endif #endif } diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index 3d741bcf..eaf68b2d 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -3,4 +3,8 @@ #define OBSW_ADD_LWGPS_TEST 0 +// Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally +// because UDP packets are not allowed in the VPN +#define OBSW_USE_TMTC_TCP_BRIDGE 0 + #endif /* COMMON_CONFIG_COMMONCONFIG_H_ */ diff --git a/fsfw b/fsfw index 1f6a5e63..54c028f9 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 1f6a5e635fcd6bd812e262cc65a15a8a054f7ecf +Subproject commit 54c028f913e81077855aa1ed727bac43e7efea82 diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 7a798717..16eacccf 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -18,10 +18,6 @@ debugging. */ #define OBSW_VERBOSE_LEVEL 1 -// Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally -// because UDP packets are not allowed in the VPN -#define OBSW_USE_TMTC_TCP_BRIDGE 0 - #define OBSW_PRINT_MISSED_DEADLINES 1 #define OBSW_ADD_TEST_CODE 1 #define OBSW_ADD_TEST_PST 1 -- 2.43.0 From 5018b24cfcd08f6ffeb81157475aa9df5570b91a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 13:55:58 +0200 Subject: [PATCH 027/116] storing RTD value now as well --- mission/devices/Max31865PT1000Handler.cpp | 29 ++++++------------- .../devicedefinitions/Max31865Definitions.h | 3 ++ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/mission/devices/Max31865PT1000Handler.cpp b/mission/devices/Max31865PT1000Handler.cpp index 12fd5102..2a779ee7 100644 --- a/mission/devices/Max31865PT1000Handler.cpp +++ b/mission/devices/Max31865PT1000Handler.cpp @@ -1,5 +1,7 @@ #include "Max31865PT1000Handler.h" +#include "fsfw/datapool/PoolReadGuard.h" + #include #include @@ -360,7 +362,6 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply( // do something with rtd value, will propably be stored in // dataset. float rtdValue = adcCode * RTD_RREF_PT1000 / INT16_MAX; - // calculate approximation float approxTemp = adcCode / 32.0 - 256.0; @@ -369,7 +370,7 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply( #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "Max31865PT1000Handler::interpretDeviceReply: Measured " << "resistance is " << rtdValue << " Ohms." << std::endl; - sif::info << "Approximated temperature is " << approxTemp << " °C" + sif::info << "Approximated temperature is " << approxTemp << " C" << std::endl; #else sif::printInfo("Max31865PT1000Handler::interpretDeviceReply: Measured resistance is %f" @@ -380,8 +381,8 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply( } #endif - ReturnValue_t result = sensorDataset.read(); - if(result != HasReturnvaluesIF::RETURN_OK) { + PoolReadGuard pg(&sensorDataset); + if(pg.getReadResult() != HasReturnvaluesIF::RETURN_OK) { // Configuration error #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "Max31865PT1000Handler::interpretDeviceReply: Error reading dataset!" @@ -389,29 +390,17 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply( #else sif::printDebug("Max31865PT1000Handler::interpretDeviceReply: Error reading dataset!\n"); #endif - return result; + return pg.getReadResult(); } if(not sensorDataset.isValid()) { + sensorDataset.setValidity(true, false); + sensorDataset.rtdValue.setValid(true); sensorDataset.temperatureCelcius.setValid(true); } + sensorDataset.rtdValue = rtdValue; sensorDataset.temperatureCelcius = approxTemp; - - result = sensorDataset.commit(); - - if(result != HasReturnvaluesIF::RETURN_OK) { - // Configuration error -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "Max31865PT1000Handler::interpretDeviceReply: " - "Error commiting dataset!" << std::endl; -#else - sif::printDebug("Max31865PT1000Handler::interpretDeviceReply: " - "Error commiting dataset!\n"); -#endif - return result; - } - break; } case(Max31865Definitions::REQUEST_FAULT_BYTE): { diff --git a/mission/devices/devicedefinitions/Max31865Definitions.h b/mission/devices/devicedefinitions/Max31865Definitions.h index 26c702a3..9b2aa3a2 100644 --- a/mission/devices/devicedefinitions/Max31865Definitions.h +++ b/mission/devices/devicedefinitions/Max31865Definitions.h @@ -9,6 +9,7 @@ namespace Max31865Definitions { enum PoolIds: lp_id_t { + RTD_VALUE, TEMPERATURE_C, FAULT_BYTE }; @@ -46,6 +47,8 @@ public: StaticLocalDataSet(sid_t(objectId, MAX31865_SET_ID)) { } + lp_var_t rtdValue = lp_var_t(sid.objectId, + PoolIds::RTD_VALUE, this); lp_var_t temperatureCelcius = lp_var_t(sid.objectId, PoolIds::TEMPERATURE_C, this); lp_var_t errorByte = lp_var_t(sid.objectId, -- 2.43.0 From 96c9069a69053c906b4b70c33ea14aa35db7607f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 13:56:53 +0200 Subject: [PATCH 028/116] new pool entry for rtd value --- mission/devices/Max31865PT1000Handler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mission/devices/Max31865PT1000Handler.cpp b/mission/devices/Max31865PT1000Handler.cpp index 2a779ee7..751d36eb 100644 --- a/mission/devices/Max31865PT1000Handler.cpp +++ b/mission/devices/Max31865PT1000Handler.cpp @@ -474,6 +474,7 @@ void Max31865PT1000Handler::doTransition(Mode_t modeFrom, ReturnValue_t Max31865PT1000Handler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { + localDataPoolMap.emplace(Max31865Definitions::PoolIds::RTD_VALUE, new PoolEntry({0})); localDataPoolMap.emplace(Max31865Definitions::PoolIds::TEMPERATURE_C, new PoolEntry({0}, 1, true)); localDataPoolMap.emplace(Max31865Definitions::PoolIds::FAULT_BYTE, -- 2.43.0 From f7ac3824987a54a0a8b2b3d14fbb6235f4f485da Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 14:00:15 +0200 Subject: [PATCH 029/116] fixes for host build --- bsp_hosted/ObjectFactory.cpp | 2 ++ bsp_hosted/main.cpp | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index c5b9ded7..9ea97fd1 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -56,4 +56,6 @@ void ObjectFactory::produce(void* args){ new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); #endif + new TestTask(objects::TEST_TASK); + } diff --git a/bsp_hosted/main.cpp b/bsp_hosted/main.cpp index 5b43da1e..153cc447 100644 --- a/bsp_hosted/main.cpp +++ b/bsp_hosted/main.cpp @@ -1,9 +1,10 @@ #include "InitMission.h" +#include "OBSWVersion.h" + +#include "fsfw/FSFWVersion.h" +#include "fsfw/tasks/TaskFactory.h" -#include -#include #include - #ifdef WIN32 static const char* COMPILE_PRINTOUT = "Windows"; #elif LINUX @@ -20,8 +21,9 @@ int main(void) { std::cout << "-- EIVE OBSW --" << std::endl; std::cout << "-- Compiled for " << COMPILE_PRINTOUT << " --" << std::endl; - std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "." - << SW_SUBVERSION << "." << SW_REVISION << " -- " << std::endl; + std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << + "." << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "." << + FSFW_REVISION << "--" << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; initmission::initMission(); -- 2.43.0 From 292bfaad16f418e0863f361af3cb104e48f0c8b4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 14:23:22 +0200 Subject: [PATCH 030/116] readme extended --- README.md | 6 ++++++ common/config/commonConfig.h.in | 2 +- tmtc | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc218749..a174fbf1 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,12 @@ tmux new -s q7s-serial q7s_serial ``` +Other useful tmux commands: +- Enable scroll mode: You can press `ctrl + b` and then `[` (`AltGr + 8`) to enable scroll mode. + You can quit scroll mode with `q`. +- Kill a tmux session: run `ctrl + b` and then `k`. +- Detach from a tmux session: run `ctrl + b` and then `d` + ### SSH console You can use the following command to connect to the Q7S with `ssh`: diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index eaf68b2d..2b0590c8 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -1,7 +1,7 @@ #ifndef COMMON_CONFIG_COMMONCONFIG_H_ #define COMMON_CONFIG_COMMONCONFIG_H_ -#define OBSW_ADD_LWGPS_TEST 0 +#define OBSW_ADD_LWGPS_TEST 0 // Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally // because UDP packets are not allowed in the VPN diff --git a/tmtc b/tmtc index 2e942ec2..6758ecef 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 2e942ec21e47485b9ab6416a0341b9ab8ec30543 +Subproject commit 6758ecef0d59d6918a7d91e6a6e01f57edb23151 -- 2.43.0 From 6506baa7b61ba2697f4d2137978be67632020c6d Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Mon, 26 Jul 2021 16:30:20 +0200 Subject: [PATCH 031/116] ploc supervisor watchdogs enable command --- mission/devices/PlocSupervisorHandler.cpp | 23 ++++ mission/devices/PlocSupervisorHandler.h | 7 +- .../PlocSupervisorDefinitions.h | 108 +++++++++++++----- tmtc | 2 +- 4 files changed, 109 insertions(+), 31 deletions(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 5af3693b..e573222c 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -115,6 +115,11 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( prepareUpdateAvailableCmd(commandData); result = RETURN_OK; break; + } + case(PLOC_SPV::WATCHDOGS_ENABLE): { + prepareWatchdogsEnableCmd(commandData); + result = RETURN_OK; + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -145,6 +150,8 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::SET_TIME_REF); this->insertInCommandMap(PLOC_SPV::DISABLE_PERIOIC_HK_TRANSMISSION); this->insertInCommandMap(PLOC_SPV::GET_BOOT_STATUS_REPORT); + this->insertInCommandMap(PLOC_SPV::UPDATE_AVAILABLE); + this->insertInCommandMap(PLOC_SPV::WATCHDOGS_ENABLE); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -530,6 +537,8 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite case PLOC_SPV::SET_MAX_RESTART_TRIES: case PLOC_SPV::RESET_MPSOC: case PLOC_SPV::SET_TIME_REF: + case PLOC_SPV::UPDATE_AVAILABLE: + case PLOC_SPV::WATCHDOGS_ENABLE: enabledReplies = 2; break; default: @@ -705,6 +714,20 @@ void PlocSupervisorHandler::prepareUpdateAvailableCmd(const uint8_t * commandDat nextReplyId = PLOC_SPV::ACK_REPORT; } +void PlocSupervisorHandler::prepareWatchdogsEnableCmd(const uint8_t * commandData) { + uint8_t offset = 0; + uint8_t watchdogPs = *(commandData + offset); + offset += 1; + uint8_t watchdogPl = *(commandData + offset); + offset += 1; + uint8_t watchdogInt = *(commandData + offset); + PLOC_SPV::WatchdogsEnable packet(watchdogPs, watchdogPl, watchdogInt); + memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); + rawPacket = commandBuffer; + rawPacketLen = packet.getFullSize(); + nextReplyId = PLOC_SPV::ACK_REPORT; +} + void PlocSupervisorHandler::disableAllReplies() { DeviceReplyMap::iterator iter; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index d4ad811c..927af9ee 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -172,7 +172,6 @@ private: */ void prepareEmptyCmd(uint16_t apid); - /** * @brief This function initializes the space packet to select the boot image of the MPSoC. */ @@ -200,6 +199,12 @@ private: */ void prepareUpdateAvailableCmd(const uint8_t * commandData); + /** + * @brief This function fills the command buffer with the packet to enable or disable the + * watchdogs on the PLOC. + */ + void prepareWatchdogsEnableCmd(const uint8_t * commandData); + /** * @brief In case an acknowledgment failure reply has been received this function disables * all previously enabled commands and resets the exepected replies variable of an diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 87153978..21580a0f 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -23,6 +23,7 @@ static const DeviceCommandId_t DISABLE_PERIOIC_HK_TRANSMISSION = 10; static const DeviceCommandId_t GET_BOOT_STATUS_REPORT = 11; /** Notifies the supervisor that a new update is available for the MPSoC */ static const DeviceCommandId_t UPDATE_AVAILABLE = 12; +static const DeviceCommandId_t WATCHDOGS_ENABLE = 13; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; @@ -342,34 +343,6 @@ private: } }; -/** - * @brief This dataset stores the boot status report of the supervisor. - */ -class BootStatusReport: public StaticLocalDataSet { -public: - - BootStatusReport(HasLocalDataPoolIF* owner) : - StaticLocalDataSet(owner, BOOT_REPORT_SET_ID) { - } - - BootStatusReport(object_id_t objectId) : - StaticLocalDataSet(sid_t(objectId, BOOT_REPORT_SET_ID)) { - } - - /** Information about boot status of MPSoC */ - lp_var_t bootSignal = lp_var_t(sid.objectId, PoolIds::BOOT_SIGNAL, this); - lp_var_t resetCounter = lp_var_t(sid.objectId, PoolIds::RESET_COUNTER, this); - /** Time the MPSoC needs for last boot */ - lp_var_t bootAfterMs = lp_var_t(sid.objectId, PoolIds::BOOT_AFTER_MS, this); - /** The currently set boot timeout */ - lp_var_t bootTimeoutMs = lp_var_t(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this); - lp_var_t activeNvm = lp_var_t(sid.objectId, PoolIds::ACTIVE_NVM, this); - /** States of the boot partition pins */ - lp_var_t bp0State = lp_var_t(sid.objectId, PoolIds::BP0_STATE, this); - lp_var_t bp1State = lp_var_t(sid.objectId, PoolIds::BP1_STATE, this); - lp_var_t bp2State = lp_var_t(sid.objectId, PoolIds::BP2_STATE, this); -}; - /** * @brief This class packages the command to notify the supervisor that a new update for the * MPSoC is available. @@ -428,7 +401,6 @@ private: serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); - serializedSize = 0; uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); @@ -470,6 +442,84 @@ private: } }; +/** + * @brief This class packages the command to enable the watchdogs of the PLOC. + */ +class WatchdogsEnable: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param watchdogPs Enables processing system watchdog + * @param watchdogPl Enables programmable logic wathdog + * @param watchdogInt + */ + WatchdogsEnable(uint8_t watchdogPs, uint8_t watchdogPl, uint8_t watchdogInt) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_WTD_ENABLE, DEFAULT_SEQUENCE_COUNT), + watchdogPs(watchdogPs), watchdogPl(watchdogPl), watchdogInt(watchdogInt) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 5; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t watchdogPs = 0; + uint8_t watchdogPl = 0; + uint8_t watchdogInt = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&watchdogPs, &data_field_ptr, &serializedSize, + sizeof(watchdogPs), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&watchdogPl, &data_field_ptr, &serializedSize, + sizeof(watchdogPl), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&watchdogInt, &data_field_ptr, &serializedSize, + sizeof(watchdogInt), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This dataset stores the boot status report of the supervisor. + */ +class BootStatusReport: public StaticLocalDataSet { +public: + + BootStatusReport(HasLocalDataPoolIF* owner) : + StaticLocalDataSet(owner, BOOT_REPORT_SET_ID) { + } + + BootStatusReport(object_id_t objectId) : + StaticLocalDataSet(sid_t(objectId, BOOT_REPORT_SET_ID)) { + } + + /** Information about boot status of MPSoC */ + lp_var_t bootSignal = lp_var_t(sid.objectId, PoolIds::BOOT_SIGNAL, this); + lp_var_t resetCounter = lp_var_t(sid.objectId, PoolIds::RESET_COUNTER, this); + /** Time the MPSoC needs for last boot */ + lp_var_t bootAfterMs = lp_var_t(sid.objectId, PoolIds::BOOT_AFTER_MS, this); + /** The currently set boot timeout */ + lp_var_t bootTimeoutMs = lp_var_t(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this); + lp_var_t activeNvm = lp_var_t(sid.objectId, PoolIds::ACTIVE_NVM, this); + /** States of the boot partition pins */ + lp_var_t bp0State = lp_var_t(sid.objectId, PoolIds::BP0_STATE, this); + lp_var_t bp1State = lp_var_t(sid.objectId, PoolIds::BP1_STATE, this); + lp_var_t bp2State = lp_var_t(sid.objectId, PoolIds::BP2_STATE, this); +}; + /** * @brief This dataset stores the housekeeping data of the supervisor. */ diff --git a/tmtc b/tmtc index 6352a6f2..75ae2c78 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6352a6f272b3138257831fcd1f5d9ffcd4902681 +Subproject commit 75ae2c786b2422ea1986ce69bdcd528346e88f1a -- 2.43.0 From 2a5cc62af7a424af36eb568dad776ae77884210f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 17:25:11 +0200 Subject: [PATCH 032/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 6758ecef..a81b8b60 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6758ecef0d59d6918a7d91e6a6e01f57edb23151 +Subproject commit a81b8b608df8f991540bc26748f0b86507ed76ef -- 2.43.0 From 0abc854567b6bdc4745e8e9e9f3e18c1dfbb8d15 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 17:29:59 +0200 Subject: [PATCH 033/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index a81b8b60..9aaf3cfa 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit a81b8b608df8f991540bc26748f0b86507ed76ef +Subproject commit 9aaf3cfa7a9bcd0bfbdb28d1fd92de151f1e6987 -- 2.43.0 From 6625d562e93056f6da1e600ef77d7199f72309d1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 17:55:45 +0200 Subject: [PATCH 034/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 9aaf3cfa..2a6c0a6c 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 9aaf3cfa7a9bcd0bfbdb28d1fd92de151f1e6987 +Subproject commit 2a6c0a6cab9be37a80e17ed98e300c8743dd4dd3 -- 2.43.0 From 3824daa865c4208e4ea9f8dcc98c9a7b079f5886 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 26 Jul 2021 18:00:14 +0200 Subject: [PATCH 035/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 2a6c0a6c..1f990e96 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 2a6c0a6cab9be37a80e17ed98e300c8743dd4dd3 +Subproject commit 1f990e9647e3f513cf1b3073e94774d530645073 -- 2.43.0 From bd9dbc5fc810181d78ec1f85c59f2132084ec507 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Mon, 26 Jul 2021 19:56:00 +0200 Subject: [PATCH 036/116] ploc supervisor watchdog configure timeout command --- bsp_q7s/core/ObjectFactory.cpp | 4 +- mission/devices/PlocSupervisorHandler.cpp | 26 ++++++++++ mission/devices/PlocSupervisorHandler.h | 10 ++++ .../PlocSupervisorDefinitions.h | 47 +++++++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 53da02c5..536d4fe8 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -802,7 +802,7 @@ void ObjectFactory::createTestComponents() { radSensor->setStartUpImmediately(); #endif -#if BOARD_TE0720 == 1 && TEST_PLOC_HANDLER == 1 +#if BOARD_TE0720 == 1 && ADD_PLOC_MPSOC == 1 UartCookie* plocUartCookie = new UartCookie(std::string("/dev/ttyPS1"), 115200, PLOC_MPSOC::MAX_REPLY_SIZE); /* Testing PlocMPSoCHandler on TE0720-03-1CFA */ @@ -820,7 +820,7 @@ void ObjectFactory::createTestComponents() { pcduSwitches::TCS_BOARD_8V_HEATER_IN); #endif -#if TE0720 == 1 && ADD_PLOC_SUPERVISOR == 1 +#if BOARD_TE0720 == 1 && ADD_PLOC_SUPERVISOR == 1 /* Configuration for MIO0 on TE0720-03-1CFA */ UartCookie* plocSupervisorCookie = new UartCookie(objects::PLOC_SUPERVISOR_HANDLER, std::string("/dev/ttyPS1"), UartModes::NON_CANONICAL, 115200, diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index e573222c..909e4891 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -120,6 +120,10 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( prepareWatchdogsEnableCmd(commandData); result = RETURN_OK; break; + } + case(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT): { + result = prepareWatchdogsConfigTimeoutCmd(commandData); + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -152,6 +156,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::GET_BOOT_STATUS_REPORT); this->insertInCommandMap(PLOC_SPV::UPDATE_AVAILABLE); this->insertInCommandMap(PLOC_SPV::WATCHDOGS_ENABLE); + this->insertInCommandMap(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -539,6 +544,7 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite case PLOC_SPV::SET_TIME_REF: case PLOC_SPV::UPDATE_AVAILABLE: case PLOC_SPV::WATCHDOGS_ENABLE: + case PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT: enabledReplies = 2; break; default: @@ -728,6 +734,26 @@ void PlocSupervisorHandler::prepareWatchdogsEnableCmd(const uint8_t * commandDat nextReplyId = PLOC_SPV::ACK_REPORT; } +ReturnValue_t PlocSupervisorHandler::prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData) { + uint8_t offset = 0; + uint8_t watchdog = *(commandData + offset); + offset += 1; + if (watchdog > 2) { + return INVALID_WATCHDOG; + } + uint32_t timeout = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 + | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); + if (timeout < 1000 || timeout > 360000) { + return INVALID_WATCHDOG_TIMEOUT; + } + PLOC_SPV::WatchdogsConfigTimeout packet(watchdog, timeout); + memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); + rawPacket = commandBuffer; + rawPacketLen = packet.getFullSize(); + nextReplyId = PLOC_SPV::ACK_REPORT; + return RETURN_OK; +} + void PlocSupervisorHandler::disableAllReplies() { DeviceReplyMap::iterator iter; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index 927af9ee..3136a5df 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -63,6 +63,10 @@ private: static const ReturnValue_t GET_TIME_FAILURE = MAKE_RETURN_CODE(0xA4); //! [EXPORT] : [COMMENT] Invalid communication interface specified static const ReturnValue_t INVALID_UART_COM_IF = MAKE_RETURN_CODE(0xA5); + //! [EXPORT] : [COMMENT] Received command with invalid watchdog parameter. Valid watchdogs are 0 for PS, 1 for PL and 2 for INT + static const ReturnValue_t INVALID_WATCHDOG = MAKE_RETURN_CODE(0xA6); + //! [EXPORT] : [COMMENT] Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms. + static const ReturnValue_t INVALID_WATCHDOG_TIMEOUT = MAKE_RETURN_CODE(0xA6); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; @@ -205,6 +209,12 @@ private: */ void prepareWatchdogsEnableCmd(const uint8_t * commandData); + /** + * @brief This function fills the command buffer with the packet to set the watchdog timer + * of one of the three watchdogs (PS, PL, INT). + */ + ReturnValue_t prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData); + /** * @brief In case an acknowledgment failure reply has been received this function disables * all previously enabled commands and resets the exepected replies variable of an diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 21580a0f..5cfd026e 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -24,6 +24,7 @@ static const DeviceCommandId_t GET_BOOT_STATUS_REPORT = 11; /** Notifies the supervisor that a new update is available for the MPSoC */ static const DeviceCommandId_t UPDATE_AVAILABLE = 12; static const DeviceCommandId_t WATCHDOGS_ENABLE = 13; +static const DeviceCommandId_t WATCHDOGS_CONFIG_TIMEOUT = 14; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; @@ -492,6 +493,52 @@ private: } }; +/** + * @brief This class packages the command to set the timeout of one of the three watchdogs (PS, + * PL, INT) + */ +class WatchdogsConfigTimeout: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param watchdogPs Selects the watchdog to configure (0 - PS, 1 - PL, 2 - INT) + * @param timeout The timeout to set + */ + WatchdogsConfigTimeout(uint8_t watchdog, uint32_t timeout) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_WTD_CONFIG_TIMEOUT, + DEFAULT_SEQUENCE_COUNT), watchdog(watchdog), timeout(timeout) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 7; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t watchdog = 0; + uint32_t timeout = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&watchdog, &data_field_ptr, &serializedSize, + sizeof(watchdog), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&timeout, &data_field_ptr, &serializedSize, + sizeof(timeout), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + /** * @brief This dataset stores the boot status report of the supervisor. */ -- 2.43.0 From 03a601d450c4eefa5adfd8d16e76b020c129809b Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Tue, 27 Jul 2021 12:02:30 +0200 Subject: [PATCH 037/116] auto calibrate alert and enable/disable latchup alert --- mission/devices/PlocSupervisorHandler.cpp | 112 ++++++++++------ mission/devices/PlocSupervisorHandler.h | 12 ++ .../PlocSupervisorDefinitions.h | 122 ++++++++++++++++++ 3 files changed, 210 insertions(+), 36 deletions(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 909e4891..4dcb2a16 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -124,6 +124,18 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( case(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT): { result = prepareWatchdogsConfigTimeoutCmd(commandData); break; + } + case(PLOC_SPV::ENABLE_LATCHUP_ALERT): { + result = prepareLatchupConfigCmd(commandData, deviceCommand); + break; + } + case(PLOC_SPV::DISABLE_LATCHUP_ALERT): { + result = prepareLatchupConfigCmd(commandData, deviceCommand); + break; + } + case(PLOC_SPV::AUTO_CALIBRATE_ALERT): { + result = prepareAutoCalibrateAlertCmd(commandData); + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -157,6 +169,9 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::UPDATE_AVAILABLE); this->insertInCommandMap(PLOC_SPV::WATCHDOGS_ENABLE); this->insertInCommandMap(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT); + this->insertInCommandMap(PLOC_SPV::ENABLE_LATCHUP_ALERT); + this->insertInCommandMap(PLOC_SPV::DISABLE_LATCHUP_ALERT); + this->insertInCommandMap(PLOC_SPV::APID_AUTO_CALIBRATE_ALERT); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -545,6 +560,9 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite case PLOC_SPV::UPDATE_AVAILABLE: case PLOC_SPV::WATCHDOGS_ENABLE: case PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT: + case PLOC_SPV::ENABLE_LATCHUP_ALERT: + case PLOC_SPV::DISABLE_LATCHUP_ALERT: + case PLOC_SPV::AUTO_CALIBRATE_ALERT: enabledReplies = 2; break; default: @@ -639,19 +657,13 @@ void PlocSupervisorHandler::handleDeviceTM(const uint8_t* data, size_t dataSize, void PlocSupervisorHandler::prepareEmptyCmd(uint16_t apid) { PLOC_SPV::EmptyPacket packet(apid); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareSelBootImageCmd(const uint8_t * commandData) { PLOC_SPV::MPSoCBootSelect packet(*commandData, *(commandData + 1), *(commandData + 2), *(commandData + 3)); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } ReturnValue_t PlocSupervisorHandler::prepareSetTimeRefCmd() { @@ -663,38 +675,26 @@ ReturnValue_t PlocSupervisorHandler::prepareSetTimeRefCmd() { return GET_TIME_FAILURE; } PLOC_SPV::SetTimeRef packet(&time); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); return RETURN_OK; } void PlocSupervisorHandler::prepareDisableHk() { PLOC_SPV::DisablePeriodicHkTransmission packet; - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareSetBootTimeoutCmd(const uint8_t * commandData) { uint32_t timeout = *(commandData) << 24 | *(commandData + 1) << 16 | *(commandData + 2) << 8 | *(commandData + 3); PLOC_SPV::SetBootTimeout packet(timeout); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareRestartTriesCmd(const uint8_t * commandData) { uint8_t restartTries = *(commandData); PLOC_SPV::SetRestartTries packet(restartTries); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareUpdateAvailableCmd(const uint8_t * commandData) { @@ -714,10 +714,7 @@ void PlocSupervisorHandler::prepareUpdateAvailableCmd(const uint8_t * commandDat PLOC_SPV::UpdateAvailable packet(imageSelect, imagePartition, imageSize, imageCrc, numberOfPackets); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } void PlocSupervisorHandler::prepareWatchdogsEnableCmd(const uint8_t * commandData) { @@ -728,10 +725,7 @@ void PlocSupervisorHandler::prepareWatchdogsEnableCmd(const uint8_t * commandDat offset += 1; uint8_t watchdogInt = *(commandData + offset); PLOC_SPV::WatchdogsEnable packet(watchdogPs, watchdogPl, watchdogInt); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } ReturnValue_t PlocSupervisorHandler::prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData) { @@ -747,13 +741,59 @@ ReturnValue_t PlocSupervisorHandler::prepareWatchdogsConfigTimeoutCmd(const uint return INVALID_WATCHDOG_TIMEOUT; } PLOC_SPV::WatchdogsConfigTimeout packet(watchdog, timeout); - memcpy(commandBuffer, packet.getWholeData(), packet.getFullSize()); - rawPacket = commandBuffer; - rawPacketLen = packet.getFullSize(); - nextReplyId = PLOC_SPV::ACK_REPORT; + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); return RETURN_OK; } +ReturnValue_t PlocSupervisorHandler::prepareLatchupConfigCmd(const uint8_t* commandData, + DeviceCommandId_t deviceCommand) { + ReturnValue_t result = RETURN_OK; + uint8_t latchupId = *commandData; + if (latchupId > 6) { + return INVALID_LATCHUP_ID; + } + switch (deviceCommand) { + case (PLOC_SPV::ENABLE_LATCHUP_ALERT): { + PLOC_SPV::LatchupAlert packet(true, latchupId); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + break; + } + case (PLOC_SPV::DISABLE_LATCHUP_ALERT): { + PLOC_SPV::LatchupAlert packet(false, latchupId); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + break; + } + default: { + sif::debug << "PlocSupervisorHandler::prepareLatchupConfigCmd: Invalid command id" + << std::endl; + result = RETURN_FAILED; + break; + } + } + return result; +} + +ReturnValue_t PlocSupervisorHandler::prepareAutoCalibrateAlertCmd(const uint8_t* commandData) { + uint8_t offset = 0; + uint8_t latchupId = *commandData; + offset += 1; + uint32_t mg = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 + | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); + if (latchupId > 6) { + return INVALID_LATCHUP_ID; + } + PLOC_SPV::AutoCalibrateAlert packet(latchupId, mg); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + return RETURN_OK; +} + +void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { + memcpy(commandBuffer, packetData, fullSize); + rawPacket = commandBuffer; + rawPacketLen = fullSize; + nextReplyId = PLOC_SPV::ACK_REPORT; +} + void PlocSupervisorHandler::disableAllReplies() { DeviceReplyMap::iterator iter; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index 3136a5df..bbbbf25e 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -67,6 +67,8 @@ private: static const ReturnValue_t INVALID_WATCHDOG = MAKE_RETURN_CODE(0xA6); //! [EXPORT] : [COMMENT] Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms. static const ReturnValue_t INVALID_WATCHDOG_TIMEOUT = MAKE_RETURN_CODE(0xA6); + //! [EXPORT] : [COMMENT] Received latchup config command with invalid latchup ID + static const ReturnValue_t INVALID_LATCHUP_ID = MAKE_RETURN_CODE(0xA7); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; @@ -215,6 +217,16 @@ private: */ ReturnValue_t prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData); + ReturnValue_t prepareLatchupConfigCmd(const uint8_t* commandData, + DeviceCommandId_t deviceCommand); + ReturnValue_t prepareAutoCalibrateAlertCmd(const uint8_t* commandData); + + + /** + * @brief Copies the content of a space packet to the command buffer. + */ + void packetToOutBuffer(uint8_t* packetData, size_t fullSize); + /** * @brief In case an acknowledgment failure reply has been received this function disables * all previously enabled commands and resets the exepected replies variable of an diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 5cfd026e..28349dab 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -25,6 +25,9 @@ static const DeviceCommandId_t GET_BOOT_STATUS_REPORT = 11; static const DeviceCommandId_t UPDATE_AVAILABLE = 12; static const DeviceCommandId_t WATCHDOGS_ENABLE = 13; static const DeviceCommandId_t WATCHDOGS_CONFIG_TIMEOUT = 14; +static const DeviceCommandId_t ENABLE_LATCHUP_ALERT = 15; +static const DeviceCommandId_t DISABLE_LATCHUP_ALERT = 16; +static const DeviceCommandId_t AUTO_CALIBRATE_ALERT = 17; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; @@ -73,6 +76,30 @@ static const uint16_t APID_WTD_ENABLE = 0xC0; static const uint16_t APID_WTD_CONFIG_TIMEOUT = 0xC1; static const uint16_t APID_SET_TIME_REF = 0xC2; static const uint16_t APID_DISABLE_HK = 0xC3; +static const uint16_t APID_ENABLE_LATCHUP_ALERT = 0xD0; +static const uint16_t APID_DISABLE_LATCHUP_ALERT = 0xD1; +static const uint16_t APID_AUTO_CALIBRATE_ALERT = 0xD2; +static const uint16_t APID_SET_ALERT_LIMIT = 0xD3; +static const uint16_t APID_SET_ALERT_IRQ_FILTER = 0xD4; +static const uint16_t APID_SET_ADC_SWEEP_PERIOD = 0xD5; +static const uint16_t APID_SET_ADC_ENABLED_CHANNELS = 0xD6; +static const uint16_t APID_SET_ADC_WINDOW_AND_STRIDE = 0xD7; +static const uint16_t APID_SET_ADC_THRESHOLD = 0xD8; +static const uint16_t APID_GET_LATCHUP_STATUS_REPORT = 0xD9; +static const uint16_t APID_COPY_ADC_DATA_TO_MRAM = 0xDA; +static const uint16_t APID_ENABLE_NVMS = 0xF0; +static const uint16_t APID_SELECT_NVM = 0xF1; +static const uint16_t APID_RUN_AUTO_EM_TESTS = 0xF2; +static const uint16_t APID_WIPE_MRAM = 0xF3; +static const uint16_t APID_DUMP_MRAM = 0xF4; +static const uint16_t APID_SET_DBG_VERBOSITY = 0xF5; +static const uint16_t APID_CAN_LOOPBACK_TEST = 0xF6; +static const uint16_t APID_PRINT_CPU_STATS = 0xF8; +static const uint16_t APID_SET_GPIO = 0xF9; +static const uint16_t APID_READ_GPIO = 0xFA; +static const uint16_t APID_RESTART_SUPERVISOR = 0xFB; +static const uint16_t APID_FACTORY_RESET = 0xFC; +static const uint16_t APID_REQUEST_LOGGING_DATA = 0xFD; static const uint16_t APID_GET_HK_REPORT = 0xC6; @@ -539,6 +566,101 @@ private: } }; +/** + * @brief This class packages the command to enable of disable the latchup alert. + * + * @details There are 7 different latchup alerts. + */ +class LatchupAlert: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param state true - enable, false - disable + * @param latchupId Identifies the latchup to enable/disable (0 - 0.85V, 1 - 1.8V, 2 - MISC, + * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) + */ + LatchupAlert(bool state, uint8_t latchupId) : + SpacePacket(DATA_FIELD_LENGTH - 1, true), latchupId(latchupId) { + if (state) { + this->setAPID(APID_ENABLE_LATCHUP_ALERT); + } else { + this->setAPID(APID_DISABLE_LATCHUP_ALERT); + } + this->setPacketSequenceCount(DEFAULT_SEQUENCE_COUNT); + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 3; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t latchupId = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, + sizeof(latchupId), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the command to calibrate a certain latchup alert. + */ +class AutoCalibrateAlert: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param latchupId Identifies the latchup alert to calibrate (0 - 0.85V, 1 - 1.8V, 2 - MISC, + * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) + * @param mg + */ + AutoCalibrateAlert(uint8_t latchupId, uint32_t mg) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_AUTO_CALIBRATE_ALERT, + DEFAULT_SEQUENCE_COUNT), latchupId(latchupId), mg(mg) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 7; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t latchupId = 0; + uint32_t mg = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, + sizeof(latchupId), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&mg, &data_field_ptr, &serializedSize, + sizeof(mg), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + /** * @brief This dataset stores the boot status report of the supervisor. */ -- 2.43.0 From 14cd3e9eea4274fcf7146ed8aa1c64dd5c58d0a3 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Wed, 28 Jul 2021 08:38:36 +0200 Subject: [PATCH 038/116] supervisor handler get latchup status report --- mission/devices/PlocSupervisorHandler.cpp | 369 +++++++++++++++--- mission/devices/PlocSupervisorHandler.h | 19 +- .../PlocSupervisorDefinitions.h | 337 +++++++++++++++- 3 files changed, 655 insertions(+), 70 deletions(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 4dcb2a16..367cc642 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -5,8 +5,10 @@ #include #include -PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF * comCookie) : - DeviceHandlerBase(objectId, uartComIFid, comCookie), hkset(this), bootStatusReport(this) { +PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, + CookieIF * comCookie) : + DeviceHandlerBase(objectId, uartComIFid, comCookie), hkset(this), bootStatusReport(this), latchupStatusReport( + this) { if (comCookie == NULL) { sif::error << "PlocSupervisorHandler: Invalid com cookie" << std::endl; } @@ -136,6 +138,38 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( case(PLOC_SPV::AUTO_CALIBRATE_ALERT): { result = prepareAutoCalibrateAlertCmd(commandData); break; + } + case(PLOC_SPV::SET_ALERT_LIMIT): { + result = prepareSetAlertLimitCmd(commandData); + break; + } + case(PLOC_SPV::SET_ALERT_IRQ_FILTER): { + result = prepareSetAlertIrqFilterCmd(commandData); + break; + } + case(PLOC_SPV::SET_ADC_SWEEP_PERIOD): { + result = prepareSetAdcSweetPeriodCmd(commandData); + break; + } + case(PLOC_SPV::SET_ADC_ENABLED_CHANNELS): { + prepareSetAdcEnabledChannelsCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::SET_ADC_WINDOW_AND_STRIDE): { + prepareSetAdcWindowAndStrideCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::SET_ADC_THRESHOLD): { + prepareSetAdcThresholdCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::GET_LATCHUP_STATUS_REPORT): { + prepareEmptyCmd(PLOC_SPV::APID_GET_LATCHUP_STATUS_REPORT); + result = RETURN_OK; + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -171,12 +205,21 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT); this->insertInCommandMap(PLOC_SPV::ENABLE_LATCHUP_ALERT); this->insertInCommandMap(PLOC_SPV::DISABLE_LATCHUP_ALERT); - this->insertInCommandMap(PLOC_SPV::APID_AUTO_CALIBRATE_ALERT); + this->insertInCommandMap(PLOC_SPV::AUTO_CALIBRATE_ALERT); + this->insertInCommandMap(PLOC_SPV::SET_ALERT_LIMIT); + this->insertInCommandMap(PLOC_SPV::SET_ALERT_IRQ_FILTER); + this->insertInCommandMap(PLOC_SPV::SET_ADC_SWEEP_PERIOD); + this->insertInCommandMap(PLOC_SPV::SET_ADC_ENABLED_CHANNELS); + this->insertInCommandMap(PLOC_SPV::SET_ADC_WINDOW_AND_STRIDE); + this->insertInCommandMap(PLOC_SPV::SET_ADC_THRESHOLD); + this->insertInCommandMap(PLOC_SPV::GET_LATCHUP_STATUS_REPORT); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); this->insertInReplyMap(PLOC_SPV::BOOT_STATUS_REPORT, 3, &bootStatusReport, PLOC_SPV::SIZE_BOOT_STATUS_REPORT); + this->insertInReplyMap(PLOC_SPV::LATCHUP_REPORT, 3, &latchupStatusReport, + PLOC_SPV::SIZE_LATCHUP_STATUS_REPORT); } ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t *start, @@ -285,9 +328,126 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool localDataPoolMap.emplace(PLOC_SPV::BP1_STATE, new PoolEntry( { 0 })); localDataPoolMap.emplace(PLOC_SPV::BP2_STATE, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::LATCHUP_ID, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::CNT0, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::CNT1, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::CNT2, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::CNT3, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::CNT4, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::CNT5, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::CNT6, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_SEC, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_MIN, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_HOUR, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_DAY, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_MON, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_YEAR, new PoolEntry( { 0 })); + localDataPoolMap.emplace(PLOC_SPV::LATCHUP_RPT_TIME_MSEC, new PoolEntry( { 0 })); + return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command, + uint8_t expectedReplies, bool useAlternateId, + DeviceCommandId_t alternateReplyID) { + + ReturnValue_t result = RETURN_OK; + + uint8_t enabledReplies = 0; + + switch (command->first) { + case PLOC_SPV::GET_HK_REPORT: { + enabledReplies = 3; + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC_SPV::HK_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " + << PLOC_SPV::HK_REPORT << " not in replyMap" << std::endl; + } + break; + } + case PLOC_SPV::GET_BOOT_STATUS_REPORT: { + enabledReplies = 3; + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC_SPV::BOOT_STATUS_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " + << PLOC_SPV::BOOT_STATUS_REPORT << " not in replyMap" << std::endl; + } + break; + } + case PLOC_SPV::GET_LATCHUP_STATUS_REPORT: { + enabledReplies = 3; + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC_SPV::LATCHUP_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " + << PLOC_SPV::LATCHUP_REPORT << " not in replyMap" << std::endl; + } + break; + } + case PLOC_SPV::RESTART_MPSOC: + case PLOC_SPV::START_MPSOC: + case PLOC_SPV::SHUTDOWN_MPSOC: + case PLOC_SPV::SEL_MPSOC_BOOT_IMAGE: + case PLOC_SPV::SET_BOOT_TIMEOUT: + case PLOC_SPV::SET_MAX_RESTART_TRIES: + case PLOC_SPV::RESET_MPSOC: + case PLOC_SPV::SET_TIME_REF: + case PLOC_SPV::UPDATE_AVAILABLE: + case PLOC_SPV::WATCHDOGS_ENABLE: + case PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT: + case PLOC_SPV::ENABLE_LATCHUP_ALERT: + case PLOC_SPV::DISABLE_LATCHUP_ALERT: + case PLOC_SPV::AUTO_CALIBRATE_ALERT: + case PLOC_SPV::SET_ALERT_LIMIT: + case PLOC_SPV::SET_ALERT_IRQ_FILTER: + case PLOC_SPV::SET_ADC_SWEEP_PERIOD: + case PLOC_SPV::SET_ADC_ENABLED_CHANNELS: + case PLOC_SPV::SET_ADC_WINDOW_AND_STRIDE: + case PLOC_SPV::SET_ADC_THRESHOLD: + case PLOC_SPV::COPY_ADC_DATA_TO_MRAM: + case PLOC_SPV::ENABLE_NVMS: + case PLOC_SPV::SELECT_NVM: + case PLOC_SPV::RUN_AUTO_EM_TESTS: + case PLOC_SPV::WIPE_MRAM: + case PLOC_SPV::DUMP_MRAM: + case PLOC_SPV::SET_DBG_VERBOSITY: + case PLOC_SPV::CAN_LOOPBACK_TEST: + case PLOC_SPV::PRINT_CPU_STATS: + case PLOC_SPV::SET_GPIO: + case PLOC_SPV::READ_GPIO: + case PLOC_SPV::RESTART_SUPERVISOR: + case PLOC_SPV::FACTORY_RESET: + case PLOC_SPV::REQUEST_LOGGING_DATA: + enabledReplies = 2; + break; + default: + sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Unknown command id" << std::endl; + break; + } + + /** + * Every command causes at least one acknowledgment and one execution report. Therefore both + * replies will be enabled here. + */ + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC_SPV::ACK_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " + << PLOC_SPV::ACK_REPORT << " not in replyMap" << std::endl; + } + + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC_SPV::EXE_REPORT); + if (result != RETURN_OK) { + sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " + << PLOC_SPV::EXE_REPORT << " not in replyMap" << std::endl; + } + + return RETURN_OK; +} + ReturnValue_t PlocSupervisorHandler::verifyPacket(const uint8_t* start, size_t foundLen) { uint16_t receivedCrc = *(start + foundLen - 2) << 8 | *(start + foundLen - 1); @@ -520,75 +680,93 @@ ReturnValue_t PlocSupervisorHandler::handleBootStatusReport(const uint8_t* data) return result; } -ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command, - uint8_t expectedReplies, bool useAlternateId, - DeviceCommandId_t alternateReplyID) { +ReturnValue_t PlocSupervisorHandler::handleLatchupStatusReport(const uint8_t* data) { ReturnValue_t result = RETURN_OK; - uint8_t enabledReplies = 0; + result = verifyPacket(data, PLOC_SPV::SIZE_BOOT_STATUS_REPORT); - switch (command->first) { - case PLOC_SPV::GET_HK_REPORT: { - enabledReplies = 3; - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::HK_REPORT); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::HK_REPORT << " not in replyMap" << std::endl; - } - break; - } - case PLOC_SPV::GET_BOOT_STATUS_REPORT: { - enabledReplies = 3; - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::BOOT_STATUS_REPORT); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::BOOT_STATUS_REPORT << " not in replyMap" << std::endl; - } - break; - } - case PLOC_SPV::RESTART_MPSOC: - case PLOC_SPV::START_MPSOC: - case PLOC_SPV::SHUTDOWN_MPSOC: - case PLOC_SPV::SEL_MPSOC_BOOT_IMAGE: - case PLOC_SPV::SET_BOOT_TIMEOUT: - case PLOC_SPV::SET_MAX_RESTART_TRIES: - case PLOC_SPV::RESET_MPSOC: - case PLOC_SPV::SET_TIME_REF: - case PLOC_SPV::UPDATE_AVAILABLE: - case PLOC_SPV::WATCHDOGS_ENABLE: - case PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT: - case PLOC_SPV::ENABLE_LATCHUP_ALERT: - case PLOC_SPV::DISABLE_LATCHUP_ALERT: - case PLOC_SPV::AUTO_CALIBRATE_ALERT: - enabledReplies = 2; - break; - default: - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Unknown command id" << std::endl; - break; + if(result == CRC_FAILURE) { + sif::error << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup status report has " + << "invalid crc" << std::endl; + return result; } - /** - * Every command causes at least one acknowledgment and one execution report. Therefore both - * replies will be enabled here. - */ - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::ACK_REPORT); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::ACK_REPORT << " not in replyMap" << std::endl; - } + uint16_t offset = PLOC_SPV::DATA_FIELD_OFFSET; + latchupStatusReport.id = *(data + offset); + offset += 1; + latchupStatusReport.cnt0 = *(data + offset) << 8 | *(data + offset + 1); + offset += 2; + latchupStatusReport.cnt1 = *(data + offset) << 8 | *(data + offset + 1); + offset += 2; + latchupStatusReport.cnt2 = *(data + offset) << 8 | *(data + offset + 1); + offset += 2; + latchupStatusReport.cnt3 = *(data + offset) << 8 | *(data + offset + 1); + offset += 2; + latchupStatusReport.cnt4 = *(data + offset) << 8 | *(data + offset + 1); + offset += 2; + latchupStatusReport.cnt5 = *(data + offset) << 8 | *(data + offset + 1); + offset += 2; + latchupStatusReport.cnt6 = *(data + offset) << 8 | *(data + offset + 1); + offset += 2; + latchupStatusReport.timeSec = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offset += 4; + latchupStatusReport.timeMin = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offset += 4; + latchupStatusReport.timeHour = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offset += 4; + latchupStatusReport.timeDay = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offset += 4; + latchupStatusReport.timeMon = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offset += 4; + latchupStatusReport.timeYear = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offset += 4; + latchupStatusReport.timeMsec = *(data + offset) << 24 | *(data + offset + 1) << 16 | + *(data + offset + 2) << 8 | *(data + offset + 3); + offset += 4; - result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, - PLOC_SPV::EXE_REPORT); - if (result != RETURN_OK) { - sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " - << PLOC_SPV::EXE_REPORT << " not in replyMap" << std::endl; - } + nextReplyId = PLOC_SPV::EXE_REPORT; - return RETURN_OK; +#if OBSW_VERBOSE_LEVEL >= 1 && PLOC_SUPERVISOR_DEBUG == 1 + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup ID: " + << static_cast(latchupStatusReport.id.value) << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT0: " + << latchupStatusReport.cnt0 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT1: " + << latchupStatusReport.cnt1 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT2: " + << latchupStatusReport.cnt2 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT3: " + << latchupStatusReport.cnt3 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT4: " + << latchupStatusReport.cnt4 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT5: " + << latchupStatusReport.cnt5 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: CNT6: " + << latchupStatusReport.cnt6 << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Sec: " + << latchupStatusReport.timeSec << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Min: " + << latchupStatusReport.timeMin << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Hour: " + << latchupStatusReport.timeHour << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Day: " + << latchupStatusReport.timeDay << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Mon: " + << latchupStatusReport.timeMon << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Year: " + << latchupStatusReport.timeYear << std::endl; + sif::info << "PlocSupervisorHandler::handleLatchupStatusReport: Msec: " + << latchupStatusReport.timeMsec << std::endl; +#endif + + return result; } void PlocSupervisorHandler::setNextReplyId() { @@ -599,12 +777,16 @@ void PlocSupervisorHandler::setNextReplyId() { case PLOC_SPV::GET_BOOT_STATUS_REPORT: nextReplyId = PLOC_SPV::BOOT_STATUS_REPORT; break; + case PLOC_SPV::GET_LATCHUP_STATUS_REPORT: + nextReplyId = PLOC_SPV::LATCHUP_REPORT; + break; default: /* If no telemetry is expected the next reply is always the execution report */ nextReplyId = PLOC_SPV::EXE_REPORT; break; } } + size_t PlocSupervisorHandler::getNextReplyLength(DeviceCommandId_t commandId){ size_t replyLen = 0; @@ -787,6 +969,65 @@ ReturnValue_t PlocSupervisorHandler::prepareAutoCalibrateAlertCmd(const uint8_t* return RETURN_OK; } +ReturnValue_t PlocSupervisorHandler::prepareSetAlertIrqFilterCmd(const uint8_t* commandData) { + uint8_t latchupId = *commandData; + uint8_t tp = *(commandData + 1); + uint8_t div = *(commandData + 2); + if (latchupId > 6) { + return INVALID_LATCHUP_ID; + } + PLOC_SPV::SetAlertIrqFilter packet(latchupId, tp, div); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + return RETURN_OK; +} + +ReturnValue_t PlocSupervisorHandler::prepareSetAlertLimitCmd(const uint8_t* commandData) { + uint8_t offset = 0; + uint8_t latchupId = *commandData; + offset += 1; + uint32_t dutycycle = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 + | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); + if (latchupId > 6) { + return INVALID_LATCHUP_ID; + } + PLOC_SPV::SetAlertlimit packet(latchupId, dutycycle); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + return RETURN_OK; +} + +ReturnValue_t PlocSupervisorHandler::prepareSetAdcSweetPeriodCmd(const uint8_t* commandData) { + uint32_t sweepPeriod = *(commandData) << 24 | *(commandData + 1) << 16 + | *(commandData + 2) << 8 | *(commandData + 3); + if (sweepPeriod < 21) { + return SWEEP_PERIOD_TOO_SMALL; + } + PLOC_SPV::SetAdcSweepPeriod packet(sweepPeriod); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + return RETURN_OK; +} + +void PlocSupervisorHandler::prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData) { + uint16_t ch = *(commandData) << 8 | *(commandData + 1); + PLOC_SPV::SetAdcEnabledChannels packet(ch); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + +void PlocSupervisorHandler::prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData) { + uint8_t offset = 0; + uint16_t windowSize = *(commandData + offset) << 8 | *(commandData + offset + 1); + offset += 2; + uint16_t stridingStepSize = *(commandData + offset) << 8 | *(commandData + offset + 1); + PLOC_SPV::SetAdcWindowAndStride packet(windowSize, stridingStepSize); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + +void PlocSupervisorHandler::prepareSetAdcThresholdCmd(const uint8_t* commandData) { + uint32_t threshold = *(commandData) << 24 | *(commandData + 1) << 16 | *(commandData + 2) << 8 + | *(commandData + 3); + PLOC_SPV::SetAdcThreshold packet(threshold); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { memcpy(commandBuffer, packetData, fullSize); rawPacket = commandBuffer; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index bbbbf25e..59c51a13 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -66,9 +66,11 @@ private: //! [EXPORT] : [COMMENT] Received command with invalid watchdog parameter. Valid watchdogs are 0 for PS, 1 for PL and 2 for INT static const ReturnValue_t INVALID_WATCHDOG = MAKE_RETURN_CODE(0xA6); //! [EXPORT] : [COMMENT] Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms. - static const ReturnValue_t INVALID_WATCHDOG_TIMEOUT = MAKE_RETURN_CODE(0xA6); + static const ReturnValue_t INVALID_WATCHDOG_TIMEOUT = MAKE_RETURN_CODE(0xA7); //! [EXPORT] : [COMMENT] Received latchup config command with invalid latchup ID - static const ReturnValue_t INVALID_LATCHUP_ID = MAKE_RETURN_CODE(0xA7); + static const ReturnValue_t INVALID_LATCHUP_ID = MAKE_RETURN_CODE(0xA8); + //! [EXPORT] : [COMMENT] Received set adc sweep period command with invalid sweep period. Must be larger than 21. + static const ReturnValue_t SWEEP_PERIOD_TOO_SMALL = MAKE_RETURN_CODE(0x9); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; @@ -105,10 +107,11 @@ private: */ DeviceCommandId_t nextReplyId = PLOC_SPV::NONE; + UartComIF* uartComIf = nullptr; + PLOC_SPV::HkSet hkset; PLOC_SPV::BootStatusReport bootStatusReport; - - UartComIF* uartComIf = nullptr; + PLOC_SPV::LatchupStatusReport latchupStatusReport; /** * @brief This function checks the crc of the received PLOC reply. @@ -154,6 +157,8 @@ private: */ ReturnValue_t handleBootStatusReport(const uint8_t* data); + ReturnValue_t handleLatchupStatusReport(const uint8_t* data); + /** * @brief Depending on the current active command, this function sets the reply id of the * next reply after a successful acknowledgment report has been received. This is @@ -220,6 +225,12 @@ private: ReturnValue_t prepareLatchupConfigCmd(const uint8_t* commandData, DeviceCommandId_t deviceCommand); ReturnValue_t prepareAutoCalibrateAlertCmd(const uint8_t* commandData); + ReturnValue_t prepareSetAlertLimitCmd(const uint8_t* commandData); + ReturnValue_t prepareSetAlertIrqFilterCmd(const uint8_t* commandData); + ReturnValue_t prepareSetAdcSweetPeriodCmd(const uint8_t* commandData); + void prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData); + void prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData); + void prepareSetAdcThresholdCmd(const uint8_t* commandData); /** diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 28349dab..7eb7c163 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -28,17 +28,40 @@ static const DeviceCommandId_t WATCHDOGS_CONFIG_TIMEOUT = 14; static const DeviceCommandId_t ENABLE_LATCHUP_ALERT = 15; static const DeviceCommandId_t DISABLE_LATCHUP_ALERT = 16; static const DeviceCommandId_t AUTO_CALIBRATE_ALERT = 17; +static const DeviceCommandId_t SET_ALERT_LIMIT = 18; +static const DeviceCommandId_t SET_ALERT_IRQ_FILTER = 19; +static const DeviceCommandId_t SET_ADC_SWEEP_PERIOD = 20; +static const DeviceCommandId_t SET_ADC_ENABLED_CHANNELS = 21; +static const DeviceCommandId_t SET_ADC_WINDOW_AND_STRIDE = 22; +static const DeviceCommandId_t SET_ADC_THRESHOLD = 23; +static const DeviceCommandId_t GET_LATCHUP_STATUS_REPORT = 24; +static const DeviceCommandId_t COPY_ADC_DATA_TO_MRAM = 25; +static const DeviceCommandId_t ENABLE_NVMS = 26; +static const DeviceCommandId_t SELECT_NVM = 27; +static const DeviceCommandId_t RUN_AUTO_EM_TESTS = 28; +static const DeviceCommandId_t WIPE_MRAM = 29; +static const DeviceCommandId_t DUMP_MRAM = 30; +static const DeviceCommandId_t SET_DBG_VERBOSITY = 31; +static const DeviceCommandId_t CAN_LOOPBACK_TEST = 32; +static const DeviceCommandId_t PRINT_CPU_STATS = 33; +static const DeviceCommandId_t SET_GPIO = 34; +static const DeviceCommandId_t READ_GPIO = 35; +static const DeviceCommandId_t RESTART_SUPERVISOR = 36; +static const DeviceCommandId_t FACTORY_RESET = 37; +static const DeviceCommandId_t REQUEST_LOGGING_DATA = 38; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; static const DeviceCommandId_t EXE_REPORT = 51; static const DeviceCommandId_t HK_REPORT = 52; static const DeviceCommandId_t BOOT_STATUS_REPORT = 53; +static const DeviceCommandId_t LATCHUP_REPORT = 54; static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14; static const uint16_t SIZE_HK_REPORT = 48; static const uint16_t SIZE_BOOT_STATUS_REPORT = 22; +static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 55; /** * SpacePacket apids of telemetry packets @@ -142,14 +165,33 @@ enum PoolIds ACTIVE_NVM, BP0_STATE, BP1_STATE, - BP2_STATE + BP2_STATE, + + LATCHUP_ID, + CNT0, + CNT1, + CNT2, + CNT3, + CNT4, + CNT5, + CNT6, + LATCHUP_RPT_TIME_SEC, + LATCHUP_RPT_TIME_MIN, + LATCHUP_RPT_TIME_HOUR, + LATCHUP_RPT_TIME_DAY, + LATCHUP_RPT_TIME_MON, + LATCHUP_RPT_TIME_YEAR, + LATCHUP_RPT_TIME_MSEC, + LATCHUP_RPT_TIME_USEC, }; static const uint8_t HK_SET_ENTRIES = 13; static const uint8_t BOOT_REPORT_SET_ENTRIES = 8; +static const uint8_t LATCHUP_RPT_SET_ENTRIES = 15; static const uint32_t HK_SET_ID = HK_REPORT; -static const uint32_t BOOT_REPORT_SET_ID = APID_BOOT_STATUS_REPORT; +static const uint32_t BOOT_REPORT_SET_ID = BOOT_STATUS_REPORT; +static const uint32_t LATCHUP_RPT_ID = LATCHUP_REPORT; /** * @brief With this class a space packet can be created which does not contain any data. @@ -661,6 +703,266 @@ private: } }; + +class SetAlertlimit: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param latchupId Identifies the latchup alert to calibrate (0 - 0.85V, 1 - 1.8V, 2 - MISC, + * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) + * @param dutycycle + */ + SetAlertlimit(uint8_t latchupId, uint32_t dutycycle) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ALERT_LIMIT, + DEFAULT_SEQUENCE_COUNT), latchupId(latchupId), dutycycle(dutycycle) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 7; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t latchupId = 0; + uint32_t dutycycle = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, + sizeof(latchupId), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&dutycycle, &data_field_ptr, &serializedSize, + sizeof(dutycycle), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +class SetAlertIrqFilter: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param latchupId Identifies the latchup alert to calibrate (0 - 0.85V, 1 - 1.8V, 2 - MISC, + * 3 - 3.3V, 4 - NVM_4XO, 5 - MISSION, 6 - SAFECOTS) + * @param tp + * @param div + */ + SetAlertIrqFilter(uint8_t latchupId, uint8_t tp, uint8_t div) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ALERT_IRQ_FILTER, + DEFAULT_SEQUENCE_COUNT), tp(tp), div(div) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 5; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t latchupId = 0; + uint8_t tp = 0; + uint8_t div = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&latchupId, &data_field_ptr, &serializedSize, + sizeof(latchupId), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&tp, &data_field_ptr, &serializedSize, + sizeof(tp), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&div, &data_field_ptr, &serializedSize, + sizeof(div), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + + +/** + * @brief This class packages the space packet to set the sweep period of the ADC. + */ +class SetAdcSweepPeriod: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param sweepPeriod Sweep period in us. minimum is 21 us + */ + SetAdcSweepPeriod(uint32_t sweepPeriod) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_SWEEP_PERIOD, + DEFAULT_SEQUENCE_COUNT), sweepPeriod(sweepPeriod) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 6; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint32_t sweepPeriod = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&sweepPeriod, &data_field_ptr, &serializedSize, + sizeof(sweepPeriod), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet to enable or disable ADC channels. + */ +class SetAdcEnabledChannels: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param ch Defines channels to be enabled or disabled. + */ + SetAdcEnabledChannels(uint16_t ch) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_ENABLED_CHANNELS, + DEFAULT_SEQUENCE_COUNT), ch(ch) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 4; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint16_t ch = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&ch, &data_field_ptr, &serializedSize, + sizeof(ch), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet to configures the window size and striding step of + * the moving average filter applied to the ADC readings. + */ +class SetAdcWindowAndStride: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param windowSize + * @param stridingStepSize + */ + SetAdcWindowAndStride(uint16_t windowSize, uint16_t stridingStepSize) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_WINDOW_AND_STRIDE, + DEFAULT_SEQUENCE_COUNT), windowSize(windowSize), stridingStepSize( + stridingStepSize) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 6; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint16_t windowSize = 0; + uint16_t stridingStepSize = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&windowSize, &data_field_ptr, &serializedSize, + sizeof(windowSize), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&stridingStepSize, &data_field_ptr, &serializedSize, + sizeof(stridingStepSize), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet to set the ADC trigger threshold. + */ +class SetAdcThreshold: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param threshold + */ + SetAdcThreshold(uint32_t threshold) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_ADC_THRESHOLD, + DEFAULT_SEQUENCE_COUNT), threshold(threshold) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 6; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint32_t threshold = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&threshold, &data_field_ptr, &serializedSize, + sizeof(threshold), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + /** * @brief This dataset stores the boot status report of the supervisor. */ @@ -719,6 +1021,37 @@ public: this); lp_var_t fmcState = lp_var_t(sid.objectId, PoolIds::FMC_STATE, this); }; + +/** + * @brief This dataset stores the last requested latchup status report. + */ +class LatchupStatusReport: public StaticLocalDataSet { +public: + + LatchupStatusReport(HasLocalDataPoolIF* owner) : + StaticLocalDataSet(owner, LATCHUP_RPT_ID) { + } + + LatchupStatusReport(object_id_t objectId) : + StaticLocalDataSet(sid_t(objectId, LATCHUP_RPT_ID)) { + } + + lp_var_t id = lp_var_t(sid.objectId, PoolIds::LATCHUP_ID, this); + lp_var_t cnt0 = lp_var_t(sid.objectId, PoolIds::CNT0, this); + lp_var_t cnt1 = lp_var_t(sid.objectId, PoolIds::CNT1, this); + lp_var_t cnt2 = lp_var_t(sid.objectId, PoolIds::CNT2, this); + lp_var_t cnt3 = lp_var_t(sid.objectId, PoolIds::CNT3, this); + lp_var_t cnt4 = lp_var_t(sid.objectId, PoolIds::CNT4, this); + lp_var_t cnt5 = lp_var_t(sid.objectId, PoolIds::CNT5, this); + lp_var_t cnt6 = lp_var_t(sid.objectId, PoolIds::CNT6, this); + lp_var_t timeSec = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_SEC, this); + lp_var_t timeMin = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MIN, this); + lp_var_t timeHour = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_HOUR, this); + lp_var_t timeDay = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_DAY, this); + lp_var_t timeMon = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MON, this); + lp_var_t timeYear = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_YEAR, this); + lp_var_t timeMsec = lp_var_t(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MSEC, this); +}; } #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCSVPDEFINITIONS_H_ */ -- 2.43.0 From 3d39ddf85c2c005fd9c15dcea8641a9932016845 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Wed, 28 Jul 2021 11:08:40 +0200 Subject: [PATCH 039/116] copy adc data to mram command --- mission/devices/PlocSupervisorHandler.cpp | 16 +++++++++++++++- .../PlocSupervisorDefinitions.h | 3 ++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 367cc642..6ba7f6ad 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -170,6 +170,11 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( prepareEmptyCmd(PLOC_SPV::APID_GET_LATCHUP_STATUS_REPORT); result = RETURN_OK; break; + } + case(PLOC_SPV::COPY_ADC_DATA_TO_MRAM): { + prepareEmptyCmd(PLOC_SPV::APID_COPY_ADC_DATA_TO_MRAM); + result = RETURN_OK; + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -213,6 +218,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::SET_ADC_WINDOW_AND_STRIDE); this->insertInCommandMap(PLOC_SPV::SET_ADC_THRESHOLD); this->insertInCommandMap(PLOC_SPV::GET_LATCHUP_STATUS_REPORT); + this->insertInCommandMap(PLOC_SPV::COPY_ADC_DATA_TO_MRAM); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -246,6 +252,10 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t *start, *foundLen = PLOC_SPV::SIZE_BOOT_STATUS_REPORT; *foundId = PLOC_SPV::BOOT_STATUS_REPORT; break; + case(PLOC_SPV::APID_LATCHUP_STATUS_REPORT): + *foundLen = PLOC_SPV::SIZE_LATCHUP_STATUS_REPORT; + *foundId = PLOC_SPV::LATCHUP_REPORT; + break; case(PLOC_SPV::APID_EXE_SUCCESS): *foundLen = PLOC_SPV::SIZE_EXE_REPORT; *foundId = PLOC_SPV::EXE_REPORT; @@ -282,6 +292,10 @@ ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id, result = handleBootStatusReport(packet); break; } + case (PLOC_SPV::LATCHUP_REPORT): { + result = handleLatchupStatusReport(packet); + break; + } case (PLOC_SPV::EXE_REPORT): { result = handleExecutionReport(packet); break; @@ -684,7 +698,7 @@ ReturnValue_t PlocSupervisorHandler::handleLatchupStatusReport(const uint8_t* da ReturnValue_t result = RETURN_OK; - result = verifyPacket(data, PLOC_SPV::SIZE_BOOT_STATUS_REPORT); + result = verifyPacket(data, PLOC_SPV::SIZE_LATCHUP_STATUS_REPORT); if(result == CRC_FAILURE) { sif::error << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup status report has " diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 7eb7c163..2350a42c 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -49,6 +49,7 @@ static const DeviceCommandId_t READ_GPIO = 35; static const DeviceCommandId_t RESTART_SUPERVISOR = 36; static const DeviceCommandId_t FACTORY_RESET = 37; static const DeviceCommandId_t REQUEST_LOGGING_DATA = 38; +static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; @@ -61,7 +62,7 @@ static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14; static const uint16_t SIZE_HK_REPORT = 48; static const uint16_t SIZE_BOOT_STATUS_REPORT = 22; -static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 55; +static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 51; /** * SpacePacket apids of telemetry packets -- 2.43.0 From 50ca738d5cacdde2a53f839b497fbf54f9b9b132 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Wed, 28 Jul 2021 11:55:16 +0200 Subject: [PATCH 040/116] select nvm command --- mission/devices/PlocSupervisorHandler.cpp | 25 ++++++ mission/devices/PlocSupervisorHandler.h | 2 + .../PlocSupervisorDefinitions.h | 85 +++++++++++++++++++ 3 files changed, 112 insertions(+) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 6ba7f6ad..e45f7f45 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -175,6 +175,16 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( prepareEmptyCmd(PLOC_SPV::APID_COPY_ADC_DATA_TO_MRAM); result = RETURN_OK; break; + } + case(PLOC_SPV::ENABLE_NVMS): { + prepareEnableNvmsCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::SELECT_NVM): { + prepareSelectNvmCmd(commandData); + result = RETURN_OK; + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -219,6 +229,8 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::SET_ADC_THRESHOLD); this->insertInCommandMap(PLOC_SPV::GET_LATCHUP_STATUS_REPORT); this->insertInCommandMap(PLOC_SPV::COPY_ADC_DATA_TO_MRAM); + this->insertInCommandMap(PLOC_SPV::ENABLE_NVMS); + this->insertInCommandMap(PLOC_SPV::SELECT_NVM); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -1042,6 +1054,19 @@ void PlocSupervisorHandler::prepareSetAdcThresholdCmd(const uint8_t* commandData packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } +void PlocSupervisorHandler::prepareEnableNvmsCmd(const uint8_t* commandData) { + uint8_t n01 = *commandData; + uint8_t n3 = *(commandData + 1); + PLOC_SPV::EnableNvms packet(n01, n3); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + +void PlocSupervisorHandler::prepareSelectNvmCmd(const uint8_t* commandData) { + uint8_t mem = *commandData; + PLOC_SPV::SelectNvm packet(mem); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { memcpy(commandBuffer, packetData, fullSize); rawPacket = commandBuffer; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index 59c51a13..f1c29554 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -231,6 +231,8 @@ private: void prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData); void prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData); void prepareSetAdcThresholdCmd(const uint8_t* commandData); + void prepareEnableNvmsCmd(const uint8_t* commandData); + void prepareSelectNvmCmd(const uint8_t* commandData); /** diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 2350a42c..10486b24 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -964,6 +964,91 @@ private: } }; +/** + * @brief This class packages the space packet to select between NVM 0 and NVM 1. + */ +class SelectNvm: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param mem 0 - select NVM0, 1 - select NVM1. + */ + SelectNvm(uint8_t mem) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SELECT_NVM, + DEFAULT_SEQUENCE_COUNT), mem(mem) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 3; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t mem = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&mem, &data_field_ptr, &serializedSize, + sizeof(mem), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet to power the NVMs on or off. + */ +class EnableNvms: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param n01 Set to one to power NVM0 and NVM1 on. 0 powers off memory. + * @param n3 Set to one to power NVM3 on. 0 powers off the memory. + */ + EnableNvms(uint8_t n01, uint8_t n3) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_ENABLE_NVMS, + DEFAULT_SEQUENCE_COUNT), n01(n01), n3(n3) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 4; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t n01 = 0; + uint8_t n3 = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&n01, &data_field_ptr, &serializedSize, + sizeof(n01), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&n3, &data_field_ptr, &serializedSize, + sizeof(n3), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + /** * @brief This dataset stores the boot status report of the supervisor. */ -- 2.43.0 From d511903872162b1d9a13e05ac4f01694f4f7afd8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jul 2021 15:24:48 +0200 Subject: [PATCH 041/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 1f990e96..31bc3d86 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 1f990e9647e3f513cf1b3073e94774d530645073 +Subproject commit 31bc3d86895dfabf59002880376e9ebfd9015923 -- 2.43.0 From dd61af5bb39aa6d28542cc203c485fdccf51186c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jul 2021 15:28:51 +0200 Subject: [PATCH 042/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 31bc3d86..8b7331c2 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 31bc3d86895dfabf59002880376e9ebfd9015923 +Subproject commit 8b7331c210e44bf2a60e5834f5f253514dae29fe -- 2.43.0 From c0b91a48796832fc73079b06376f10458e0fdcf0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jul 2021 16:37:08 +0200 Subject: [PATCH 043/116] added functions to get current boot copy --- bsp_q7s/core/CoreController.cpp | 136 +++++++++++++++++++++----------- bsp_q7s/core/CoreController.h | 28 ++++++- 2 files changed, 117 insertions(+), 47 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 2351c9be..d6555f95 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -15,8 +15,12 @@ #include +CoreController::Chip CoreController::currentChip = Chip::NO_CHIP; +CoreController::Copy CoreController::currentCopy = Copy::NO_COPY; + CoreController::CoreController(object_id_t objectId): ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) { + initBootCopy(); } ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { @@ -136,51 +140,11 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ const uint8_t *data, size_t size) { switch(actionId) { case(LIST_DIRECTORY_INTO_FILE): { - // TODO: Packet definition for clean deserialization - // 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with - // null termination, at least 7 bytes for minimum target file name /tmp/a with - // null termination. - if(size < 14) { - return HasActionsIF::INVALID_PARAMETERS; - } - // We could also make -l optional, but I can't think of a reason why to not use -l.. - - // This flag specifies to run ls with -a - bool aFlag = data[0]; - data += 1; - // This flag specifies to run ls with -R - bool RFlag = data[1]; - data += 1; - - size_t remainingSize = size - 2; - // One larger for null termination, which prevents undefined behaviour if the sent - // strings are not 0 terminated properly - std::vector repoAndTargetFileBuffer(remainingSize + 1, 0); - std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize); - const char* currentCharPtr = reinterpret_cast(repoAndTargetFileBuffer.data()); - // Full target file name - std::string repoName(currentCharPtr); - size_t repoLength = repoName.length(); - // The other string needs to be at least one letter plus NULL termination to be valid at all - // The first string also needs to be NULL terminated, but the termination is not included - // in the string length, so this is subtracted from the remaining size as well - if(repoLength > remainingSize - 3) { - return HasActionsIF::INVALID_PARAMETERS; - } - // The file length will not include the NULL termination, so we skip it - currentCharPtr += repoLength + 1; - std::string targetFileName(currentCharPtr); - std::ostringstream oss; - oss << "ls -l"; - if(aFlag) { - oss << "a"; - } - if(RFlag) { - oss << "R"; - } - oss << " " << repoName << " > " << targetFileName; - std::system(oss.str().c_str()); + return actionListDirectoryIntoFile(actionId, commandedBy, data, size); + } + case(REBOOT_OBC): { return HasReturnvaluesIF::RETURN_OK; + break; } default: { return HasActionsIF::INVALID_ACTION_ID; @@ -189,7 +153,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ } ReturnValue_t CoreController::initializeAfterTaskCreation() { - ReturnValue_t result = versionFileInit(); + ReturnValue_t result = initVersionFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; } @@ -272,7 +236,7 @@ ReturnValue_t CoreController::incrementAllocationFailureCount() { return scratch::writeNumber(scratch::ALLOC_FAILURE_COUNT, count); } -ReturnValue_t CoreController::versionFileInit() { +ReturnValue_t CoreController::initVersionFile() { std::string unameFileName = "/tmp/uname_version.txt"; // TODO: No -v flag for now. If the kernel version is used, need to cut off first few letters @@ -356,6 +320,86 @@ ReturnValue_t CoreController::versionFileInit() { return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { + // TODO: Packet definition for clean deserialization + // 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with + // null termination, at least 7 bytes for minimum target file name /tmp/a with + // null termination. + if(size < 14) { + return HasActionsIF::INVALID_PARAMETERS; + } + // We could also make -l optional, but I can't think of a reason why to not use -l.. + + // This flag specifies to run ls with -a + bool aFlag = data[0]; + data += 1; + // This flag specifies to run ls with -R + bool RFlag = data[1]; + data += 1; + + size_t remainingSize = size - 2; + // One larger for null termination, which prevents undefined behaviour if the sent + // strings are not 0 terminated properly + std::vector repoAndTargetFileBuffer(remainingSize + 1, 0); + std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize); + const char* currentCharPtr = reinterpret_cast(repoAndTargetFileBuffer.data()); + // Full target file name + std::string repoName(currentCharPtr); + size_t repoLength = repoName.length(); + // The other string needs to be at least one letter plus NULL termination to be valid at all + // The first string also needs to be NULL terminated, but the termination is not included + // in the string length, so this is subtracted from the remaining size as well + if(repoLength > remainingSize - 3) { + return HasActionsIF::INVALID_PARAMETERS; + } + // The file length will not include the NULL termination, so we skip it + currentCharPtr += repoLength + 1; + std::string targetFileName(currentCharPtr); + std::ostringstream oss; + oss << "ls -l"; + if(aFlag) { + oss << "a"; + } + if(RFlag) { + oss << "R"; + } + oss << " " << repoName << " > " << targetFileName; + int result = std::system(oss.str().c_str()); + if(result != 0) { + utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile"); + actionHelper.finish(false, commandedBy, actionId); + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CoreController::initBootCopy() { + std::string fileName = "/tmp/curr_copy.txt"; + std::string cmd = "xsc_boot_copy > " + fileName; + int result = std::system(cmd.c_str()); + if(result != 0) { + utility::handleSystemError(result, "CoreController::initBootCopy"); + } + std::ifstream file(fileName); + std::string line; + std::getline(file, line); + std::istringstream iss(line); + int value = 0; + iss >> value; + currentChip = static_cast(value); + sif::debug << "Current chip: " << currentChip << std::endl; + iss >> value; + currentCopy = static_cast(value); + sif::debug << "Current chip: " << currentCopy << std::endl; + return HasReturnvaluesIF::RETURN_OK; +} + +void CoreController::getCurrentBootCopy(Chip &chip, Copy ©) { + // Not really thread-safe but it does not need to be + chip = currentChip; + copy = currentCopy; +} + void CoreController::initPrint() { #if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_USE_TMTC_TCP_BRIDGE == 0 diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 88415949..5576f7ca 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -6,14 +6,30 @@ #include "events/subsystemIdRanges.h" + + class CoreController: public ExtendedControllerBase { public: + enum Chip: uint8_t { + CHIP_0, + CHIP_1, + NO_CHIP + }; + + enum Copy: uint8_t { + COPY_0, + COPY_1, + NO_COPY + }; + static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0; + static constexpr ActionId_t REBOOT_OBC = 1; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); + CoreController(object_id_t objectId); ReturnValue_t initialize() override; @@ -27,7 +43,12 @@ public: void performControlOperation() override; static ReturnValue_t incrementAllocationFailureCount(); + static void getCurrentBootCopy(Chip& chip, Copy& copy); + private: + static Chip currentChip; + static Copy currentCopy; + ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; @@ -40,7 +61,12 @@ private: ReturnValue_t sdCardColdRedundantInit(SdCardManager* sdcMan, SdCardManager::SdStatusPair& statusPair); - ReturnValue_t versionFileInit(); + ReturnValue_t initVersionFile(); + ReturnValue_t initBootCopy(); + + ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t *data, size_t size); + void initPrint(); }; -- 2.43.0 From 1a4f907925af1c414cad1b89d05fb0ebd3021587 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jul 2021 17:48:08 +0200 Subject: [PATCH 044/116] moved sd card init, more functions static now --- README.md | 2 +- bsp_q7s/core/CoreController.cpp | 23 +++++++++++++---------- bsp_q7s/core/CoreController.h | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a174fbf1..d71db451 100644 --- a/README.md +++ b/README.md @@ -318,7 +318,7 @@ wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/rfoaistRd67yBbH/downloa or the following command for Linux (could be useful for CI/CD) ```sh -wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/2Fp2ag6NGnbtAsK/download/gcc-arm-linux-gnueabi.tar.gz +wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/MRaeA2XnMXpZ5Pp/download/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz ``` ## Installing CMake and MSYS2 on Windows diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index d6555f95..5d99d3ec 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -20,6 +20,18 @@ CoreController::Copy CoreController::currentCopy = Copy::NO_COPY; CoreController::CoreController(object_id_t objectId): ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + try { + result = sdCardInit(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; + } + } + catch(const std::filesystem::filesystem_error& e) { + sif::error << "CoreController::CoreController: sdCardInit failed with exception " << + e.what() << std::endl; + } + initBootCopy(); } @@ -41,16 +53,6 @@ LocalPoolDataSetBase* CoreController::getDataSetHandle(sid_t sid) { ReturnValue_t CoreController::initialize() { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - try { - result = sdCardInit(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::initialize: SD card init failed" << std::endl; - } - } - catch(const std::filesystem::filesystem_error& e) { - sif::error << "CoreController::initialize: sdCardInit failed with exception " << e.what() - << std::endl; - } result = scratch::writeNumber(scratch::ALLOC_FAILURE_COUNT, 0); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -374,6 +376,7 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId, } ReturnValue_t CoreController::initBootCopy() { + // We could create this file even before the OBSW is started.. std::string fileName = "/tmp/curr_copy.txt"; std::string cmd = "xsc_boot_copy > " + fileName; int result = std::system(cmd.c_str()); diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 5576f7ca..add107e7 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -62,7 +62,7 @@ private: SdCardManager::SdStatusPair& statusPair); ReturnValue_t initVersionFile(); - ReturnValue_t initBootCopy(); + static ReturnValue_t initBootCopy(); ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size); -- 2.43.0 From 1e6ea91438147734330869512577324ca4eb0fa4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jul 2021 18:43:11 +0200 Subject: [PATCH 045/116] README update --- README.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d71db451..b8ecdde6 100644 --- a/README.md +++ b/README.md @@ -591,6 +591,10 @@ More detailed information about the used q7s commands can be found in the Q7S us ## Launching an application at start-up +You can also do the steps performed here on a host computer inside the `q7s-rootfs` directory +of the [Q7S base repository](https://egit.irs.uni-stuttgart.de/eive/q7s-base). This might +be more convenient while also allowing to update all images at once with the finished `rootfs.xdi`. + Load the root partiton from the flash memory (there are to nor-flash memories and each flash holds two xdi images). Note: It is not possible to modify the currently loaded root partition, e.g. creating directories. To do this, the parition needs to be mounted. @@ -616,7 +620,7 @@ creating directories. To do this, the parition needs to be mounted. chmod +x application ``` -5. Create systemd service in /lib/systemd/system. The following shows an example service. +5. Create systemd service in `/etc/systemd/system`. The following shows an example service. ```sh cat > example.service @@ -634,11 +638,19 @@ creating directories. To do this, the parition needs to be mounted. [Install] WantedBy=multi-user.target ``` -6. Enable the service. This is normally done with systemctl enable. However, this is not possible - when the service is created for a mounted root partition. Therefore create a symlink as follows. + +6. Enable the service. This is normally done with `systemctl enable ` which would create + a symlink in the `multi-user.target.wants` directory. However, this is not possible + when the service is created for a mounted root partition. It is also not possible during run + time because symlinks can't be created in a read-only filesystem. Therefore, relative symlinks + are used like this: + ```sh - ln -s '/tmp/the-mounted-xdi-image/lib/systemd/system/example.service' '/tmp/the-mounted-xdi-image/etc/systemd/system/multi-user.target.wants/example.service' + cd etc/systemd/system/multi-user.target.wants/ + ln -s ../example.service example.service ``` + + You can check the symlinnks with `ls -l` 7. The modified root partition is written back when the partion is locked again. ```sh -- 2.43.0 From b846a936b439a12e5a23faffe587ab32e42deb13 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jul 2021 18:50:50 +0200 Subject: [PATCH 046/116] README update --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index b8ecdde6..4865885d 100644 --- a/README.md +++ b/README.md @@ -666,6 +666,29 @@ creating directories. To do this, the parition needs to be mounted. systemctl status example ``` + +## Current user systemd services + +The following custom `systemd` services are currently running on the Q7S and can be found in +the `/etc/systemd/system` folder. +You can query that status of a service by running `systemctl status `. + +### `tcfagent` + +This starts the `/usr/bin/agent` program to allows remote debugging. Might not be part of +the mission code + +### `eive-early-config` + +This is a configuration script which runs early after `local-fs.target` and `sysinit.target` +Currently only pipes the output of `xsc_boot_copy` into the file `/tmp/curr_copy.txt` which can be +used by other software components to read the current chip and copy. + +### `eive-post-ntpd-config` + +This is a configuration scripts which runs after the Network Time Protocol has run. This script +currently sets the static IP address `192.168.133.10` and starts the `can` interface. + ## PCDU Connect to serial console of P60 Dock -- 2.43.0 From fc769be7894605459dedd2fe57ba800ceba7aa6f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jul 2021 18:56:36 +0200 Subject: [PATCH 047/116] updated cp script --- scripts/q7s-cp.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/q7s-cp.py b/scripts/q7s-cp.py index 9de9d661..0c8c1a79 100755 --- a/scripts/q7s-cp.py +++ b/scripts/q7s-cp.py @@ -8,7 +8,13 @@ def main(): cmd = build_cmd(args) # Run the command print(f'Running command: {cmd}') - os.system(cmd) + result = os.system(cmd) + if result != 0: + print('') + print('Removing problematic SSH key and trying again..') + remove_ssh_key_cmd = 'ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "[localhost]:1535"' + os.system(remove_ssh_key_cmd) + result = os.system(cmd) def handle_args(): -- 2.43.0 From f4b67945cc7e724cda6958859bc68b7a2510bcec Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Wed, 28 Jul 2021 19:34:10 +0200 Subject: [PATCH 048/116] wipe mram command --- mission/devices/PlocSupervisorHandler.cpp | 32 ++++++ mission/devices/PlocSupervisorHandler.h | 6 +- .../PlocSupervisorDefinitions.h | 102 ++++++++++++++++++ 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index e45f7f45..a86993b0 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -185,6 +185,15 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( prepareSelectNvmCmd(commandData); result = RETURN_OK; break; + } + case(PLOC_SPV::RUN_AUTO_EM_TESTS): { + result = prepareRunAutoEmTest(commandData); + break; + } + case(PLOC_SPV::WIPE_MRAM): { + prepareWipeMramCmd(commandData); + result = RETURN_OK; + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -231,6 +240,8 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::COPY_ADC_DATA_TO_MRAM); this->insertInCommandMap(PLOC_SPV::ENABLE_NVMS); this->insertInCommandMap(PLOC_SPV::SELECT_NVM); + this->insertInCommandMap(PLOC_SPV::RUN_AUTO_EM_TESTS); + this->insertInCommandMap(PLOC_SPV::WIPE_MRAM); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -1067,6 +1078,27 @@ void PlocSupervisorHandler::prepareSelectNvmCmd(const uint8_t* commandData) { packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } +ReturnValue_t PlocSupervisorHandler::prepareRunAutoEmTest(const uint8_t* commandData) { + uint8_t test = *commandData; + if (test != 1 && test != 2) { + return INVALID_TEST_PARAM; + } + PLOC_SPV::RunAutoEmTests packet(test); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + return RETURN_OK; +} + +void PlocSupervisorHandler::prepareWipeMramCmd(const uint8_t* commandData) { + uint8_t offset = 0; + uint32_t start = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 + | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); + offset += 4; + uint32_t stop = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 + | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); + PLOC_SPV::MramCmd packet(start, stop, PLOC_SPV::MramCmd::MramAction::WIPE); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { memcpy(commandBuffer, packetData, fullSize); rawPacket = commandBuffer; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index f1c29554..723f8cfe 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -70,7 +70,9 @@ private: //! [EXPORT] : [COMMENT] Received latchup config command with invalid latchup ID static const ReturnValue_t INVALID_LATCHUP_ID = MAKE_RETURN_CODE(0xA8); //! [EXPORT] : [COMMENT] Received set adc sweep period command with invalid sweep period. Must be larger than 21. - static const ReturnValue_t SWEEP_PERIOD_TOO_SMALL = MAKE_RETURN_CODE(0x9); + static const ReturnValue_t SWEEP_PERIOD_TOO_SMALL = MAKE_RETURN_CODE(0xA9); + //! [EXPORT] : [COMMENT] Receive auto EM test command with invalid test param. Valid params are 1 and 2. + static const ReturnValue_t INVALID_TEST_PARAM = MAKE_RETURN_CODE(0xAA); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; @@ -233,6 +235,8 @@ private: void prepareSetAdcThresholdCmd(const uint8_t* commandData); void prepareEnableNvmsCmd(const uint8_t* commandData); void prepareSelectNvmCmd(const uint8_t* commandData); + ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData); + void prepareWipeMramCmd(const uint8_t* commandData); /** diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 10486b24..ce1400be 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -1049,6 +1049,108 @@ private: } }; +/** + * @brief This class packages the space packet to run auto EM tests. + */ +class RunAutoEmTests: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param test 1 - complete EM test, 2 - Short test (only memory readback NVM0,1,3) + */ + RunAutoEmTests(uint8_t test) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_RUN_AUTO_EM_TESTS, + DEFAULT_SEQUENCE_COUNT), test(test) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 3; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t test = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&test, &data_field_ptr, &serializedSize, + sizeof(test), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet to wipe or dump parts of the MRAM. + */ +class MramCmd: public SpacePacket { +public: + + enum class MramAction { + WIPE, + DUMP + }; + + /** + * @brief Constructor + * + * @param start Start address of the MRAM section to wipe or dump + * @param stop End address of the MRAM section to wipe or dump + * @param action Dump or wipe MRAM + */ + MramCmd(uint32_t start, uint32_t stop, MramAction action) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_IDLE_PACKET, + DEFAULT_SEQUENCE_COUNT), start(start), stop(stop) { + if(action == MramAction::WIPE) { + this->setAPID(APID_WIPE_MRAM); + } + else if (action == MramAction::DUMP) { + this->setAPID(APID_DUMP_MRAM); + } + else { + sif::debug << "WipeMram: Invalid action specified"; + } + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 8; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint32_t start = 0; + uint32_t stop = 0; + + void initPacket() { + uint8_t concatBuffer[6]; + concatBuffer[0] = static_cast(start >> 16); + concatBuffer[1] = static_cast(start >> 8); + concatBuffer[2] = static_cast(start); + concatBuffer[3] = static_cast(stop >> 16); + concatBuffer[4] = static_cast(stop >> 8); + concatBuffer[5] = static_cast(stop); + uint8_t* data_field_ptr = this->localData.fields.buffer; + std::memcpy(data_field_ptr, concatBuffer, sizeof(concatBuffer)); + size_t serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + /** * @brief This dataset stores the boot status report of the supervisor. */ -- 2.43.0 From 4f3a680a073c2ec204f60d910ebe0707683274f5 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Wed, 28 Jul 2021 19:38:54 +0200 Subject: [PATCH 049/116] updated tmtc --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 75ae2c78..6601233f 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 75ae2c786b2422ea1986ce69bdcd528346e88f1a +Subproject commit 6601233f419fd395111c9f98043f3e687ee23dc3 -- 2.43.0 From 125593be21cdf4f9211f926adac1b3cbf8077a65 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jul 2021 19:46:19 +0200 Subject: [PATCH 050/116] reading chip and copy works --- bsp_q7s/core/CoreController.cpp | 27 +++++++++++++++------------ bsp_q7s/core/CoreController.h | 4 ++-- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 5d99d3ec..a37db440 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -22,17 +22,19 @@ CoreController::CoreController(object_id_t objectId): ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; try { - result = sdCardInit(); + result = initSdCard(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; } + result = initBootCopy(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::CoreController: Boot copy init" << std::endl; + } } catch(const std::filesystem::filesystem_error& e) { - sif::error << "CoreController::CoreController: sdCardInit failed with exception " << + sif::error << "CoreController::CoreController: Failed with exception " << e.what() << std::endl; } - - initBootCopy(); } ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { @@ -68,7 +70,7 @@ ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t CoreController::sdCardInit() { +ReturnValue_t CoreController::initSdCard() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE sif::info << "No SD card initialization will be performed" << std::endl; return HasReturnvaluesIF::RETURN_OK; @@ -376,12 +378,15 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId, } ReturnValue_t CoreController::initBootCopy() { - // We could create this file even before the OBSW is started.. std::string fileName = "/tmp/curr_copy.txt"; - std::string cmd = "xsc_boot_copy > " + fileName; - int result = std::system(cmd.c_str()); - if(result != 0) { - utility::handleSystemError(result, "CoreController::initBootCopy"); + if(not std::filesystem::exists(fileName)) { + // Thils file is created by the systemd service eive-early-config so this should + // not happen normally + std::string cmd = "xsc_boot_copy > " + fileName; + int result = std::system(cmd.c_str()); + if(result != 0) { + utility::handleSystemError(result, "CoreController::initBootCopy"); + } } std::ifstream file(fileName); std::string line; @@ -390,10 +395,8 @@ ReturnValue_t CoreController::initBootCopy() { int value = 0; iss >> value; currentChip = static_cast(value); - sif::debug << "Current chip: " << currentChip << std::endl; iss >> value; currentCopy = static_cast(value); - sif::debug << "Current chip: " << currentCopy << std::endl; return HasReturnvaluesIF::RETURN_OK; } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index add107e7..34d72be4 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -55,14 +55,14 @@ private: ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); - ReturnValue_t sdCardInit(); + ReturnValue_t initSdCard(); ReturnValue_t sdCardSetup(SdCardManager& sdcMan, SdCardManager::SdStatusPair& statusPair, sd::SdCard sdCard, sd::SdStatus status, std::string sdString); ReturnValue_t sdCardColdRedundantInit(SdCardManager* sdcMan, SdCardManager::SdStatusPair& statusPair); ReturnValue_t initVersionFile(); - static ReturnValue_t initBootCopy(); + ReturnValue_t initBootCopy(); ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size); -- 2.43.0 From 190590e1b5270377e770bf337cc6f94e07702279 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 28 Jul 2021 20:11:22 +0200 Subject: [PATCH 051/116] new conf option --- bsp_q7s/boardconfig/q7sConfig.h.in | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bsp_q7s/boardconfig/q7sConfig.h.in b/bsp_q7s/boardconfig/q7sConfig.h.in index 2fd52eb7..61e924d8 100644 --- a/bsp_q7s/boardconfig/q7sConfig.h.in +++ b/bsp_q7s/boardconfig/q7sConfig.h.in @@ -5,9 +5,9 @@ #cmakedefine01 Q7S_SIMPLE_MODE -#define Q7S_SD_NONE 0 -#define Q7S_SD_COLD_REDUNDANT 1 -#define Q7S_SD_HOT_REDUNDANT 2 +#define Q7S_SD_NONE 0 +#define Q7S_SD_COLD_REDUNDANT 1 +#define Q7S_SD_HOT_REDUNDANT 2 // The OBSW will perform different actions to set up the SD cards depending on the flag set here // Set to Q7S_SD_NONE: Don't do anything // Set to Q7S_COLD_REDUNDANT: On startup, get the prefered SD card, turn it on and mount it, and @@ -15,7 +15,9 @@ // Set to Q7S_HOT_REDUNDANT: On startup, turn on both SD cards and mount them #define Q7S_SD_CARD_CONFIG Q7S_SD_COLD_REDUNDANT -#define Q7S_ADD_RTD_DEVICES 0 +// Probably better if this is disabled for mission code. Convenient for development +#define Q7S_CHECK_FOR_ALREADY_RUNNING_IMG 1 +#define Q7S_ADD_RTD_DEVICES 0 /* Only one of those 2 should be enabled! */ /* Add code for ACS board */ -- 2.43.0 From 6cd4f6cfe3cae85854b0b1535f977c2e22938f6f Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Thu, 29 Jul 2021 09:21:33 +0200 Subject: [PATCH 052/116] ploc supervisor mram dump --- mission/devices/PlocSupervisorHandler.cpp | 16 ++++++++++++++++ mission/devices/PlocSupervisorHandler.h | 1 + tmtc | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index a86993b0..cfb9ef3a 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -194,6 +194,11 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( prepareWipeMramCmd(commandData); result = RETURN_OK; break; + } + case(PLOC_SPV::DUMP_MRAM): { + prepareDumpMramCmd(commandData); + result = RETURN_OK; + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -242,6 +247,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::SELECT_NVM); this->insertInCommandMap(PLOC_SPV::RUN_AUTO_EM_TESTS); this->insertInCommandMap(PLOC_SPV::WIPE_MRAM); + this->insertInCommandMap(PLOC_SPV::DUMP_MRAM); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -1099,6 +1105,16 @@ void PlocSupervisorHandler::prepareWipeMramCmd(const uint8_t* commandData) { packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } +void PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandData) { + uint32_t start = 0; + uint32_t stop = 0; + size_t size = sizeof(start) + sizeof(stop); + SerializeAdapter::deSerialize(&start, &commandData, &size, SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&stop, &commandData, &size, SerializeIF::Endianness::BIG); + PLOC_SPV::MramCmd packet(start, stop, PLOC_SPV::MramCmd::MramAction::DUMP); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { memcpy(commandBuffer, packetData, fullSize); rawPacket = commandBuffer; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index 723f8cfe..9736d1a2 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -237,6 +237,7 @@ private: void prepareSelectNvmCmd(const uint8_t* commandData); ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData); void prepareWipeMramCmd(const uint8_t* commandData); + void prepareDumpMramCmd(const uint8_t* commandData); /** diff --git a/tmtc b/tmtc index 6601233f..1b1f26ac 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6601233f419fd395111c9f98043f3e687ee23dc3 +Subproject commit 1b1f26ac3a948a320a29a16083613ea29789a378 -- 2.43.0 From 59bcf6cec20baf94114cd4211c39d886e2f7c3bb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 11:35:20 +0200 Subject: [PATCH 053/116] added eive-watchdog --- CMakeLists.txt | 74 +++++--- .../Q7S/simple/simple_make_debug_cfg.sh | 2 +- .../Q7S/simple/simple_ninja_debug_cfg.sh | 2 +- watchdog/CMakeLists.txt | 4 + watchdog/Watchdog.cpp | 161 ++++++++++++++++++ watchdog/Watchdog.h | 37 ++++ watchdog/main.cpp | 15 ++ watchdog/watchdogConf.h.in | 16 ++ 8 files changed, 283 insertions(+), 28 deletions(-) create mode 100644 watchdog/CMakeLists.txt create mode 100644 watchdog/Watchdog.cpp create mode 100644 watchdog/Watchdog.h create mode 100644 watchdog/main.cpp create mode 100644 watchdog/watchdogConf.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index b7dbea87..49d0d42b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,8 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_SCRIPT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") if(TGT_BSP MATCHES "arm/q7s") - option(Q7S_SIMPLE_MODE OFF "Simple mode with a minimal main function") + option(BUILD_WATCHDOG "Compile the OBSW watchdog insted" OFF) + option(BUILD_Q7S_SIMPLE_MODE OFF "Simple mode with a minimal main function") endif() option(ADD_ETL_LIB "Add ETL library" ON) @@ -32,8 +33,13 @@ endif() include(${CMAKE_SCRIPT_PATH}/PreProjectConfig.cmake) pre_project_config() +set(PROJECT_NAME_TO_SET eive-obsw) +if(BUILD_WATCHDOG) + set(PROJECT_NAME_TO_SET eive-watchdog) +endif() + # Project Name -project(eive_obsw ASM C CXX) +project(${PROJECT_NAME_TO_SET} ASM C CXX) ################################################################################ # Pre-Sources preparation @@ -60,6 +66,7 @@ set(MISSION_PATH mission) set(TEST_PATH test/testtasks) set(LINUX_PATH linux) set(COMMON_PATH common) +set(WATCHDOG_PATH watchdog) set(COMMON_CONFIG_PATH ${COMMON_PATH}/config) set(FSFW_HAL_LIB_PATH fsfw_hal) @@ -82,7 +89,7 @@ if(TGT_BSP) OR TGT_BSP MATCHES "arm/beagleboneblack" ) set(FSFW_CONFIG_PATH "linux/fsfwconfig") - if(NOT Q7S_SIMPLE_MODE) + if(NOT BUILD_Q7S_SIMPLE_MODE) set(ADD_LINUX_FILES TRUE) set(ADD_CSP_LIB TRUE) set(FSFW_HAL_ADD_LINUX ON) @@ -107,13 +114,17 @@ else() endif() # Configuration files -configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h) -configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h) -configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h) -if(${TGT_BSP} MATCHES "arm/q7s") - configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h) -elseif(${TGT_BSP} MATCHES "arm/raspberrypi") - configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h) +if(NOT BUILD_WATCHDOG) + configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h) + configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h) + configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h) + if(${TGT_BSP} MATCHES "arm/q7s") + configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h) + elseif(${TGT_BSP} MATCHES "arm/raspberrypi") + configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h) + endif() +else() + configure_file(${WATCHDOG_PATH}/watchdogConf.h.in watchdogConf.h) endif() # Set common config path for FSFW @@ -131,26 +142,27 @@ set(LWGPS_CONFIG_PATH "${COMMON_PATH}/config") # Add executable add_executable(${TARGET_NAME}) -if(ADD_CSP_LIB) - add_subdirectory(${CSP_LIB_PATH}) -endif() - if(ADD_ETL_LIB) add_subdirectory(${ETL_LIB_PATH}) endif() -if(ADD_LINUX_FILES) - add_subdirectory(${LINUX_PATH}) -endif() - if(ADD_JSON_LIB) add_subdirectory(${LIB_JSON_PATH}) endif() -add_subdirectory(${BSP_PATH}) -add_subdirectory(${COMMON_PATH}) +if(ADD_CSP_LIB) + add_subdirectory(${CSP_LIB_PATH}) +endif() -if(NOT Q7S_SIMPLE_MODE) +if(NOT BUILD_WATCHDOG) + if(ADD_LINUX_FILES) + add_subdirectory(${LINUX_PATH}) + endif() + add_subdirectory(${BSP_PATH}) + add_subdirectory(${COMMON_PATH}) +endif() + +if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT BUILD_WATCHDOG)) add_subdirectory(${LWGPS_LIB_PATH}) add_subdirectory(${FSFW_PATH}) add_subdirectory(${MISSION_PATH}) @@ -158,6 +170,9 @@ if(NOT Q7S_SIMPLE_MODE) add_subdirectory(${ARCSEC_LIB_PATH}) endif() +if(BUILD_WATCHDOG) + add_subdirectory(${WATCHDOG_PATH}) +endif() ################################################################################ # Post-Sources preparation @@ -165,14 +180,13 @@ endif() set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux) -if(NOT Q7S_SIMPLE_MODE) +if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT BUILD_WATCHDOG)) # Add libraries for all sources. target_link_libraries(${TARGET_NAME} PRIVATE ${LIB_FSFW_NAME} ${LIB_OS_NAME} ${LIB_LWGPS_NAME} ${LIB_ARCSEC} - ${LIB_CXX_FS} ) endif() @@ -194,6 +208,10 @@ if(ADD_JSON_LIB) ) endif() +target_link_libraries(${TARGET_NAME} PRIVATE + ${LIB_CXX_FS} +) + # Add include paths for all sources. target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} @@ -249,10 +267,14 @@ if(NOT CMAKE_SIZE) endif() endif() -if(TGT_BSP) - set(TARGET_STRING "Target BSP: ${TGT_BSP}") +if(BUILD_WATCHDOG) + set(TARGET_STRING "OBSW Watchdog") else() - set(TARGET_STRING "Target BSP: Hosted") + if(TGT_BSP) + set(TARGET_STRING "Target BSP: ${TGT_BSP}") + else() + set(TARGET_STRING "Target BSP: Hosted") + endif() endif() string(CONCAT POST_BUILD_COMMENT diff --git a/cmake/scripts/Q7S/simple/simple_make_debug_cfg.sh b/cmake/scripts/Q7S/simple/simple_make_debug_cfg.sh index 8a6c7b3f..50b87101 100755 --- a/cmake/scripts/Q7S/simple/simple_make_debug_cfg.sh +++ b/cmake/scripts/Q7S/simple/simple_make_debug_cfg.sh @@ -18,7 +18,7 @@ os_fsfw="linux" tgt_bsp="arm/q7s" build_dir="build-Simple-Q7S" build_generator="" -definitions="Q7S_SIMPLE_MODE=On" +definitions="BUILD_Q7S_SIMPLE_MODE=On" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" python="py" diff --git a/cmake/scripts/Q7S/simple/simple_ninja_debug_cfg.sh b/cmake/scripts/Q7S/simple/simple_ninja_debug_cfg.sh index 965aae45..c97b1e54 100755 --- a/cmake/scripts/Q7S/simple/simple_ninja_debug_cfg.sh +++ b/cmake/scripts/Q7S/simple/simple_ninja_debug_cfg.sh @@ -18,7 +18,7 @@ os_fsfw="linux" tgt_bsp="arm/q7s" build_dir="build-Simple-Q7S" build_generator="Ninja" -definitions="Q7S_SIMPLE_MODE=On" +definitions="BUILD_Q7S_SIMPLE_MODE=On" if [ "${OS}" = "Windows_NT" ]; then python="py" # Could be other OS but this works for now. diff --git a/watchdog/CMakeLists.txt b/watchdog/CMakeLists.txt new file mode 100644 index 00000000..0179053c --- /dev/null +++ b/watchdog/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${TARGET_NAME} PRIVATE + main.cpp + Watchdog.cpp +) diff --git a/watchdog/Watchdog.cpp b/watchdog/Watchdog.cpp new file mode 100644 index 00000000..e66a2545 --- /dev/null +++ b/watchdog/Watchdog.cpp @@ -0,0 +1,161 @@ +#include "Watchdog.h" +#include "watchdogConf.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + + +WatchdogTask::WatchdogTask (): fd(0) { + +} + +WatchdogTask::~WatchdogTask() { + +} + +int WatchdogTask::performOperation() { + int result = 0; + // Only create the FIFO if it does not exist yet + if(not std::filesystem::exists(watchdog::FIFO_NAME)) { + // Permission 666 or rw-rw-rw- + mode_t mode = DEFFILEMODE; + result = mkfifo(watchdog::FIFO_NAME.c_str(), mode); + if(result != 0) { + std::cerr << "eive-watchdog: Could not created named pipe at " << + watchdog::FIFO_NAME << ", error " << errno << ": " << strerror(errno) << + std::endl; + return -2; + } +#if WATCHDOG_VERBOSE_LEVEL >= 1 + std::cout << "eive-watchdog: Pipe at " << watchdog::FIFO_NAME << + " created successfully" << std::endl; +#endif + } + + // Open FIFO read only and non-blocking + fd = open(watchdog::FIFO_NAME.c_str(), O_RDONLY | O_NONBLOCK); + if(fd < 0) { + std::cerr << "eive-watchdog: Opening pipe " << watchdog::FIFO_NAME << + "read-only failed with " << errno << ": " << strerror(errno) << std::endl; + } + + while(true) { + WatchdogTask::LoopResult loopResult = watchdogLoop(); + switch(loopResult) { + case(LoopResult::OK): { + break; + } + case(LoopResult::CANCEL_RQ): { + if(state == States::RUNNING) { + state = States::SUSPENDED; + } + break; + } + case(LoopResult::TIMEOUT): { + std::cout << "eive-watchdog: The FIFO timed out!" << std::endl; + break; + } + case(LoopResult::RESTART_RQ): { + if(state == States::SUSPENDED) { + state = States::RUNNING; + } + break; + } + } + } + if (close(fd) < 0) { + std::cerr << "eive-watchdog: Closing named pipe at " << watchdog::FIFO_NAME << + "failed, error " << errno << ": " << strerror(errno) << std::endl; + } + std::cout << "eive-watchdog: Finished" << std::endl; + return 0; +} + +WatchdogTask::LoopResult WatchdogTask::watchdogLoop() { + using namespace std::chrono_literals; + char readChar; + struct pollfd waiter = {}; + waiter.fd = fd; + waiter.events = POLLIN; + + switch(state) { + case(States::SUSPENDED): { + // Sleep, then check whether a restart request was received + std::this_thread::sleep_for(1000ms); + break; + } + case(States::RUNNING): { + // Continue as usual + break; + } + case(States::NOT_STARTED): { + // This should not happen + std::cerr << "eive-watchdog: State is NOT_STARTED, configuration error" << std::endl; + break; + } + case(States::FAULTY): { + // TODO: Not sure what to do yet. Continue for now + break; + } + } + + // 10 seconds timeout, only poll one file descriptor + switch(poll(&waiter, 1, watchdog::TIMEOUT_MS)) { + case(0): { + return LoopResult::TIMEOUT; + } + case(1): { + if (waiter.revents & POLLIN) { + ssize_t readLen = read(fd, buf.data(), buf.size()); + if (readLen < 0) { + std::cerr << "eive-watchdog: Read error on pipe " << watchdog::FIFO_NAME << + ", error " << errno << ": " << strerror(errno) << std::endl; + break; + } + for(ssize_t idx = 0; idx < readLen; idx++) { + readChar = buf[idx]; + // Cancel request + if(readChar == 'c') { + return LoopResult::CANCEL_RQ; + } + // Begin request. Does not work if the operation was not suspended before + else if(readChar == 'b') { + return LoopResult::RESTART_RQ; + } + // Everything else: All working as expected + else { + + } + } +#if WATCHDOG_VERBOSE_LEVEL == 2 + std::cout << "Read " << readLen << " byte(s) on the pipe " << FIFO_NAME + << std::endl; +#endif + } + else if(waiter.revents & POLLERR) { + std::cerr << "eive-watchdog: Poll error error on pipe " << watchdog::FIFO_NAME << + std::endl; + } + else if (waiter.revents & POLLHUP) { + // Writer closed its end + } + break; + } + default: { + std::cerr << "eive-watchdog: Unknown poll error at " << watchdog::FIFO_NAME << ", error " << + errno << ": " << strerror(errno) << std::endl; + break; + } + } + return LoopResult::OK; +} diff --git a/watchdog/Watchdog.h b/watchdog/Watchdog.h new file mode 100644 index 00000000..53935fc2 --- /dev/null +++ b/watchdog/Watchdog.h @@ -0,0 +1,37 @@ +#ifndef WATCHDOG_WATCHDOG_H_ +#define WATCHDOG_WATCHDOG_H_ + +#include + + +class WatchdogTask { +public: + enum class States { + NOT_STARTED, + RUNNING, + SUSPENDED, + FAULTY + }; + + enum class LoopResult { + OK, + CANCEL_RQ, + RESTART_RQ, + TIMEOUT + }; + + WatchdogTask(); + + virtual ~WatchdogTask(); + + int performOperation(); +private: + int fd = 0; + + std::array buf; + States state = States::NOT_STARTED; + + LoopResult watchdogLoop(); +}; + +#endif /* WATCHDOG_WATCHDOG_H_ */ diff --git a/watchdog/main.cpp b/watchdog/main.cpp new file mode 100644 index 00000000..eea608f1 --- /dev/null +++ b/watchdog/main.cpp @@ -0,0 +1,15 @@ +#include "Watchdog.h" + +#include + +/** + * @brief This watchdog application uses a FIFO to check whether the OBSW is still running. + * It checks whether the OBSW writes to the the FIFO regularly. + */ +int main() { + std::cout << "Starting OBSW watchdog.." << std::endl; + WatchdogTask watchdogTask; + watchdogTask.performOperation(); + return 0; +} + diff --git a/watchdog/watchdogConf.h.in b/watchdog/watchdogConf.h.in new file mode 100644 index 00000000..8b9a0afc --- /dev/null +++ b/watchdog/watchdogConf.h.in @@ -0,0 +1,16 @@ +#include + +#define WATCHDOG_VERBOSE_LEVEL 1 +/** + * This flag instructs the watchdog to create a special file in /tmp if the OBSW is running + * or to delete it if it is not running + */ +#define WATCHDOG_CREATE_FILE_IF_RUNNING 1 + +namespace watchdog { + +static constexpr int TIMEOUT_MS = 10 * 1000; +const std::string FIFO_NAME = "/tmp/obsw-watchdog"; +const std::string RUNNING_FILE_NAME = "/tmp/obsw-running"; + +} -- 2.43.0 From 55727accf5e35f81371214f74ac18faaa9a33e95 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 11:59:32 +0200 Subject: [PATCH 054/116] minor tweaks --- watchdog/Watchdog.cpp | 18 ++++++++---------- watchdog/main.cpp | 11 ++++++++--- watchdog/watchdogConf.h.in | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/watchdog/Watchdog.cpp b/watchdog/Watchdog.cpp index e66a2545..f4f8c03c 100644 --- a/watchdog/Watchdog.cpp +++ b/watchdog/Watchdog.cpp @@ -14,16 +14,7 @@ #include - WatchdogTask::WatchdogTask (): fd(0) { - -} - -WatchdogTask::~WatchdogTask() { - -} - -int WatchdogTask::performOperation() { int result = 0; // Only create the FIFO if it does not exist yet if(not std::filesystem::exists(watchdog::FIFO_NAME)) { @@ -34,20 +25,27 @@ int WatchdogTask::performOperation() { std::cerr << "eive-watchdog: Could not created named pipe at " << watchdog::FIFO_NAME << ", error " << errno << ": " << strerror(errno) << std::endl; - return -2; + throw std::runtime_error("eive-watchdog: FIFO creation failed"); } #if WATCHDOG_VERBOSE_LEVEL >= 1 std::cout << "eive-watchdog: Pipe at " << watchdog::FIFO_NAME << " created successfully" << std::endl; #endif } +} +WatchdogTask::~WatchdogTask() { + +} + +int WatchdogTask::performOperation() { // Open FIFO read only and non-blocking fd = open(watchdog::FIFO_NAME.c_str(), O_RDONLY | O_NONBLOCK); if(fd < 0) { std::cerr << "eive-watchdog: Opening pipe " << watchdog::FIFO_NAME << "read-only failed with " << errno << ": " << strerror(errno) << std::endl; } + state = States::RUNNING; while(true) { WatchdogTask::LoopResult loopResult = watchdogLoop(); diff --git a/watchdog/main.cpp b/watchdog/main.cpp index eea608f1..a1ae3ae8 100644 --- a/watchdog/main.cpp +++ b/watchdog/main.cpp @@ -7,9 +7,14 @@ * It checks whether the OBSW writes to the the FIFO regularly. */ int main() { - std::cout << "Starting OBSW watchdog.." << std::endl; - WatchdogTask watchdogTask; - watchdogTask.performOperation(); + std::cout << "eive-watchdog: Starting OBSW watchdog.." << std::endl; + try { + WatchdogTask watchdogTask; + watchdogTask.performOperation(); + } + catch(const std::runtime_error& e) { + std::cerr << "eive-watchdog: Run time exception " << e.what() << std::endl; + } return 0; } diff --git a/watchdog/watchdogConf.h.in b/watchdog/watchdogConf.h.in index 8b9a0afc..daa9f248 100644 --- a/watchdog/watchdogConf.h.in +++ b/watchdog/watchdogConf.h.in @@ -10,7 +10,7 @@ namespace watchdog { static constexpr int TIMEOUT_MS = 10 * 1000; -const std::string FIFO_NAME = "/tmp/obsw-watchdog"; +const std::string FIFO_NAME = "/tmp/watchdog-pipe"; const std::string RUNNING_FILE_NAME = "/tmp/obsw-running"; } -- 2.43.0 From 6361fcb6bb32a3c150a6e82538393d11f8957e79 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Thu, 29 Jul 2021 12:06:14 +0200 Subject: [PATCH 055/116] added Jenkinsfile, moved together with Dockerfile into automation folder having the automation files in an empty folder accelerates docker build. Also, I think these files are not related to the source code and as such should live in their own space --- automation/Dockerfile-q7s | 18 ++++++++++++++ automation/Jenkinsfile | 49 +++++++++++++++++++++++++++++++++++++++ bsp_q7s/Dockerfile | 35 ---------------------------- 3 files changed, 67 insertions(+), 35 deletions(-) create mode 100644 automation/Dockerfile-q7s create mode 100644 automation/Jenkinsfile delete mode 100644 bsp_q7s/Dockerfile diff --git a/automation/Dockerfile-q7s b/automation/Dockerfile-q7s new file mode 100644 index 00000000..207afa04 --- /dev/null +++ b/automation/Dockerfile-q7s @@ -0,0 +1,18 @@ +FROM ubuntu:focal + +RUN apt-get update +RUN apt-get --yes upgrade +RUN apt-get --yes install cmake libgpiod-dev xz-utils nano curl + +# Q7S root filesystem, required for cross-compilation. +RUN mkdir -p /usr/rootfs; \ +curl https://buggy.irs.uni-stuttgart.de/eive/tools/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz \ + | tar -xz -C /usr/rootfs + +# Cross compiler +RUN mkdir -p /usr/tools; \ +curl https://buggy.irs.uni-stuttgart.de/eive/tools/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.gz \ + | tar -xz -C /usr/tools + +ENV Q7S_SYSROOT="/usr/rootfs/cortexa9hf-neon-xiphos-linux-gnueabi" +ENV PATH=$PATH:"/usr/tools/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin" diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile new file mode 100644 index 00000000..8b735710 --- /dev/null +++ b/automation/Jenkinsfile @@ -0,0 +1,49 @@ +pipeline { + agent any + stages { + stage('Build Container') { + when { + changeset "automation/Dockerfile-q7s" + branch 'develop' + } + steps { + sh 'docker build -t eive-fsw-build-q7s:gcc8 - < automation/Dockerfile-q7s' + + } + } + stage('Clean') { + when { + anyof { + changelog 'cleanCI' + changeset '*.cmake' + changeset 'CMakeLists.txt' + } + } + steps { + sh 'rm -rf build-q7s-debug' + } + } + stage('Build Q7S') { + agent { + docker { + image 'eive-fsw-build-q7s:gcc8' + reuseNode true + } + } + steps { + dir('build-q7s-debug') { + sh 'cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DFSFW_OSAL=linux ..' + sh 'cmake --build . -j' + } + } + } + stage('Deploy') { + when { + tag 'v*.*.*' + } + steps { + sh 'echo Deploying' + } + } + } +} diff --git a/bsp_q7s/Dockerfile b/bsp_q7s/Dockerfile deleted file mode 100644 index 04184c4a..00000000 --- a/bsp_q7s/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM ubuntu:latest -# FROM alpine:latest - -ENV TZ=Europe/Berlin -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone - -RUN apt-get update && apt-get install -y curl cmake g++ - -# Q7S root filesystem, required for cross-compilation. Use IPv6 for curl -RUN mkdir -p /usr/rootfs; \ - curl -6 https://eive-cloud.irs.uni-stuttgart.de/index.php/s/dnfMy9kGpgynN6J/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz \ - | tar xvz -C /usr/rootfs -# Q7S C++ cross-compiler. Use IPv6 for curl -RUN mkdir -p /usr/tools; \ - curl -6 https://eive-cloud.irs.uni-stuttgart.de/index.php/s/RMsbHydJc6PSqcz/download/gcc-arm-linux-gnueabi.tar.gz \ - | tar xvz -C /usr/tools - -# RUN apk add cmake make g++ - -# Required for cmake build -ENV Q7S_SYSROOT="/usr/rootfs/cortexa9hf-neon-xiphos-linux-gnueabi" -ENV PATH=$PATH:"/usr/tools/gcc-arm-linux-gnueabi/bin" - -WORKDIR /usr/src/app -COPY . . - -RUN set -ex; \ - rm -rf build-q7s; \ - mkdir build-q7s; \ - cd build-q7s; \ - cmake -DCMAKE_BUILD_TYPE=Release -DOS_FSFW=linux -DTGT_BSP="arm/q7s" ..; - -ENTRYPOINT ["cmake", "--build", "build-q7s"] -CMD ["-j"] -# CMD ["bash"] -- 2.43.0 From afb7a2008f8267d118e34e23b1e90deb8d5e1d0f Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Thu, 29 Jul 2021 12:14:37 +0200 Subject: [PATCH 056/116] typo in Jenkinsfile --- automation/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile index 8b735710..52cd895b 100644 --- a/automation/Jenkinsfile +++ b/automation/Jenkinsfile @@ -13,7 +13,7 @@ pipeline { } stage('Clean') { when { - anyof { + anyOf { changelog 'cleanCI' changeset '*.cmake' changeset 'CMakeLists.txt' -- 2.43.0 From acaf87095aa504c8ceb603e3e4eca9516eecbc47 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Thu, 29 Jul 2021 12:17:30 +0200 Subject: [PATCH 057/116] forcing docker build --- automation/Dockerfile-q7s | 1 + 1 file changed, 1 insertion(+) diff --git a/automation/Dockerfile-q7s b/automation/Dockerfile-q7s index 207afa04..21b56439 100644 --- a/automation/Dockerfile-q7s +++ b/automation/Dockerfile-q7s @@ -14,5 +14,6 @@ RUN mkdir -p /usr/tools; \ curl https://buggy.irs.uni-stuttgart.de/eive/tools/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.gz \ | tar -xz -C /usr/tools + ENV Q7S_SYSROOT="/usr/rootfs/cortexa9hf-neon-xiphos-linux-gnueabi" ENV PATH=$PATH:"/usr/tools/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin" -- 2.43.0 From af6f24d66866c4cc6e512bfab35cf89ccb9c94d6 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Thu, 29 Jul 2021 12:18:32 +0200 Subject: [PATCH 058/116] forcing docker build #2 --- automation/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile index 52cd895b..70db7d41 100644 --- a/automation/Jenkinsfile +++ b/automation/Jenkinsfile @@ -4,7 +4,7 @@ pipeline { stage('Build Container') { when { changeset "automation/Dockerfile-q7s" - branch 'develop' + branch 'mohr_ci' } steps { sh 'docker build -t eive-fsw-build-q7s:gcc8 - < automation/Dockerfile-q7s' -- 2.43.0 From 6c8336bcfedc629b0ae95694cd00ec6269da1963 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Thu, 29 Jul 2021 12:20:02 +0200 Subject: [PATCH 059/116] something's broken with the automatic docker build, reverting change, will look into it later --- automation/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile index 70db7d41..52cd895b 100644 --- a/automation/Jenkinsfile +++ b/automation/Jenkinsfile @@ -4,7 +4,7 @@ pipeline { stage('Build Container') { when { changeset "automation/Dockerfile-q7s" - branch 'mohr_ci' + branch 'develop' } steps { sh 'docker build -t eive-fsw-build-q7s:gcc8 - < automation/Dockerfile-q7s' -- 2.43.0 From 93fa82c4135b173de84efa34226ecfe51b788dc5 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Thu, 29 Jul 2021 12:23:17 +0200 Subject: [PATCH 060/116] copy pasted wrong cmake line --- automation/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile index 52cd895b..7b184280 100644 --- a/automation/Jenkinsfile +++ b/automation/Jenkinsfile @@ -32,7 +32,7 @@ pipeline { } steps { dir('build-q7s-debug') { - sh 'cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DFSFW_OSAL=linux ..' + sh 'cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DFSFW_OSAL=linux ..' sh 'cmake --build . -j' } } -- 2.43.0 From 12be969ca2562649228caba9f043f087f56a1107 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Thu, 29 Jul 2021 12:34:01 +0200 Subject: [PATCH 061/116] jenkins seems to overwrite out PATH --- automation/Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile index 7b184280..43bf8728 100644 --- a/automation/Jenkinsfile +++ b/automation/Jenkinsfile @@ -32,6 +32,8 @@ pipeline { } steps { dir('build-q7s-debug') { + sh 'echo $PATH' + sh 'export PATH=$PATH:/usr/tools/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin' sh 'cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DFSFW_OSAL=linux ..' sh 'cmake --build . -j' } -- 2.43.0 From 4fbfbe8bb86f5908374f2674398ee1bb8d88dff3 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Thu, 29 Jul 2021 12:38:24 +0200 Subject: [PATCH 062/116] cleanCI --- automation/Jenkinsfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/automation/Jenkinsfile b/automation/Jenkinsfile index 43bf8728..7b184280 100644 --- a/automation/Jenkinsfile +++ b/automation/Jenkinsfile @@ -32,8 +32,6 @@ pipeline { } steps { dir('build-q7s-debug') { - sh 'echo $PATH' - sh 'export PATH=$PATH:/usr/tools/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin' sh 'cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug -DFSFW_OSAL=linux ..' sh 'cmake --build . -j' } -- 2.43.0 From 983ce045a9af75eae0d9ebcab469c1c3b46c764f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 13:07:07 +0200 Subject: [PATCH 063/116] continued --- CMakeLists.txt | 3 +-- bsp_q7s/core/obsw.cpp | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 49d0d42b..5e49dd9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,9 +123,8 @@ if(NOT BUILD_WATCHDOG) elseif(${TGT_BSP} MATCHES "arm/raspberrypi") configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h) endif() -else() - configure_file(${WATCHDOG_PATH}/watchdogConf.h.in watchdogConf.h) endif() +configure_file(${WATCHDOG_PATH}/watchdogConf.h.in watchdogConf.h) # Set common config path for FSFW set(FSFW_ADDITIONAL_INC_PATHS diff --git a/bsp_q7s/core/obsw.cpp b/bsp_q7s/core/obsw.cpp index 4a13e178..64b0b422 100644 --- a/bsp_q7s/core/obsw.cpp +++ b/bsp_q7s/core/obsw.cpp @@ -20,6 +20,9 @@ int obsw::obsw() { FSFW_REVISION << "--" << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; +#if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1 + // Check special file here +#endif initmission::initMission(); for(;;) { -- 2.43.0 From ff86c8af7385a13cd64141a27e7d1de4fe0eb051 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 16:31:04 +0200 Subject: [PATCH 064/116] watchdog handling finished --- CMakeLists.txt | 13 +-- bsp_q7s/core/CoreController.cpp | 41 ++++++++++ bsp_q7s/core/CoreController.h | 2 + bsp_q7s/core/obsw.cpp | 12 ++- linux/fsfwconfig/OBSWConfig.h.in | 4 + watchdog/Watchdog.cpp | 133 ++++++++++++++++++++++--------- watchdog/Watchdog.h | 11 ++- watchdog/watchdogConf.h.in | 8 ++ 8 files changed, 179 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e49dd9a..7e5e4482 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,17 +96,20 @@ if(TGT_BSP) endif() endif() - if(${TGT_BSP} MATCHES "arm/raspberrypi") - add_definitions(-DRASPBERRY_PI) + if(${TGT_BSP} MATCHES "arm/raspberrypi") + # Used by configure file + set(RASPBERRY_PI ON) set(FSFW_HAL_ADD_RASPBERRY_PI ON) endif() - if(${TGT_BSP} MATCHES "arm/beagleboneblack") - add_definitions(-DBEAGLEBONEBLACK) + if(${TGT_BSP} MATCHES "arm/beagleboneblack") + # Used by configure file + set(BEAGLEBONEBLACK ON) endif() if(${TGT_BSP} MATCHES "arm/q7s") - add_definitions(-DXIPHOS_Q7S) + # Used by configure file + set(XIPHOS_Q7S ON) endif() else() # Required by FSFW library diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index a37db440..bdfac5f8 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -1,6 +1,7 @@ #include "CoreController.h" #include "OBSWConfig.h" #include "OBSWVersion.h" +#include "watchdogConf.h" #include "fsfw/FSFWVersion.h" #include "fsfw/serviceinterface/ServiceInterface.h" @@ -13,6 +14,9 @@ #include "bsp_q7s/memory/scratchApi.h" #include "bsp_q7s/memory/SdCardManager.h" +#include +#include + #include CoreController::Chip CoreController::currentChip = Chip::NO_CHIP; @@ -22,6 +26,11 @@ CoreController::CoreController(object_id_t objectId): ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; try { + result = initWatchdogFifo(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::CoreController: Watchdog FIFO init failed" << + std::endl; + } result = initSdCard(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; @@ -30,6 +39,7 @@ CoreController::CoreController(object_id_t objectId): if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::CoreController: Boot copy init" << std::endl; } + } catch(const std::filesystem::filesystem_error& e) { sif::error << "CoreController::CoreController: Failed with exception " << @@ -42,6 +52,16 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { + if(watchdogFifoFd != 0) { + // Write to OBSW watchdog FIFO here + const char writeChar = 'a'; + std::cout << "Writing to FIFO.." << std::endl; + ssize_t writtenBytes = write(watchdogFifoFd, &writeChar, 1); + if(writtenBytes < 0) { + sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " << + strerror(errno) << std::endl; + } + } } ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, @@ -406,6 +426,23 @@ void CoreController::getCurrentBootCopy(Chip &chip, Copy ©) { copy = currentCopy; } +ReturnValue_t CoreController::initWatchdogFifo() { + if(not std::filesystem::exists(watchdog::FIFO_NAME)) { + // Still return RETURN_OK for now + sif::info << "Watchdog FIFO " << watchdog::FIFO_NAME << " does not exist, can't initiate" << + " watchdog" << std::endl; + return HasReturnvaluesIF::RETURN_OK; + } + // Open FIFO write only and non-blocking + watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY); + if(watchdogFifoFd < 0) { + std::cerr << "Opening pipe " << watchdog::FIFO_NAME << "write-only failed with " << + errno << ": " << strerror(errno) << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} + void CoreController::initPrint() { #if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_USE_TMTC_TCP_BRIDGE == 0 @@ -415,5 +452,9 @@ void CoreController::initPrint() { sif::info << "Created TCP server for TMTC commanding with listener port " << TcpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; #endif + + if(watchdogFifoFd != 0) { + sif::info << "Opened watchdog FIFO successfully.." << std::endl; + } #endif } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 34d72be4..ea212a16 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -63,12 +63,14 @@ private: ReturnValue_t initVersionFile(); ReturnValue_t initBootCopy(); + ReturnValue_t initWatchdogFifo(); ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size); void initPrint(); + int watchdogFifoFd = 0; }; diff --git a/bsp_q7s/core/obsw.cpp b/bsp_q7s/core/obsw.cpp index 64b0b422..47b7b9d2 100644 --- a/bsp_q7s/core/obsw.cpp +++ b/bsp_q7s/core/obsw.cpp @@ -2,11 +2,15 @@ #include "OBSWVersion.h" #include "OBSWConfig.h" #include "InitMission.h" +#include "watchdogConf.h" #include "fsfw/tasks/TaskFactory.h" #include "fsfw/FSFWVersion.h" #include +#include + +static int OBSW_ALREADY_RUNNING = -2; int obsw::obsw() { std::cout << "-- EIVE OBSW --" << std::endl; @@ -21,7 +25,13 @@ int obsw::obsw() { std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; #if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1 - // Check special file here + // Check special file here. This file is created or deleted by the eive-watchdog application + // or systemd service! + if(std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { + sif::warning << "File " << watchdog::RUNNING_FILE_NAME << " exists so the software might " + "already be running. Aborting.." << std::endl; + return OBSW_ALREADY_RUNNING; + } #endif initmission::initMission(); diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 16eacccf..778a1611 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -6,6 +6,10 @@ #ifndef FSFWCONFIG_OBSWCONFIG_H_ #define FSFWCONFIG_OBSWCONFIG_H_ +#cmakedefine RASPBERRY_Pi +#cmakedefine XIPHOS_Q7S +#cmakedefine BEAGLEBONEBLACK + #ifdef RASPBERRY_PI #include "rpiConfig.h" #elif defined(XIPHOS_Q7S) diff --git a/watchdog/Watchdog.cpp b/watchdog/Watchdog.cpp index f4f8c03c..21be1e1d 100644 --- a/watchdog/Watchdog.cpp +++ b/watchdog/Watchdog.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -54,21 +55,34 @@ int WatchdogTask::performOperation() { break; } case(LoopResult::CANCEL_RQ): { - if(state == States::RUNNING) { + std::cout << "eive-watchdog: Received cancel request, closing watchdog.." << std::endl; + return 0; + } + case(LoopResult::SUSPEND_RQ): { + std::cout << "eive-watchdog: Suspending watchdog operations" << std::endl; + if(state == States::RUNNING or state == States::FAULTY) { + watchdogRunning = false; state = States::SUSPENDED; } break; } case(LoopResult::TIMEOUT): { std::cout << "eive-watchdog: The FIFO timed out!" << std::endl; + performTimeoutOperation(); break; } case(LoopResult::RESTART_RQ): { - if(state == States::SUSPENDED) { + if(state == States::SUSPENDED or state == States::FAULTY) { state = States::RUNNING; + watchdogRunning = true; + performRunningOperation(); } break; } + case(LoopResult::FAULT): { + // Configuration error + std::cerr << "Fault has occured in watchdog loop" << std::endl; + } } } if (close(fd) < 0) { @@ -81,7 +95,6 @@ int WatchdogTask::performOperation() { WatchdogTask::LoopResult WatchdogTask::watchdogLoop() { using namespace std::chrono_literals; - char readChar; struct pollfd waiter = {}; waiter.fd = fd; waiter.events = POLLIN; @@ -113,41 +126,7 @@ WatchdogTask::LoopResult WatchdogTask::watchdogLoop() { return LoopResult::TIMEOUT; } case(1): { - if (waiter.revents & POLLIN) { - ssize_t readLen = read(fd, buf.data(), buf.size()); - if (readLen < 0) { - std::cerr << "eive-watchdog: Read error on pipe " << watchdog::FIFO_NAME << - ", error " << errno << ": " << strerror(errno) << std::endl; - break; - } - for(ssize_t idx = 0; idx < readLen; idx++) { - readChar = buf[idx]; - // Cancel request - if(readChar == 'c') { - return LoopResult::CANCEL_RQ; - } - // Begin request. Does not work if the operation was not suspended before - else if(readChar == 'b') { - return LoopResult::RESTART_RQ; - } - // Everything else: All working as expected - else { - - } - } -#if WATCHDOG_VERBOSE_LEVEL == 2 - std::cout << "Read " << readLen << " byte(s) on the pipe " << FIFO_NAME - << std::endl; -#endif - } - else if(waiter.revents & POLLERR) { - std::cerr << "eive-watchdog: Poll error error on pipe " << watchdog::FIFO_NAME << - std::endl; - } - else if (waiter.revents & POLLHUP) { - // Writer closed its end - } - break; + return pollEvent(waiter); } default: { std::cerr << "eive-watchdog: Unknown poll error at " << watchdog::FIFO_NAME << ", error " << @@ -157,3 +136,81 @@ WatchdogTask::LoopResult WatchdogTask::watchdogLoop() { } return LoopResult::OK; } + +WatchdogTask::LoopResult WatchdogTask::pollEvent(struct pollfd& waiter) { + if (waiter.revents & POLLIN) { + ssize_t readLen = read(fd, buf.data(), buf.size()); + if (readLen < 0) { + std::cerr << "eive-watchdog: Read error on pipe " << watchdog::FIFO_NAME << + ", error " << errno << ": " << strerror(errno) << std::endl; + return LoopResult::OK; + } +#if WATCHDOG_VERBOSE_LEVEL == 2 + std::cout << "Read " << readLen << " byte(s) on the pipe " << FIFO_NAME + << std::endl; +#endif + return parseCommandByte(readLen); + + } + else if(waiter.revents & POLLERR) { + std::cerr << "eive-watchdog: Poll error error on pipe " << watchdog::FIFO_NAME << + std::endl; + return LoopResult::FAULT; + } + else if (waiter.revents & POLLHUP) { + // Writer closed its end + } + return LoopResult::FAULT; +} + +WatchdogTask::LoopResult WatchdogTask::parseCommandByte(ssize_t readLen) { + for(ssize_t idx = 0; idx < readLen; idx++) { + char readChar = buf[idx]; + // Cancel request + if(readChar == watchdog::CANCEL_CHAR) { + return LoopResult::CANCEL_RQ; + } + // Begin request. Does not work if the operation was not suspended before + else if(readChar == watchdog::RESTART_CHAR) { + return LoopResult::RESTART_RQ; + } + // Suspend request + else if(readChar == watchdog::SUSPEND_CHAR) { + return LoopResult::SUSPEND_RQ; + } + // Everything else: All working as expected + } + return LoopResult::OK; +} + +int WatchdogTask::performRunningOperation() { + if(not obswRunning) { + obswRunning = true; +#if WATCHDOG_CREATE_FILE_IF_RUNNING == 1 + if (not std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { + std::ofstream obswRunningFile(watchdog::RUNNING_FILE_NAME); + if(not obswRunningFile.good()) { + std::cerr << "Creating file " << watchdog::RUNNING_FILE_NAME << " failed" + << std::endl; + } + } +#endif + } + return 0; +} + +int WatchdogTask::performTimeoutOperation() { +#if WATCHDOG_CREATE_FILE_IF_RUNNING == 1 + if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { + int result = std::remove(watchdog::RUNNING_FILE_NAME.c_str()); + if(result != 0) { + std::cerr << "Removing " << watchdog::RUNNING_FILE_NAME << " failed with code " << + errno << ": " << strerror(errno) << std::endl; + } + } +#endif + if(obswRunning) { + obswRunning = false; + } + return 0; +} diff --git a/watchdog/Watchdog.h b/watchdog/Watchdog.h index 53935fc2..088acc5e 100644 --- a/watchdog/Watchdog.h +++ b/watchdog/Watchdog.h @@ -15,9 +15,11 @@ public: enum class LoopResult { OK, + SUSPEND_RQ, CANCEL_RQ, RESTART_RQ, - TIMEOUT + TIMEOUT, + FAULT }; WatchdogTask(); @@ -28,10 +30,17 @@ public: private: int fd = 0; + bool obswRunning = false; + bool watchdogRunning = false; std::array buf; States state = States::NOT_STARTED; LoopResult watchdogLoop(); + LoopResult pollEvent(struct pollfd& waiter); + LoopResult parseCommandByte(ssize_t readLen); + + int performRunningOperation(); + int performTimeoutOperation(); }; #endif /* WATCHDOG_WATCHDOG_H_ */ diff --git a/watchdog/watchdogConf.h.in b/watchdog/watchdogConf.h.in index daa9f248..81faf572 100644 --- a/watchdog/watchdogConf.h.in +++ b/watchdog/watchdogConf.h.in @@ -1,4 +1,5 @@ #include +#include #define WATCHDOG_VERBOSE_LEVEL 1 /** @@ -13,4 +14,11 @@ static constexpr int TIMEOUT_MS = 10 * 1000; const std::string FIFO_NAME = "/tmp/watchdog-pipe"; const std::string RUNNING_FILE_NAME = "/tmp/obsw-running"; +// Suspend watchdog operations temporarily +static constexpr char SUSPEND_CHAR = 's'; +// Resume watchdog operations +static constexpr char RESTART_CHAR = 'b'; +// Causes the watchdog to close down +static constexpr char CANCEL_CHAR = 'c'; + } -- 2.43.0 From dba620baf2c526e79758090e7b64ca5e32fe88de Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 17:21:27 +0200 Subject: [PATCH 065/116] various bugfixes, watchdog working now --- CMakeLists.txt | 2 +- bsp_q7s/core/CoreController.cpp | 1 - linux/boardtest/SpiTestClass.cpp | 1 + watchdog/Watchdog.cpp | 44 +++++++++++++++++++++++++------- watchdog/Watchdog.h | 2 ++ watchdog/watchdogConf.h.in | 2 +- 6 files changed, 40 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e5e4482..cc476dcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,7 @@ endif() include(${CMAKE_SCRIPT_PATH}/PreProjectConfig.cmake) pre_project_config() -set(PROJECT_NAME_TO_SET eive-obsw) +set(PROJECT_NAME_TO_SET eive-obsw-$ENV{USERNAME}) if(BUILD_WATCHDOG) set(PROJECT_NAME_TO_SET eive-watchdog) endif() diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index bdfac5f8..02e0adea 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -55,7 +55,6 @@ void CoreController::performControlOperation() { if(watchdogFifoFd != 0) { // Write to OBSW watchdog FIFO here const char writeChar = 'a'; - std::cout << "Writing to FIFO.." << std::endl; ssize_t writtenBytes = write(watchdogFifoFd, &writeChar, 1); if(writtenBytes < 0) { sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " << diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index 71313f25..6f634168 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -1,4 +1,5 @@ #include "SpiTestClass.h" +#include "OBSWConfig.h" #include "devices/gpioIds.h" diff --git a/watchdog/Watchdog.cpp b/watchdog/Watchdog.cpp index 21be1e1d..9e316451 100644 --- a/watchdog/Watchdog.cpp +++ b/watchdog/Watchdog.cpp @@ -52,6 +52,7 @@ int WatchdogTask::performOperation() { WatchdogTask::LoopResult loopResult = watchdogLoop(); switch(loopResult) { case(LoopResult::OK): { + performRunningOperation(); break; } case(LoopResult::CANCEL_RQ): { @@ -59,29 +60,26 @@ int WatchdogTask::performOperation() { return 0; } case(LoopResult::SUSPEND_RQ): { - std::cout << "eive-watchdog: Suspending watchdog operations" << std::endl; - if(state == States::RUNNING or state == States::FAULTY) { - watchdogRunning = false; - state = States::SUSPENDED; - } + performSuspendOperation(); break; } case(LoopResult::TIMEOUT): { - std::cout << "eive-watchdog: The FIFO timed out!" << std::endl; performTimeoutOperation(); break; } case(LoopResult::RESTART_RQ): { if(state == States::SUSPENDED or state == States::FAULTY) { - state = States::RUNNING; - watchdogRunning = true; performRunningOperation(); } break; } case(LoopResult::FAULT): { + using namespace std::chrono_literals; // Configuration error std::cerr << "Fault has occured in watchdog loop" << std::endl; + // Prevent spam + std::this_thread::sleep_for(2000ms); + } } } @@ -149,7 +147,9 @@ WatchdogTask::LoopResult WatchdogTask::pollEvent(struct pollfd& waiter) { std::cout << "Read " << readLen << " byte(s) on the pipe " << FIFO_NAME << std::endl; #endif - return parseCommandByte(readLen); + else if(readLen >= 1) { + return parseCommandByte(readLen); + } } else if(waiter.revents & POLLERR) { @@ -184,9 +184,20 @@ WatchdogTask::LoopResult WatchdogTask::parseCommandByte(ssize_t readLen) { } int WatchdogTask::performRunningOperation() { + if(state != States::RUNNING) { + state = States::RUNNING; + } + if(not obswRunning) { + if(printTimeoutLatch) { + // Reset latch so user can see timeouts + printTimeoutLatch = false; + } + obswRunning = true; + std::cout << "eive-watchdog: Running OBSW detected.." << std::endl; #if WATCHDOG_CREATE_FILE_IF_RUNNING == 1 + std::cout << "eive-watchdog: Creating " << watchdog::RUNNING_FILE_NAME << std::endl; if (not std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { std::ofstream obswRunningFile(watchdog::RUNNING_FILE_NAME); if(not obswRunningFile.good()) { @@ -200,6 +211,12 @@ int WatchdogTask::performRunningOperation() { } int WatchdogTask::performTimeoutOperation() { + // Latch prevents spam on console + if(not printTimeoutLatch) { + std::cout << "eive-watchdog: The FIFO timed out!" << std::endl; + printTimeoutLatch = true; + } + #if WATCHDOG_CREATE_FILE_IF_RUNNING == 1 if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { int result = std::remove(watchdog::RUNNING_FILE_NAME.c_str()); @@ -214,3 +231,12 @@ int WatchdogTask::performTimeoutOperation() { } return 0; } + +int WatchdogTask::performSuspendOperation() { + if(state == States::RUNNING or state == States::FAULTY) { + std::cout << "eive-watchdog: Suspending watchdog operations" << std::endl; + watchdogRunning = false; + state = States::SUSPENDED; + } + return 0; +} diff --git a/watchdog/Watchdog.h b/watchdog/Watchdog.h index 088acc5e..649fca6e 100644 --- a/watchdog/Watchdog.h +++ b/watchdog/Watchdog.h @@ -32,6 +32,7 @@ private: bool obswRunning = false; bool watchdogRunning = false; + bool printTimeoutLatch = false; std::array buf; States state = States::NOT_STARTED; @@ -41,6 +42,7 @@ private: int performRunningOperation(); int performTimeoutOperation(); + int performSuspendOperation(); }; #endif /* WATCHDOG_WATCHDOG_H_ */ diff --git a/watchdog/watchdogConf.h.in b/watchdog/watchdogConf.h.in index 81faf572..02d84e70 100644 --- a/watchdog/watchdogConf.h.in +++ b/watchdog/watchdogConf.h.in @@ -10,7 +10,7 @@ namespace watchdog { -static constexpr int TIMEOUT_MS = 10 * 1000; +static constexpr int TIMEOUT_MS = 5 * 1000; const std::string FIFO_NAME = "/tmp/watchdog-pipe"; const std::string RUNNING_FILE_NAME = "/tmp/obsw-running"; -- 2.43.0 From 34d3479e81a2da79d1d68e4b53e0e7eb7f6b406e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 18:09:54 +0200 Subject: [PATCH 066/116] various bugfixes and improvements --- bsp_q7s/core/CoreController.cpp | 63 +++++++++++++++++++++++++-------- bsp_q7s/core/CoreController.h | 6 ++++ watchdog/Watchdog.cpp | 47 +++++++++++++++--------- watchdog/Watchdog.h | 5 +-- 4 files changed, 88 insertions(+), 33 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 02e0adea..4a9db02a 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -23,7 +23,8 @@ CoreController::Chip CoreController::currentChip = Chip::NO_CHIP; CoreController::Copy CoreController::currentCopy = Copy::NO_COPY; CoreController::CoreController(object_id_t objectId): - ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) { + ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), + opDivider(5) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; try { result = initWatchdogFifo(); @@ -52,15 +53,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - if(watchdogFifoFd != 0) { - // Write to OBSW watchdog FIFO here - const char writeChar = 'a'; - ssize_t writtenBytes = write(watchdogFifoFd, &writeChar, 1); - if(writtenBytes < 0) { - sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " << - strerror(errno) << std::endl; - } - } + performWatchdogControlOperation(); } ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, @@ -432,12 +425,18 @@ ReturnValue_t CoreController::initWatchdogFifo() { " watchdog" << std::endl; return HasReturnvaluesIF::RETURN_OK; } - // Open FIFO write only and non-blocking - watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY); + // Open FIFO write only and non-blocking to prevent SW from killing itself. + watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY | O_NONBLOCK); if(watchdogFifoFd < 0) { - std::cerr << "Opening pipe " << watchdog::FIFO_NAME << "write-only failed with " << - errno << ": " << strerror(errno) << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + if(errno == ENXIO) { + watchdogFifoFd = RETRY_FIFO_OPEN; + sif::info << "eive-watchdog not running. FIFO can not be opened" << std::endl; + } + else { + sif::error << "Opening pipe " << watchdog::FIFO_NAME << " write-only failed with " << + errno << ": " << strerror(errno) << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } } return HasReturnvaluesIF::RETURN_OK; } @@ -457,3 +456,37 @@ void CoreController::initPrint() { } #endif } + +void CoreController::performWatchdogControlOperation() { + // Only perform each fifth iteration + if(watchdogFifoFd != 0 and opDivider.checkAndIncrement()) { + if(watchdogFifoFd == RETRY_FIFO_OPEN) { + // Open FIFO write only and non-blocking + watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY | O_NONBLOCK); + if(watchdogFifoFd < 0) { + if(errno == ENXIO) { + watchdogFifoFd = RETRY_FIFO_OPEN; + // No printout for now, would be spam + return; + } + else { + sif::error << "Opening pipe " << watchdog::FIFO_NAME << + " write-only failed with " << errno << ": " << + strerror(errno) << std::endl; + return; + } + } + sif::info << "Opened " << watchdog::FIFO_NAME << " successfully" << std::endl; + } + else if(watchdogFifoFd > 0) { + // Write to OBSW watchdog FIFO here + const char writeChar = 'a'; + ssize_t writtenBytes = write(watchdogFifoFd, &writeChar, 1); + if(writtenBytes < 0) { + sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " << + strerror(errno) << std::endl; + } + } + } + +} diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index ea212a16..92b22dd4 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -1,6 +1,7 @@ #ifndef BSP_Q7S_CORE_CORECONTROLLER_H_ #define BSP_Q7S_CORE_CORECONTROLLER_H_ +#include #include "fsfw/controller/ExtendedControllerBase.h" #include "bsp_q7s/memory/SdCardManager.h" @@ -70,7 +71,12 @@ private: void initPrint(); + // Designated value for rechecking FIFO open + static constexpr int RETRY_FIFO_OPEN = -2; int watchdogFifoFd = 0; + + PeriodicOperationDivider opDivider; + void performWatchdogControlOperation(); }; diff --git a/watchdog/Watchdog.cpp b/watchdog/Watchdog.cpp index 9e316451..f3627a75 100644 --- a/watchdog/Watchdog.cpp +++ b/watchdog/Watchdog.cpp @@ -64,7 +64,11 @@ int WatchdogTask::performOperation() { break; } case(LoopResult::TIMEOUT): { - performTimeoutOperation(); + performNotRunningOperation(loopResult); + break; + } + case(LoopResult::HUNG_UP): { + performNotRunningOperation(loopResult); break; } case(LoopResult::RESTART_RQ): { @@ -159,6 +163,7 @@ WatchdogTask::LoopResult WatchdogTask::pollEvent(struct pollfd& waiter) { } else if (waiter.revents & POLLHUP) { // Writer closed its end + return LoopResult::HUNG_UP; } return LoopResult::FAULT; } @@ -189,9 +194,9 @@ int WatchdogTask::performRunningOperation() { } if(not obswRunning) { - if(printTimeoutLatch) { + if(printNotRunningLatch) { // Reset latch so user can see timeouts - printTimeoutLatch = false; + printNotRunningLatch = false; } obswRunning = true; @@ -210,25 +215,35 @@ int WatchdogTask::performRunningOperation() { return 0; } -int WatchdogTask::performTimeoutOperation() { +int WatchdogTask::performNotRunningOperation(LoopResult type) { // Latch prevents spam on console - if(not printTimeoutLatch) { - std::cout << "eive-watchdog: The FIFO timed out!" << std::endl; - printTimeoutLatch = true; + if(not printNotRunningLatch) { + if(type == LoopResult::HUNG_UP) { + std::cout << "eive-watchdog: FIFO writer hung up!" << std::endl; + } + else { + std::cout << "eive-watchdog: The FIFO timed out!" << std::endl; + } + printNotRunningLatch = true; } -#if WATCHDOG_CREATE_FILE_IF_RUNNING == 1 - if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { - int result = std::remove(watchdog::RUNNING_FILE_NAME.c_str()); - if(result != 0) { - std::cerr << "Removing " << watchdog::RUNNING_FILE_NAME << " failed with code " << - errno << ": " << strerror(errno) << std::endl; - } - } -#endif if(obswRunning) { +#if WATCHDOG_CREATE_FILE_IF_RUNNING == 1 + if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { + int result = std::remove(watchdog::RUNNING_FILE_NAME.c_str()); + if(result != 0) { + std::cerr << "Removing " << watchdog::RUNNING_FILE_NAME << " failed with code " << + errno << ": " << strerror(errno) << std::endl; + } + } +#endif obswRunning = false; } + if(type == LoopResult::HUNG_UP) { + using namespace std::chrono_literals; + // Prevent spam + std::this_thread::sleep_for(2000ms); + } return 0; } diff --git a/watchdog/Watchdog.h b/watchdog/Watchdog.h index 649fca6e..fb7ac65b 100644 --- a/watchdog/Watchdog.h +++ b/watchdog/Watchdog.h @@ -19,6 +19,7 @@ public: CANCEL_RQ, RESTART_RQ, TIMEOUT, + HUNG_UP, FAULT }; @@ -32,7 +33,7 @@ private: bool obswRunning = false; bool watchdogRunning = false; - bool printTimeoutLatch = false; + bool printNotRunningLatch = false; std::array buf; States state = States::NOT_STARTED; @@ -41,7 +42,7 @@ private: LoopResult parseCommandByte(ssize_t readLen); int performRunningOperation(); - int performTimeoutOperation(); + int performNotRunningOperation(LoopResult type); int performSuspendOperation(); }; -- 2.43.0 From 208aeb66406b96d0a34edd49eb69b1d3316e5a7c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 18:17:14 +0200 Subject: [PATCH 067/116] added build scripts, updated proj files --- cmake/scripts/Q7S/watchdog/make_debug_cfg.sh | 36 ++ .../scripts/Q7S/watchdog/make_release_cfg.sh | 36 ++ cmake/scripts/Q7S/watchdog/ninja_debug_cfg.sh | 34 ++ .../scripts/Q7S/watchdog/ninja_release_cfg.sh | 34 ++ misc/eclipse/.cproject | 332 +++++++++++++++++- 5 files changed, 471 insertions(+), 1 deletion(-) create mode 100755 cmake/scripts/Q7S/watchdog/make_debug_cfg.sh create mode 100755 cmake/scripts/Q7S/watchdog/make_release_cfg.sh create mode 100755 cmake/scripts/Q7S/watchdog/ninja_debug_cfg.sh create mode 100755 cmake/scripts/Q7S/watchdog/ninja_release_cfg.sh diff --git a/cmake/scripts/Q7S/watchdog/make_debug_cfg.sh b/cmake/scripts/Q7S/watchdog/make_debug_cfg.sh new file mode 100755 index 00000000..d5b58df9 --- /dev/null +++ b/cmake/scripts/Q7S/watchdog/make_debug_cfg.sh @@ -0,0 +1,36 @@ +#!/bin/sh +counter=0 +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f "cmake_build_config.py" ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "cmake_build_config.py not found in upper directories!" + exit 1 +fi + +os_fsfw="linux" +tgt_bsp="arm/q7s" +build_dir="build-Debug-Watchdog" +build_generator="" +definitions="BUILD_WATCHDOG=ON" +if [ "${OS}" = "Windows_NT" ]; then + build_generator="MinGW Makefiles" + python="py" +# Could be other OS but this works for now. +else + build_generator="Unix Makefiles" + python="python3" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ + -d "${definitions}" -l"${build_dir}" +# set +x + diff --git a/cmake/scripts/Q7S/watchdog/make_release_cfg.sh b/cmake/scripts/Q7S/watchdog/make_release_cfg.sh new file mode 100755 index 00000000..726e82ed --- /dev/null +++ b/cmake/scripts/Q7S/watchdog/make_release_cfg.sh @@ -0,0 +1,36 @@ +#!/bin/sh +counter=0 +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f "cmake_build_config.py" ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "cmake_build_config.py not found in upper directories!" + exit 1 +fi + +os_fsfw="linux" +tgt_bsp="arm/q7s" +build_dir="build-Release-Watchdog" +build_generator="" +definitions="BUILD_WATCHDOG=ON" +if [ "${OS}" = "Windows_NT" ]; then + build_generator="MinGW Makefiles" + python="py" +# Could be other OS but this works for now. +else + build_generator="Unix Makefiles" + python="python3" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ + -d "${definitions} -l"${build_dir}" +# set +x + diff --git a/cmake/scripts/Q7S/watchdog/ninja_debug_cfg.sh b/cmake/scripts/Q7S/watchdog/ninja_debug_cfg.sh new file mode 100755 index 00000000..99a414e7 --- /dev/null +++ b/cmake/scripts/Q7S/watchdog/ninja_debug_cfg.sh @@ -0,0 +1,34 @@ +#!/bin/sh +counter=0 +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f "cmake_build_config.py" ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "cmake_build_config.py not found in upper directories!" + exit 1 +fi + +os_fsfw="linux" +tgt_bsp="arm/q7s" +build_dir="build-Debug-Watchdog" +build_generator="Ninja" +definitions="-DBUILD_WATCHDOG=ON" +if [ "${OS}" = "Windows_NT" ]; then + python="py" +# Could be other OS but this works for now. +else + python="python3" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ + -d "${definitions}" -l "${build_dir}" +# set +x + diff --git a/cmake/scripts/Q7S/watchdog/ninja_release_cfg.sh b/cmake/scripts/Q7S/watchdog/ninja_release_cfg.sh new file mode 100755 index 00000000..3e6beac3 --- /dev/null +++ b/cmake/scripts/Q7S/watchdog/ninja_release_cfg.sh @@ -0,0 +1,34 @@ +#!/bin/sh +counter=0 +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f "cmake_build_config.py" ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "cmake_build_config.py not found in upper directories!" + exit 1 +fi + +os_fsfw="linux" +tgt_bsp="arm/q7s" +build_dir="build-Release-Watchdog" +build_generator="Ninja" +definitions="BUILD_WATCHDOG=ON" +if [ "${OS}" = "Windows_NT" ]; then + python="py" +# Could be other OS but this works for now. +else + python="python3" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ + -d "${definitions}" -l"${build_dir}" +# set +x + diff --git a/misc/eclipse/.cproject b/misc/eclipse/.cproject index 84814acc..fe0208b8 100644 --- a/misc/eclipse/.cproject +++ b/misc/eclipse/.cproject @@ -254,7 +254,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1044,6 +1370,9 @@ + + + @@ -1060,6 +1389,7 @@ + -- 2.43.0 From df971d4ec59d5cf39388e1a70b3fe788654223e2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 18:21:05 +0200 Subject: [PATCH 068/116] dont need csp lib in watchdog --- CMakeLists.txt | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc476dcc..5f56a4fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,9 +152,7 @@ if(ADD_JSON_LIB) add_subdirectory(${LIB_JSON_PATH}) endif() -if(ADD_CSP_LIB) - add_subdirectory(${CSP_LIB_PATH}) -endif() + if(NOT BUILD_WATCHDOG) if(ADD_LINUX_FILES) @@ -162,6 +160,9 @@ if(NOT BUILD_WATCHDOG) endif() add_subdirectory(${BSP_PATH}) add_subdirectory(${COMMON_PATH}) + if(ADD_CSP_LIB) + add_subdirectory(${CSP_LIB_PATH}) + endif() endif() if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT BUILD_WATCHDOG)) @@ -192,24 +193,28 @@ if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT BUILD_WATCHDOG)) ) endif() +if(NOT BUILD_WATCHDOG) + if(ADD_CSP_LIB) + target_link_libraries(${TARGET_NAME} PRIVATE + ${LIB_CSP_NAME} + ) + endif() +endif() + if(ADD_ETL_LIB) target_link_libraries(${TARGET_NAME} PRIVATE ${LIB_ETL_NAME} ) endif() -if(ADD_CSP_LIB) - target_link_libraries(${TARGET_NAME} PRIVATE - ${LIB_CSP_NAME} - ) -endif() - if(ADD_JSON_LIB) target_link_libraries(${TARGET_NAME} PRIVATE ${LIB_JSON_NAME} ) endif() + + target_link_libraries(${TARGET_NAME} PRIVATE ${LIB_CXX_FS} ) -- 2.43.0 From 940d4965bcf1727f0a2cfbd44e1c9e2e42e5ddbd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 18:32:02 +0200 Subject: [PATCH 069/116] small corrections --- bsp_q7s/core/CoreController.cpp | 2 +- watchdog/main.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 4a9db02a..72171c65 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -451,7 +451,7 @@ void CoreController::initPrint() { TcpTmTcBridge::DEFAULT_SERVER_PORT << std::endl; #endif - if(watchdogFifoFd != 0) { + if(watchdogFifoFd > 0) { sif::info << "Opened watchdog FIFO successfully.." << std::endl; } #endif diff --git a/watchdog/main.cpp b/watchdog/main.cpp index a1ae3ae8..f297f429 100644 --- a/watchdog/main.cpp +++ b/watchdog/main.cpp @@ -14,6 +14,7 @@ int main() { } catch(const std::runtime_error& e) { std::cerr << "eive-watchdog: Run time exception " << e.what() << std::endl; + return -1; } return 0; } -- 2.43.0 From d8acf94a02d17b939ac7e92457d61f878299f9f4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 18:33:15 +0200 Subject: [PATCH 070/116] more corrections --- watchdog/Watchdog.cpp | 1 + watchdog/main.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/watchdog/Watchdog.cpp b/watchdog/Watchdog.cpp index f3627a75..9ae60548 100644 --- a/watchdog/Watchdog.cpp +++ b/watchdog/Watchdog.cpp @@ -45,6 +45,7 @@ int WatchdogTask::performOperation() { if(fd < 0) { std::cerr << "eive-watchdog: Opening pipe " << watchdog::FIFO_NAME << "read-only failed with " << errno << ": " << strerror(errno) << std::endl; + return -1; } state = States::RUNNING; diff --git a/watchdog/main.cpp b/watchdog/main.cpp index f297f429..ba75dc30 100644 --- a/watchdog/main.cpp +++ b/watchdog/main.cpp @@ -10,7 +10,10 @@ int main() { std::cout << "eive-watchdog: Starting OBSW watchdog.." << std::endl; try { WatchdogTask watchdogTask; - watchdogTask.performOperation(); + int result = watchdogTask.performOperation(); + if(result != 0) { + return result; + } } catch(const std::runtime_error& e) { std::cerr << "eive-watchdog: Run time exception " << e.what() << std::endl; -- 2.43.0 From 8c3d25f62db70b2aafa9bb4886b7ba6921b2a215 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 29 Jul 2021 19:43:00 +0200 Subject: [PATCH 071/116] updated README --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4865885d..fc4163e1 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,29 @@ When using Windows, run theses steps in MSYS2. # Useful and Common Commands (Host) +## Build generation + +Replace `Debug` with `Release` for release build. Add `-G "MinGW Makefiles` or `-G "Ninja"` +on Windows or when `ninja` should be used. You can build with `cmake --build . -j` after +build generation. You can finds scripts in `cmake/scripts` to perform the build commands +automatically. + +### Q7S OBSW + +```sh +mkdir build-Debug-Q7S && cd build-Debug-Q7S +cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DCMAKE_BUILD_TYPE=Debug .. +cmake --build . -j +``` + +### Q7S Watchdog + +```sh +mkdir build-Debug-Q7S && cd build-Debug-Q7S +cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DBUILD_WATCHDOG=ON -DCMAKE_BUILD_TYPE=Debug .. +cmake --build . -j +``` + ## Connect to EIVE flatsat ### DNS @@ -192,6 +215,12 @@ Other useful tmux commands: You can quit scroll mode with `q`. - Kill a tmux session: run `ctrl + b` and then `k`. - Detach from a tmux session: run `ctrl + b` and then `d` +- [Pipe last 3000 lines](https://unix.stackexchange.com/questions/26548/write-all-tmux-scrollback-to-a-file) + into file for copying or analysis: + 1. `ctrl + b` and `:` + 2. `capture-pane -S -3000` + `enter` + 3. `save-buffer /tmp/tmux-output.txt` + `enter` + ### SSH console @@ -587,7 +616,7 @@ pscp -scp -P 22 eive@192.168.199.227:/example-file More detailed information about the used q7s commands can be found in the Q7S user manual. -# Q7S +# Q7S OBC ## Launching an application at start-up @@ -666,13 +695,31 @@ creating directories. To do this, the parition needs to be mounted. systemctl status example ``` - ## Current user systemd services The following custom `systemd` services are currently running on the Q7S and can be found in the `/etc/systemd/system` folder. You can query that status of a service by running `systemctl status `. +### `eive-watchdog` + +The watchdog will create a pipe at `/tmp/watchdog-pipe` which can be used both by the watchdog and +the EIVE OBSW. The watchdog will only read from this pipe while the OBSW will only write +to this pipe. The watchdog checks for basic ASCII commands as a first basic feature set. +The most important functionality is that the watchdog cant detect if a timeout +has happened. This can happen beause the OBSW is hanging (or at least the CoreController thread) or +there is simply now OBSW running on the system. It does to by checking whether the FIFO is +regulary written to, which means the EIVE OBSW is alive. + +If the EIVE OBSW is alive, a special file called `/tmp/obsw-running` will be created. +This file can be used by any other software component to query whether the EIVE OBSW is running. +The EIVE OBSW itself can be configured to check whether this file exists, which prevents two +EIVE OBSW instances running on the Q7S at once. + +If a timeout occurs, this special file will be deleted as well. +The watchdog and its configuration will be directly integrated into this repostory, which +makes adaptions easy. + ### `tcfagent` This starts the `/usr/bin/agent` program to allows remote debugging. Might not be part of -- 2.43.0 From 503d5923c4f5431aa05154e04355aef34f0d48d2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 30 Jul 2021 16:40:24 +0200 Subject: [PATCH 072/116] making some stuff optional --- CMakeLists.txt | 3 ++- cmake/Q7SCrossCompileConfig.cmake | 32 ++++++++++++++++--------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f56a4fc..9afa81ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,8 @@ if(TGT_BSP MATCHES "arm/q7s") endif() option(ADD_ETL_LIB "Add ETL library" ON) -option(ADD_JSON_LIB "Add JSON librara" ON) +option(ADD_JSON_LIB "Add JSON library" ON) +option(EIVE_SYSROOT_MAGIC "Perform sysroot magic which might not be necessary" OFF) if(NOT FSFW_OSAL) set(FSFW_OSAL host CACHE STRING "OS for the FSFW.") diff --git a/cmake/Q7SCrossCompileConfig.cmake b/cmake/Q7SCrossCompileConfig.cmake index 746df453..006b2c96 100644 --- a/cmake/Q7SCrossCompileConfig.cmake +++ b/cmake/Q7SCrossCompileConfig.cmake @@ -54,21 +54,23 @@ set(CMAKE_SYSTEM_PROCESSOR "armv7") set(CMAKE_C_COMPILER ${CROSS_COMPILE_CC}) set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX}) -# List of library dirs where LD has to look. Pass them directly through gcc. -set(LIB_DIRS - "${SYSROOT_PATH}/usr/include" - "${SYSROOT_PATH}/usr/include/linux" - "${SYSROOT_PATH}/usr/lib" - "${SYSROOT_PATH}/lib" - "${SYSROOT_PATH}" - "${SYSROOT_PATH}/usr/lib/arm-xiphos-linux-gnueabi" -) -# You can additionally check the linker paths if you add the -# flags ' -Xlinker --verbose' -set(COMMON_FLAGS "-I${SYSROOT_PATH}/usr/lib") -foreach(LIB ${LIB_DIRS}) - set(COMMON_FLAGS "${COMMON_FLAGS} -L${LIB} -Wl,-rpath-link,${LIB}") -endforeach() +if(EIVE_SYSROOT_MAGIC) + # List of library dirs where LD has to look. Pass them directly through gcc. + set(LIB_DIRS + "${SYSROOT_PATH}/usr/include" + "${SYSROOT_PATH}/usr/include/linux" + "${SYSROOT_PATH}/usr/lib" + "${SYSROOT_PATH}/lib" + "${SYSROOT_PATH}" + "${SYSROOT_PATH}/usr/lib/arm-xiphos-linux-gnueabi" + ) + # You can additionally check the linker paths if you add the + # flags ' -Xlinker --verbose' + set(COMMON_FLAGS "-I${SYSROOT_PATH}/usr/lib") + foreach(LIB ${LIB_DIRS}) + set(COMMON_FLAGS "${COMMON_FLAGS} -L${LIB} -Wl,-rpath-link,${LIB}") + endforeach() +endif() set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}" -- 2.43.0 From 926e1e336a1824b83e1d951d5031db0db3a2c04c Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sat, 31 Jul 2021 08:32:57 +0200 Subject: [PATCH 073/116] mram dump reply --- bsp_q7s/core/ObjectFactory.cpp | 3 +- mission/core/GenericFactory.cpp | 4 +- mission/devices/PlocSupervisorHandler.cpp | 97 ++++++++++++++++++- mission/devices/PlocSupervisorHandler.h | 33 ++++--- .../PlocSupervisorDefinitions.h | 11 ++- tmtc | 2 +- 6 files changed, 130 insertions(+), 20 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 536d4fe8..7ba018a4 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -170,7 +170,8 @@ void ObjectFactory::produce(void* args){ /* Configuration for MIO0 on TE0720-03-1CFA */ UartCookie* plocSupervisorCookie = new UartCookie(objects::PLOC_SUPERVISOR_HANDLER, std::string("/dev/ttyUL3"), UartModes::NON_CANONICAL, 115200, - PLOC_SPV::MAX_REPLY_SIZE); + PLOC_SPV::MAX_PACKET_SIZE * 20); + plocSupervisorCookie->setNoFixedSizeReply(); PlocSupervisorHandler* plocSupervisor = new PlocSupervisorHandler( objects::PLOC_SUPERVISOR_HANDLER, objects::UART_COM_IF, plocSupervisorCookie); plocSupervisor->setStartUpImmediately(); diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index a6708f98..cc1b88e5 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -36,14 +36,14 @@ void ObjectFactory::produceGenericObjects() { { PoolManager::LocalPoolConfig poolCfg = { - {100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024} + {100, 16}, {50, 32}, {25, 64}, {15, 128}, {10, 1024}, {5, 2048} }; new PoolManager(objects::TC_STORE, poolCfg); } { PoolManager::LocalPoolConfig poolCfg = { - {100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024} + {100, 16}, {50, 32}, {25, 64}, {15, 128}, {10, 1024}, {5, 2048} }; new PoolManager(objects::TM_STORE, poolCfg); } diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index cfb9ef3a..7a55e7a6 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -247,7 +247,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::SELECT_NVM); this->insertInCommandMap(PLOC_SPV::RUN_AUTO_EM_TESTS); this->insertInCommandMap(PLOC_SPV::WIPE_MRAM); - this->insertInCommandMap(PLOC_SPV::DUMP_MRAM); + this->insertInCommandAndReplyMap(PLOC_SPV::DUMP_MRAM, 3); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); this->insertInReplyMap(PLOC_SPV::HK_REPORT, 3, &hkset, PLOC_SPV::SIZE_HK_REPORT); @@ -260,6 +260,11 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { + if (nextReplyId == PLOC_SPV::DUMP_MRAM) { + *foundId = PLOC_SPV::DUMP_MRAM; + return parseMramPackets(start, remainingSize, foundLen); + } + ReturnValue_t result = RETURN_OK; uint16_t apid = (*(start) << 8 | *(start + 1)) & APID_MASK; @@ -325,6 +330,10 @@ ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id, result = handleLatchupStatusReport(packet); break; } + case (PLOC_SPV::DUMP_MRAM): { + result = handleMramDumpPacket(); + break; + } case (PLOC_SPV::EXE_REPORT): { result = handleExecutionReport(packet); break; @@ -429,6 +438,16 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite } break; } + case PLOC_SPV::DUMP_MRAM: { + enabledReplies = expectedMramDumpPackets + 2; + result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, + PLOC_SPV::DUMP_MRAM); + if (result != RETURN_OK) { + sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " + << PLOC_SPV::LATCHUP_REPORT << " not in replyMap" << std::endl; + } + break; + } case PLOC_SPV::RESTART_MPSOC: case PLOC_SPV::START_MPSOC: case PLOC_SPV::SHUTDOWN_MPSOC: @@ -454,7 +473,6 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite case PLOC_SPV::SELECT_NVM: case PLOC_SPV::RUN_AUTO_EM_TESTS: case PLOC_SPV::WIPE_MRAM: - case PLOC_SPV::DUMP_MRAM: case PLOC_SPV::SET_DBG_VERBOSITY: case PLOC_SPV::CAN_LOOPBACK_TEST: case PLOC_SPV::PRINT_CPU_STATS: @@ -823,6 +841,9 @@ void PlocSupervisorHandler::setNextReplyId() { case PLOC_SPV::GET_LATCHUP_STATUS_REPORT: nextReplyId = PLOC_SPV::LATCHUP_REPORT; break; + case PLOC_SPV::DUMP_MRAM: + nextReplyId = PLOC_SPV::DUMP_MRAM; + break; default: /* If no telemetry is expected the next reply is always the execution report */ nextReplyId = PLOC_SPV::EXE_REPORT; @@ -838,6 +859,16 @@ size_t PlocSupervisorHandler::getNextReplyLength(DeviceCommandId_t commandId){ return replyLen; } + if (nextReplyId == PLOC_SPV::DUMP_MRAM) { + /** + * Try to read 20 MRAM packets. If reply is larger, the packets will be read with the + * next doSendRead call. The command will be as long active as the packet with the sequence + * count indicating the last packet has not been received. + */ + replyLen = PLOC_SPV::MAX_PACKET_SIZE * 20; + return replyLen; + } + DeviceReplyIter iter = deviceReplyMap.find(nextReplyId); if (iter != deviceReplyMap.end()) { if (iter->second.delayCycles == 0) { @@ -1113,6 +1144,14 @@ void PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandData) { SerializeAdapter::deSerialize(&stop, &commandData, &size, SerializeIF::Endianness::BIG); PLOC_SPV::MramCmd packet(start, stop, PLOC_SPV::MramCmd::MramAction::DUMP); packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + expectedMramDumpPackets = (stop - start) / PLOC_SPV::MAX_DATA_CAPACITY; + if ((stop - start) % PLOC_SPV::MAX_DATA_CAPACITY) { + expectedMramDumpPackets++; + mramLastPktLen = (stop - start) % PLOC_SPV::MAX_DATA_CAPACITY; + } + else { + mramLastPktLen = 0; + } } void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { @@ -1143,6 +1182,13 @@ void PlocSupervisorHandler::disableAllReplies() { info->command = deviceCommandMap.end(); break; } + case PLOC_SPV::DUMP_MRAM: { + iter = deviceReplyMap.find(PLOC_SPV::DUMP_MRAM); + info = &(iter->second); + info->delayCycles = 0; + info->command = deviceCommandMap.end(); + break; + } default: { break; } @@ -1182,3 +1228,50 @@ void PlocSupervisorHandler::disableExeReportReply() { /* Expected replies is set to one here. The value will set to 0 in replyToReply() */ info->command->second.expectedReplies = 1; } + +ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t *packet, size_t remainingSize, + size_t* foundLen) { + uint16_t packetLen = 0; + + for (size_t idx = 0; idx < remainingSize; idx++) { + std::memcpy(spacePacketBuffer + bufferTop, packet + idx, 1); + bufferTop += 1; + *foundLen += 1; + if (bufferTop >= PLOC_SPV::SPACE_PACKET_HEADER_LENGTH) { + packetLen = spacePacketBuffer[4] << 8 | spacePacketBuffer[5]; + } + + if (bufferTop == PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1) { + packetInBuffer = true; + bufferTop = 0; + return RETURN_OK; + } + + if (bufferTop == PLOC_SPV::MAX_PACKET_SIZE) { + *foundLen = remainingSize; + disableAllReplies(); + bufferTop = 0; + return MRAM_PACKET_PARSING_FAILURE; + } + } + + return IGNORE_FULL_PACKET; +} + +ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket() { + + ReturnValue_t result = RETURN_OK; + + // Prepare packet for downlink + if (packetInBuffer) { + uint16_t packetLen = spacePacketBuffer[4] << 8 | spacePacketBuffer[5]; + result = verifyPacket(spacePacketBuffer, PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1); + if (result != RETURN_OK) { + sif::warning << "PlocSupervisorHandler::handleMramDumpPacket: CRC failure" << std::endl; + } + handleDeviceTM(spacePacketBuffer + PLOC_SPV::SPACE_PACKET_HEADER_LENGTH, packetLen - 1, + PLOC_SPV::DUMP_MRAM); + packetInBuffer = false; + } + return RETURN_OK; +} diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index 9736d1a2..35098ffb 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -73,6 +73,8 @@ private: static const ReturnValue_t SWEEP_PERIOD_TOO_SMALL = MAKE_RETURN_CODE(0xA9); //! [EXPORT] : [COMMENT] Receive auto EM test command with invalid test param. Valid params are 1 and 2. static const ReturnValue_t INVALID_TEST_PARAM = MAKE_RETURN_CODE(0xAA); + //! [EXPORT] : [COMMENT] Returned when scanning for MRAM dump packets failed. + static const ReturnValue_t MRAM_PACKET_PARSING_FAILURE = MAKE_RETURN_CODE(0xAB); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; @@ -90,18 +92,6 @@ private: uint8_t commandBuffer[PLOC_SPV::MAX_COMMAND_SIZE]; - /** - * @brief This object is incremented each time a packet is sent or received. By checking the - * packet sequence count of a received packet, no packets can be lost without noticing - * it. Only the least significant 14 bits represent the packet sequence count in a - * space packet. Thus the maximum value amounts to 16383 (0x3FFF). - * @note Normally this should never happen because the PLOC replies are always sent in a - * fixed order. However, the PLOC software checks this value and will return an ACK - * failure report in case the sequence count is not incremented with each transferred - * space packet. - */ - uint16_t packetSequenceCount = 0x3FFF; - /** * This variable is used to store the id of the next reply to receive. This is necessary * because the PLOC sends as reply to each command at least one acknowledgment and execution @@ -115,6 +105,17 @@ private: PLOC_SPV::BootStatusReport bootStatusReport; PLOC_SPV::LatchupStatusReport latchupStatusReport; + /** Number of expected replies following the MRAM dump command */ + uint32_t expectedMramDumpPackets = 0; + size_t mramLastPktLen = 0; + /** Set to true as soon as a complete space packet is present in the spacePacketBuffer */ + bool packetInBuffer = false; + /** Points to the next free position in the space packet buffer */ + uint16_t bufferTop = 0; + + /** This buffer is used to concatenate space packets received in two different read steps */ + uint8_t spacePacketBuffer[PLOC_SPV::MAX_PACKET_SIZE]; + /** * @brief This function checks the crc of the received PLOC reply. * @@ -266,6 +267,14 @@ private: * the variable expectedReplies of an active command will be set to 0. */ void disableExeReportReply(); + + /** + * @brief Function is called in scanForReply and fills the spacePacketBuffer with the read + * data until a full packet has been received. + */ + ReturnValue_t parseMramPackets(const uint8_t *packet, size_t remainingSize, size_t* foundlen); + + ReturnValue_t handleMramDumpPacket(); }; #endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index ce1400be..ff0f7bd9 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -77,7 +77,7 @@ static const uint16_t APID_UPDATE_STATUS_REPORT = 0x206; static const uint16_t APID_WDG_STATUS_REPORT = 0x207; static const uint16_t APID_LATCHUP_STATUS_REPORT = 0x208; static const uint16_t APID_SOC_SYSMON = 0x209; -static const uint16_t APID_MRAM = 0x20A; +static const uint16_t APID_MRAM_DUMP_TM = 0x20A; static const uint16_t APID_SRAM = 0x20B; static const uint16_t APID_NOR_DATA = 0x20C; static const uint16_t APID_DATA_LOGGER_DATA = 0x20D; @@ -137,8 +137,13 @@ static const uint8_t DATA_FIELD_OFFSET = 6; static const uint16_t LENGTH_EMPTY_TC = 2; // Only CRC will be transported with the data field /** This is the maximum length of a space packet as defined by the TAS ICD */ -static const size_t MAX_REPLY_SIZE = 1024; +//static const size_t MAX_REPLY_SIZE = 1024; static const size_t MAX_COMMAND_SIZE = 1024; +static const size_t MAX_DATA_CAPACITY = 1016; +/** This is the maximum size of a space packet for the supervisor */ +static const size_t MAX_PACKET_SIZE = 1024; + +static const uint8_t SPACE_PACKET_HEADER_LENGTH = 6; enum SequenceFlags { CONTINUED_PKT = 0b00, FIRST_PKT = 0b01, LAST_PKT = 0b10, STANDALONE_PKT = 0b11 @@ -1106,6 +1111,8 @@ public: * @param start Start address of the MRAM section to wipe or dump * @param stop End address of the MRAM section to wipe or dump * @param action Dump or wipe MRAM + * + * @note The content at the stop address is excluded from the dump or wipe operation. */ MramCmd(uint32_t start, uint32_t stop, MramAction action) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_IDLE_PACKET, diff --git a/tmtc b/tmtc index 1b1f26ac..6fcd52da 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 1b1f26ac3a948a320a29a16083613ea29789a378 +Subproject commit 6fcd52daa693040099cac85367863ad24e477f9a -- 2.43.0 From 0b1b74e879e578ea64a0a559cb534fb9257f69ed Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 31 Jul 2021 19:31:04 +0200 Subject: [PATCH 074/116] renamed cmake var, updated all shell scripts --- CMakeLists.txt | 18 +++++----- README.md | 2 +- .../BeagleBoneBlack/create_cmake_debug_cfg.sh | 30 ---------------- .../crosscompile/create_cmake_debug_cfg.sh | 30 ---------------- .../crosscompile/create_cmake_release_cfg.sh | 30 ---------------- .../create_cmake_relwithdeb_cfg.sh | 30 ---------------- .../crosscompile/make-debug-cfg.sh | 35 +++++++++++++++++++ .../crosscompile/make-release-cfg.sh | 35 +++++++++++++++++++ .../scripts/BeagleBoneBlack/make-debug-cfg.sh | 35 +++++++++++++++++++ .../scripts/Host/create_cmake_release_cfg.sh | 27 -------------- .../Host/create_cmake_relwithdeb_cfg.sh | 26 -------------- cmake/scripts/Host/create_cmake_size_cfg.sh | 26 -------------- cmake/scripts/Host/make-debug-cfg.sh | 32 +++++++++++++++++ cmake/scripts/Host/make-release-cfg.sh | 32 +++++++++++++++++ cmake/scripts/Host/make_debug_cfg.sh | 27 -------------- cmake/scripts/Host/ninja-debug-cfg.sh | 32 +++++++++++++++++ .../{make_debug_cfg.sh => make-debug-cfg.sh} | 18 +++++----- ...ake_release_cfg.sh => make-release-cfg.sh} | 17 ++++----- ...{ninja_debug_cfg.sh => ninja-debug-cfg.sh} | 17 ++++----- .../{make_debug_cfg.sh => make-debug-cfg.sh} | 17 ++++----- ...ake_release_cfg.sh => make-release-cfg.sh} | 17 ++++----- ...{ninja_debug_cfg.sh => ninja-debug-cfg.sh} | 17 ++++----- ...ja_release_cfg.sh => ninja-release-cfg.sh} | 17 ++++----- ..._debug_cfg.sh => make-simple-debug-cfg.sh} | 17 ++++----- ...debug_cfg.sh => ninja-simple-debug-cfg.sh} | 17 ++++----- .../{make_debug_cfg.sh => make-debug-cfg.sh} | 19 +++++----- ...ake_release_cfg.sh => make-release-cfg.sh} | 2 +- ...{ninja_debug_cfg.sh => ninja-debug-cfg.sh} | 19 +++++----- ...ja_release_cfg.sh => ninja-release-cfg.sh} | 19 +++++----- .../{make_debug_cfg.sh => make-debug-cfg.sh} | 19 +++++----- cmake/scripts/RPi/make-release-cfg.sh | 33 +++++++++++++++++ cmake/scripts/RPi/make_release_cfg.sh | 29 --------------- ...{ninja_debug_cfg.sh => ninja-debug-cfg.sh} | 17 ++++----- ...ake_build_config.py => cmake-build-cfg.py} | 0 34 files changed, 375 insertions(+), 383 deletions(-) delete mode 100644 cmake/scripts/BeagleBoneBlack/create_cmake_debug_cfg.sh delete mode 100644 cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_debug_cfg.sh delete mode 100644 cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_release_cfg.sh delete mode 100644 cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_relwithdeb_cfg.sh create mode 100755 cmake/scripts/BeagleBoneBlack/crosscompile/make-debug-cfg.sh create mode 100755 cmake/scripts/BeagleBoneBlack/crosscompile/make-release-cfg.sh create mode 100755 cmake/scripts/BeagleBoneBlack/make-debug-cfg.sh delete mode 100644 cmake/scripts/Host/create_cmake_release_cfg.sh delete mode 100644 cmake/scripts/Host/create_cmake_relwithdeb_cfg.sh delete mode 100644 cmake/scripts/Host/create_cmake_size_cfg.sh create mode 100755 cmake/scripts/Host/make-debug-cfg.sh create mode 100755 cmake/scripts/Host/make-release-cfg.sh delete mode 100755 cmake/scripts/Host/make_debug_cfg.sh create mode 100755 cmake/scripts/Host/ninja-debug-cfg.sh rename cmake/scripts/Linux/{make_debug_cfg.sh => make-debug-cfg.sh} (58%) rename cmake/scripts/Linux/{make_release_cfg.sh => make-release-cfg.sh} (58%) rename cmake/scripts/Linux/{ninja_debug_cfg.sh => ninja-debug-cfg.sh} (57%) rename cmake/scripts/Q7S/{make_debug_cfg.sh => make-debug-cfg.sh} (59%) rename cmake/scripts/Q7S/{make_release_cfg.sh => make-release-cfg.sh} (59%) rename cmake/scripts/Q7S/{ninja_debug_cfg.sh => ninja-debug-cfg.sh} (56%) rename cmake/scripts/Q7S/{ninja_release_cfg.sh => ninja-release-cfg.sh} (56%) rename cmake/scripts/Q7S/simple/{simple_make_debug_cfg.sh => make-simple-debug-cfg.sh} (62%) rename cmake/scripts/Q7S/simple/{simple_ninja_debug_cfg.sh => ninja-simple-debug-cfg.sh} (59%) rename cmake/scripts/Q7S/watchdog/{make_debug_cfg.sh => make-debug-cfg.sh} (58%) rename cmake/scripts/Q7S/watchdog/{make_release_cfg.sh => make-release-cfg.sh} (95%) rename cmake/scripts/Q7S/watchdog/{ninja_debug_cfg.sh => ninja-debug-cfg.sh} (55%) rename cmake/scripts/Q7S/watchdog/{ninja_release_cfg.sh => ninja-release-cfg.sh} (54%) rename cmake/scripts/RPi/{make_debug_cfg.sh => make-debug-cfg.sh} (60%) create mode 100755 cmake/scripts/RPi/make-release-cfg.sh delete mode 100755 cmake/scripts/RPi/make_release_cfg.sh rename cmake/scripts/RPi/{ninja_debug_cfg.sh => ninja-debug-cfg.sh} (56%) rename cmake/scripts/{cmake_build_config.py => cmake-build-cfg.py} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9afa81ff..d057de50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_SCRIPT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") if(TGT_BSP MATCHES "arm/q7s") - option(BUILD_WATCHDOG "Compile the OBSW watchdog insted" OFF) + option(EIVE_BUILD_WATCHDOG "Compile the OBSW watchdog insted" OFF) option(BUILD_Q7S_SIMPLE_MODE OFF "Simple mode with a minimal main function") endif() @@ -35,7 +35,7 @@ include(${CMAKE_SCRIPT_PATH}/PreProjectConfig.cmake) pre_project_config() set(PROJECT_NAME_TO_SET eive-obsw-$ENV{USERNAME}) -if(BUILD_WATCHDOG) +if(EIVE_BUILD_WATCHDOG) set(PROJECT_NAME_TO_SET eive-watchdog) endif() @@ -118,7 +118,7 @@ else() endif() # Configuration files -if(NOT BUILD_WATCHDOG) +if(NOT EIVE_BUILD_WATCHDOG) configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h) configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h) configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h) @@ -155,7 +155,7 @@ endif() -if(NOT BUILD_WATCHDOG) +if(NOT EIVE_BUILD_WATCHDOG) if(ADD_LINUX_FILES) add_subdirectory(${LINUX_PATH}) endif() @@ -166,7 +166,7 @@ if(NOT BUILD_WATCHDOG) endif() endif() -if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT BUILD_WATCHDOG)) +if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT EIVE_BUILD_WATCHDOG)) add_subdirectory(${LWGPS_LIB_PATH}) add_subdirectory(${FSFW_PATH}) add_subdirectory(${MISSION_PATH}) @@ -174,7 +174,7 @@ if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT BUILD_WATCHDOG)) add_subdirectory(${ARCSEC_LIB_PATH}) endif() -if(BUILD_WATCHDOG) +if(EIVE_BUILD_WATCHDOG) add_subdirectory(${WATCHDOG_PATH}) endif() @@ -184,7 +184,7 @@ endif() set_property(CACHE FSFW_OSAL PROPERTY STRINGS host linux) -if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT BUILD_WATCHDOG)) +if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT EIVE_BUILD_WATCHDOG)) # Add libraries for all sources. target_link_libraries(${TARGET_NAME} PRIVATE ${LIB_FSFW_NAME} @@ -194,7 +194,7 @@ if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT BUILD_WATCHDOG)) ) endif() -if(NOT BUILD_WATCHDOG) +if(NOT EIVE_BUILD_WATCHDOG) if(ADD_CSP_LIB) target_link_libraries(${TARGET_NAME} PRIVATE ${LIB_CSP_NAME} @@ -275,7 +275,7 @@ if(NOT CMAKE_SIZE) endif() endif() -if(BUILD_WATCHDOG) +if(EIVE_BUILD_WATCHDOG) set(TARGET_STRING "OBSW Watchdog") else() if(TGT_BSP) diff --git a/README.md b/README.md index fc4163e1..a5947a93 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ cmake --build . -j ```sh mkdir build-Debug-Q7S && cd build-Debug-Q7S -cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DBUILD_WATCHDOG=ON -DCMAKE_BUILD_TYPE=Debug .. +cmake -DTGT_BSP=arm/q7s -DFSFW_OSAL=linux -DEIVE_BUILD_WATCHDOG=ON -DCMAKE_BUILD_TYPE=Debug .. cmake --build . -j ``` diff --git a/cmake/scripts/BeagleBoneBlack/create_cmake_debug_cfg.sh b/cmake/scripts/BeagleBoneBlack/create_cmake_debug_cfg.sh deleted file mode 100644 index cfa71d02..00000000 --- a/cmake/scripts/BeagleBoneBlack/create_cmake_debug_cfg.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 -fi - -os_fsfw="linux" -tgt_bsp="arm/beagleboneblack" -build_generator="" -builddir="build-Debug-BBB" -defines="LINUX_CROSS_COMPILE=OFF" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" -fi - -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ - -l "${builddir}" -d "${defines}" diff --git a/cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_debug_cfg.sh b/cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_debug_cfg.sh deleted file mode 100644 index b413d07f..00000000 --- a/cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_debug_cfg.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 -fi - -os_fsfw="linux" -tgt_bsp="arm/beagleboneblack" -build_generator="" -builddir="build-Debug-BBB" -defines="LINUX_CROSS_COMPILE=ON" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" -fi - -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ - -l "${builddir}" -d "${defines}" diff --git a/cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_release_cfg.sh b/cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_release_cfg.sh deleted file mode 100644 index 81e3322d..00000000 --- a/cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_release_cfg.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 -fi - -os_fsfw="linux" -tgt_bsp="arm/beagleboneblack" -build_generator="" -builddir="build-Release-BBB" -defines="LINUX_CROSS_COMPILE=ON" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" -fi - -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ - -l "${builddir}" -d "${defines}" diff --git a/cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_relwithdeb_cfg.sh b/cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_relwithdeb_cfg.sh deleted file mode 100644 index 81e3322d..00000000 --- a/cmake/scripts/BeagleBoneBlack/crosscompile/create_cmake_relwithdeb_cfg.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 -fi - -os_fsfw="linux" -tgt_bsp="arm/beagleboneblack" -build_generator="" -builddir="build-Release-BBB" -defines="LINUX_CROSS_COMPILE=ON" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" -fi - -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ - -l "${builddir}" -d "${defines}" diff --git a/cmake/scripts/BeagleBoneBlack/crosscompile/make-debug-cfg.sh b/cmake/scripts/BeagleBoneBlack/crosscompile/make-debug-cfg.sh new file mode 100755 index 00000000..ba8d94cc --- /dev/null +++ b/cmake/scripts/BeagleBoneBlack/crosscompile/make-debug-cfg.sh @@ -0,0 +1,35 @@ +#!/bin/sh +counter=0 +cfg_script_name="cmake-build-cfg.py" +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "${cfg_script_name} not found in upper directories!" + exit 1 +fi + +os_fsfw="linux" +tgt_bsp="arm/beagleboneblack" +build_generator="" +builddir="build-Debug-BBB" +defines="LINUX_CROSS_COMPILE=ON" +if [ "${OS}" = "Windows_NT" ]; then + build_generator="MinGW Makefiles" +# Could be other OS but this works for now. +else + build_generator="Unix Makefiles" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ + -l "${builddir}" -d "${defines}" +# Use this if commands are added which should not be printed +# set +x diff --git a/cmake/scripts/BeagleBoneBlack/crosscompile/make-release-cfg.sh b/cmake/scripts/BeagleBoneBlack/crosscompile/make-release-cfg.sh new file mode 100755 index 00000000..59d548c5 --- /dev/null +++ b/cmake/scripts/BeagleBoneBlack/crosscompile/make-release-cfg.sh @@ -0,0 +1,35 @@ +#!/bin/sh +counter=0 +cfg_script_name="cmake-build-cfg.py" +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "${cfg_script_name} not found in upper directories!" + exit 1 +fi + +os_fsfw="linux" +tgt_bsp="arm/beagleboneblack" +build_generator="" +builddir="build-Release-BBB" +defines="LINUX_CROSS_COMPILE=ON" +if [ "${OS}" = "Windows_NT" ]; then + build_generator="MinGW Makefiles" +# Could be other OS but this works for now. +else + build_generator="Unix Makefiles" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ + -l "${builddir}" -d "${defines}" +# Use this if commands are added which should not be printed +# set +x diff --git a/cmake/scripts/BeagleBoneBlack/make-debug-cfg.sh b/cmake/scripts/BeagleBoneBlack/make-debug-cfg.sh new file mode 100755 index 00000000..ede76acf --- /dev/null +++ b/cmake/scripts/BeagleBoneBlack/make-debug-cfg.sh @@ -0,0 +1,35 @@ +#!/bin/sh +counter=0 +cfg_script_name="cmake-build-cfg.py" +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "${cfg_script_name} not found in upper directories!" + exit 1 +fi + +os_fsfw="linux" +tgt_bsp="arm/beagleboneblack" +build_generator="" +builddir="build-Debug-BBB" +defines="LINUX_CROSS_COMPILE=OFF" +if [ "${OS}" = "Windows_NT" ]; then + build_generator="MinGW Makefiles" +# Could be other OS but this works for now. +else + build_generator="Unix Makefiles" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ + -l "${builddir}" -d "${defines}" +# Use this if commands are added which should not be printed +# set +x diff --git a/cmake/scripts/Host/create_cmake_release_cfg.sh b/cmake/scripts/Host/create_cmake_release_cfg.sh deleted file mode 100644 index 19ae5b32..00000000 --- a/cmake/scripts/Host/create_cmake_release_cfg.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "create_cmake_cfg.sh not found in upper directories!" - exit 1 -fi - -build_generator="" -os_fsfw="host" -build_dir="Release-Host" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" -fi - -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -l"${build_dir}" diff --git a/cmake/scripts/Host/create_cmake_relwithdeb_cfg.sh b/cmake/scripts/Host/create_cmake_relwithdeb_cfg.sh deleted file mode 100644 index f9321e69..00000000 --- a/cmake/scripts/Host/create_cmake_relwithdeb_cfg.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "create_cmake_cfg.sh not found in upper directories!" - exit 1 -fi - -build_generator="" -os_fsfw="host" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" -fi - -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "reldeb" diff --git a/cmake/scripts/Host/create_cmake_size_cfg.sh b/cmake/scripts/Host/create_cmake_size_cfg.sh deleted file mode 100644 index 6a3cbe60..00000000 --- a/cmake/scripts/Host/create_cmake_size_cfg.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "create_cmake_cfg.sh not found in upper directories!" - exit 1 -fi - -build_generator="" -os_fsfw="host" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" -fi - -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "size" \ No newline at end of file diff --git a/cmake/scripts/Host/make-debug-cfg.sh b/cmake/scripts/Host/make-debug-cfg.sh new file mode 100755 index 00000000..3bda2da2 --- /dev/null +++ b/cmake/scripts/Host/make-debug-cfg.sh @@ -0,0 +1,32 @@ +#!/bin/sh +counter=0 +cfg_script_name="cmake-build-cfg.py" +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "${cfg_script_name} not found in upper directories!" + exit 1 +fi + +build_generator="Unix Makefiles" +os_fsfw="host" +builddir="build-Debug-Host" +if [ "${OS}" = "Windows_NT" ]; then + python="py" +# Could be other OS but this works for now. +else + python="python3" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}" +# Use this if commands are added which should not be printed +# set +x diff --git a/cmake/scripts/Host/make-release-cfg.sh b/cmake/scripts/Host/make-release-cfg.sh new file mode 100755 index 00000000..eb0a9f57 --- /dev/null +++ b/cmake/scripts/Host/make-release-cfg.sh @@ -0,0 +1,32 @@ +#!/bin/sh +counter=0 +cfg_script_name="cmake-build-cfg.py" +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "${cfg_script_name} not found in upper directories!" + exit 1 +fi + +build_generator="Unix Makefiles" +os_fsfw="host" +builddir="build-Release-Host" +if [ "${OS}" = "Windows_NT" ]; then + python="py" +# Could be other OS but this works for now. +else + python="python3" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "release" -l "${builddir}" +# Use this if commands are added which should not be printed +# set +x diff --git a/cmake/scripts/Host/make_debug_cfg.sh b/cmake/scripts/Host/make_debug_cfg.sh deleted file mode 100755 index 24be2099..00000000 --- a/cmake/scripts/Host/make_debug_cfg.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "create_cmake_cfg.sh not found in upper directories!" - exit 1 -fi - -build_generator="" -build_dir="build-Debug-Host" -os_fsfw="host" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" -fi - -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l"${build_dir}" diff --git a/cmake/scripts/Host/ninja-debug-cfg.sh b/cmake/scripts/Host/ninja-debug-cfg.sh new file mode 100755 index 00000000..d1627174 --- /dev/null +++ b/cmake/scripts/Host/ninja-debug-cfg.sh @@ -0,0 +1,32 @@ +#!/bin/sh +counter=0 +cfg_script_name="cmake-build-cfg.py" +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "${cfg_script_name} not found in upper directories!" + exit 1 +fi + +build_generator="Ninja" +os_fsfw="host" +builddir="build-Debug-Host" +if [ "${OS}" = "Windows_NT" ]; then + python="py" +# Could be other OS but this works for now. +else + python="python3" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}" +# Use this if commands are added which should not be printed +# set +x diff --git a/cmake/scripts/Linux/make_debug_cfg.sh b/cmake/scripts/Linux/make-debug-cfg.sh similarity index 58% rename from cmake/scripts/Linux/make_debug_cfg.sh rename to cmake/scripts/Linux/make-debug-cfg.sh index dc21896d..e2130416 100755 --- a/cmake/scripts/Linux/make_debug_cfg.sh +++ b/cmake/scripts/Linux/make-debug-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "create_cmake_cfg.sh not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi build_generator="Unix Makefiles" @@ -26,7 +27,6 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}" +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}" # Use this if commands are added which should not be printed # set +x - diff --git a/cmake/scripts/Linux/make_release_cfg.sh b/cmake/scripts/Linux/make-release-cfg.sh similarity index 58% rename from cmake/scripts/Linux/make_release_cfg.sh rename to cmake/scripts/Linux/make-release-cfg.sh index 95d87e70..0426967b 100755 --- a/cmake/scripts/Linux/make_release_cfg.sh +++ b/cmake/scripts/Linux/make-release-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "create_cmake_cfg.sh not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi build_generator="Unix Makefiles" @@ -26,6 +27,6 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -l "${builddir}" +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "release" -l "${builddir}" # Use this if commands are added which should not be printed # set +x diff --git a/cmake/scripts/Linux/ninja_debug_cfg.sh b/cmake/scripts/Linux/ninja-debug-cfg.sh similarity index 57% rename from cmake/scripts/Linux/ninja_debug_cfg.sh rename to cmake/scripts/Linux/ninja-debug-cfg.sh index 9627ccf6..905612e0 100755 --- a/cmake/scripts/Linux/ninja_debug_cfg.sh +++ b/cmake/scripts/Linux/ninja-debug-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "create_cmake_cfg.sh not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi build_generator="Ninja" @@ -26,7 +27,7 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}" +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -l "${builddir}" # Use this if commands are added which should not be printed # set +x diff --git a/cmake/scripts/Q7S/make_debug_cfg.sh b/cmake/scripts/Q7S/make-debug-cfg.sh similarity index 59% rename from cmake/scripts/Q7S/make_debug_cfg.sh rename to cmake/scripts/Q7S/make-debug-cfg.sh index 4613d36a..c0807320 100755 --- a/cmake/scripts/Q7S/make_debug_cfg.sh +++ b/cmake/scripts/Q7S/make-debug-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" @@ -29,7 +30,7 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ -l"${build_dir}" # set +x diff --git a/cmake/scripts/Q7S/make_release_cfg.sh b/cmake/scripts/Q7S/make-release-cfg.sh similarity index 59% rename from cmake/scripts/Q7S/make_release_cfg.sh rename to cmake/scripts/Q7S/make-release-cfg.sh index 9d7992f3..c421f336 100755 --- a/cmake/scripts/Q7S/make_release_cfg.sh +++ b/cmake/scripts/Q7S/make-release-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" @@ -29,6 +30,6 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ -l"${build_dir}" # set +x diff --git a/cmake/scripts/Q7S/ninja_debug_cfg.sh b/cmake/scripts/Q7S/ninja-debug-cfg.sh similarity index 56% rename from cmake/scripts/Q7S/ninja_debug_cfg.sh rename to cmake/scripts/Q7S/ninja-debug-cfg.sh index abb68de2..9a6b35c8 100755 --- a/cmake/scripts/Q7S/ninja_debug_cfg.sh +++ b/cmake/scripts/Q7S/ninja-debug-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" @@ -27,7 +28,7 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ -l "${build_dir}" # set +x diff --git a/cmake/scripts/Q7S/ninja_release_cfg.sh b/cmake/scripts/Q7S/ninja-release-cfg.sh similarity index 56% rename from cmake/scripts/Q7S/ninja_release_cfg.sh rename to cmake/scripts/Q7S/ninja-release-cfg.sh index f5431d9a..a9c82d54 100755 --- a/cmake/scripts/Q7S/ninja_release_cfg.sh +++ b/cmake/scripts/Q7S/ninja-release-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" @@ -27,7 +28,7 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ -l"${build_dir}" # set +x diff --git a/cmake/scripts/Q7S/simple/simple_make_debug_cfg.sh b/cmake/scripts/Q7S/simple/make-simple-debug-cfg.sh similarity index 62% rename from cmake/scripts/Q7S/simple/simple_make_debug_cfg.sh rename to cmake/scripts/Q7S/simple/make-simple-debug-cfg.sh index 50b87101..93f4a087 100755 --- a/cmake/scripts/Q7S/simple/simple_make_debug_cfg.sh +++ b/cmake/scripts/Q7S/simple/make-simple-debug-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" @@ -30,6 +31,6 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ -l "${build_dir}" -d "${definitions}" # set +x diff --git a/cmake/scripts/Q7S/simple/simple_ninja_debug_cfg.sh b/cmake/scripts/Q7S/simple/ninja-simple-debug-cfg.sh similarity index 59% rename from cmake/scripts/Q7S/simple/simple_ninja_debug_cfg.sh rename to cmake/scripts/Q7S/simple/ninja-simple-debug-cfg.sh index c97b1e54..c1805eff 100755 --- a/cmake/scripts/Q7S/simple/simple_ninja_debug_cfg.sh +++ b/cmake/scripts/Q7S/simple/ninja-simple-debug-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" @@ -28,7 +29,7 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ -l "${build_dir}" -d "${definitions}" # set +x diff --git a/cmake/scripts/Q7S/watchdog/make_debug_cfg.sh b/cmake/scripts/Q7S/watchdog/make-debug-cfg.sh similarity index 58% rename from cmake/scripts/Q7S/watchdog/make_debug_cfg.sh rename to cmake/scripts/Q7S/watchdog/make-debug-cfg.sh index d5b58df9..0f829fea 100755 --- a/cmake/scripts/Q7S/watchdog/make_debug_cfg.sh +++ b/cmake/scripts/Q7S/watchdog/make-debug-cfg.sh @@ -1,24 +1,25 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" tgt_bsp="arm/q7s" build_dir="build-Debug-Watchdog" build_generator="" -definitions="BUILD_WATCHDOG=ON" +definitions="EIVE_BUILD_WATCHDOG=ON" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" python="py" @@ -30,7 +31,7 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ -d "${definitions}" -l"${build_dir}" # set +x diff --git a/cmake/scripts/Q7S/watchdog/make_release_cfg.sh b/cmake/scripts/Q7S/watchdog/make-release-cfg.sh similarity index 95% rename from cmake/scripts/Q7S/watchdog/make_release_cfg.sh rename to cmake/scripts/Q7S/watchdog/make-release-cfg.sh index 726e82ed..c8df73d5 100755 --- a/cmake/scripts/Q7S/watchdog/make_release_cfg.sh +++ b/cmake/scripts/Q7S/watchdog/make-release-cfg.sh @@ -18,7 +18,7 @@ os_fsfw="linux" tgt_bsp="arm/q7s" build_dir="build-Release-Watchdog" build_generator="" -definitions="BUILD_WATCHDOG=ON" +definitions="EIVE_BUILD_WATCHDOG=ON" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" python="py" diff --git a/cmake/scripts/Q7S/watchdog/ninja_debug_cfg.sh b/cmake/scripts/Q7S/watchdog/ninja-debug-cfg.sh similarity index 55% rename from cmake/scripts/Q7S/watchdog/ninja_debug_cfg.sh rename to cmake/scripts/Q7S/watchdog/ninja-debug-cfg.sh index 99a414e7..ed23bb6a 100755 --- a/cmake/scripts/Q7S/watchdog/ninja_debug_cfg.sh +++ b/cmake/scripts/Q7S/watchdog/ninja-debug-cfg.sh @@ -1,24 +1,25 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" tgt_bsp="arm/q7s" build_dir="build-Debug-Watchdog" build_generator="Ninja" -definitions="-DBUILD_WATCHDOG=ON" +definitions="EIVE_BUILD_WATCHDOG=ON" if [ "${OS}" = "Windows_NT" ]; then python="py" # Could be other OS but this works for now. @@ -28,7 +29,7 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ -d "${definitions}" -l "${build_dir}" # set +x diff --git a/cmake/scripts/Q7S/watchdog/ninja_release_cfg.sh b/cmake/scripts/Q7S/watchdog/ninja-release-cfg.sh similarity index 54% rename from cmake/scripts/Q7S/watchdog/ninja_release_cfg.sh rename to cmake/scripts/Q7S/watchdog/ninja-release-cfg.sh index 3e6beac3..d8f5e18e 100755 --- a/cmake/scripts/Q7S/watchdog/ninja_release_cfg.sh +++ b/cmake/scripts/Q7S/watchdog/ninja-release-cfg.sh @@ -1,24 +1,25 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" tgt_bsp="arm/q7s" build_dir="build-Release-Watchdog" build_generator="Ninja" -definitions="BUILD_WATCHDOG=ON" +definitions="EIVE_BUILD_WATCHDOG=ON" if [ "${OS}" = "Windows_NT" ]; then python="py" # Could be other OS but this works for now. @@ -28,7 +29,7 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ -d "${definitions}" -l"${build_dir}" # set +x diff --git a/cmake/scripts/RPi/make_debug_cfg.sh b/cmake/scripts/RPi/make-debug-cfg.sh similarity index 60% rename from cmake/scripts/RPi/make_debug_cfg.sh rename to cmake/scripts/RPi/make-debug-cfg.sh index dbb178de..3b95ceee 100755 --- a/cmake/scripts/RPi/make_debug_cfg.sh +++ b/cmake/scripts/RPi/make-debug-cfg.sh @@ -1,19 +1,21 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi + os_fsfw="linux" tgt_bsp="arm/raspberrypi" build_generator="" @@ -29,7 +31,6 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ -l"${build_dir}" # set +x - diff --git a/cmake/scripts/RPi/make-release-cfg.sh b/cmake/scripts/RPi/make-release-cfg.sh new file mode 100755 index 00000000..56b48735 --- /dev/null +++ b/cmake/scripts/RPi/make-release-cfg.sh @@ -0,0 +1,33 @@ +#!/bin/sh +counter=0 +cfg_script_name="cmake-build-cfg.py" +while [ ${counter} -lt 5 ] +do + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) +done + +if [ "${counter}" -ge 5 ];then + echo "${cfg_script_name} not found in upper directories!" + exit 1 +fi + +os_fsfw="linux" +tgt_bsp="arm/raspberrypi" +build_generator="" +build_dir="build-Release-RPi" +if [ "${OS}" = "Windows_NT" ]; then + build_generator="MinGW Makefiles" +# Could be other OS but this works for now. +else + build_generator="Unix Makefiles" +fi + +echo "Running command (without the leading +):" +set -x # Print command +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ + -l"${build_dir}" +# set +x diff --git a/cmake/scripts/RPi/make_release_cfg.sh b/cmake/scripts/RPi/make_release_cfg.sh deleted file mode 100755 index 10e4b777..00000000 --- a/cmake/scripts/RPi/make_release_cfg.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh -counter=0 -while [ ${counter} -lt 5 ] -do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) -done - -if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 -fi - -os_fsfw="linux" -tgt_bsp="arm/raspberrypi" -build_generator="" -build_dir="build-Release-RPi" -if [ "${OS}" = "Windows_NT" ]; then - build_generator="MinGW Makefiles" -# Could be other OS but this works for now. -else - build_generator="Unix Makefiles" -fi - -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ - -l"${build_dir}" diff --git a/cmake/scripts/RPi/ninja_debug_cfg.sh b/cmake/scripts/RPi/ninja-debug-cfg.sh similarity index 56% rename from cmake/scripts/RPi/ninja_debug_cfg.sh rename to cmake/scripts/RPi/ninja-debug-cfg.sh index 3fa0e5f4..4cfb9854 100755 --- a/cmake/scripts/RPi/ninja_debug_cfg.sh +++ b/cmake/scripts/RPi/ninja-debug-cfg.sh @@ -1,17 +1,18 @@ #!/bin/sh counter=0 +cfg_script_name="cmake-build-cfg.py" while [ ${counter} -lt 5 ] do - cd .. - if [ -f "cmake_build_config.py" ];then - break - fi - counter=$((counter=counter + 1)) + cd .. + if [ -f ${cfg_script_name} ];then + break + fi + counter=$((counter=counter + 1)) done if [ "${counter}" -ge 5 ];then - echo "cmake_build_config.py not found in upper directories!" - exit 1 + echo "${cfg_script_name} not found in upper directories!" + exit 1 fi os_fsfw="linux" @@ -27,7 +28,7 @@ fi echo "Running command (without the leading +):" set -x # Print command -${python} cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ +${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ -l"${build_dir}" # set +x diff --git a/cmake/scripts/cmake_build_config.py b/cmake/scripts/cmake-build-cfg.py similarity index 100% rename from cmake/scripts/cmake_build_config.py rename to cmake/scripts/cmake-build-cfg.py -- 2.43.0 From 340ca0618c10081751cb505724038c64c11a6135 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sun, 1 Aug 2021 17:11:32 +0200 Subject: [PATCH 075/116] supervisor mram dump --- mission/devices/PlocSupervisorHandler.cpp | 117 +++++++++++++----- mission/devices/PlocSupervisorHandler.h | 26 +++- .../PlocSupervisorDefinitions.h | 5 +- 3 files changed, 115 insertions(+), 33 deletions(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 7a55e7a6..17ef9a5f 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -191,13 +191,11 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( break; } case(PLOC_SPV::WIPE_MRAM): { - prepareWipeMramCmd(commandData); - result = RETURN_OK; + result = prepareWipeMramCmd(commandData); break; } case(PLOC_SPV::DUMP_MRAM): { - prepareDumpMramCmd(commandData); - result = RETURN_OK; + result = prepareDumpMramCmd(commandData); break; } default: @@ -439,7 +437,7 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite break; } case PLOC_SPV::DUMP_MRAM: { - enabledReplies = expectedMramDumpPackets + 2; + enabledReplies = 2; // expected replies will be increased in handleMramDumpPacket result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, PLOC_SPV::DUMP_MRAM); if (result != RETURN_OK) { @@ -1125,18 +1123,21 @@ ReturnValue_t PlocSupervisorHandler::prepareRunAutoEmTest(const uint8_t* command return RETURN_OK; } -void PlocSupervisorHandler::prepareWipeMramCmd(const uint8_t* commandData) { - uint8_t offset = 0; - uint32_t start = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 - | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); - offset += 4; - uint32_t stop = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 - | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); +ReturnValue_t PlocSupervisorHandler::prepareWipeMramCmd(const uint8_t* commandData) { + uint32_t start = 0; + uint32_t stop = 0; + size_t size = sizeof(start) + sizeof(stop); + SerializeAdapter::deSerialize(&start, &commandData, &size, SerializeIF::Endianness::BIG); + SerializeAdapter::deSerialize(&stop, &commandData, &size, SerializeIF::Endianness::BIG); + if ((stop - start) <= 0) { + return INVALID_MRAM_ADDRESSES; + } PLOC_SPV::MramCmd packet(start, stop, PLOC_SPV::MramCmd::MramAction::WIPE); packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + return RETURN_OK; } -void PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandData) { +ReturnValue_t PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandData) { uint32_t start = 0; uint32_t stop = 0; size_t size = sizeof(start) + sizeof(stop); @@ -1144,14 +1145,15 @@ void PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandData) { SerializeAdapter::deSerialize(&stop, &commandData, &size, SerializeIF::Endianness::BIG); PLOC_SPV::MramCmd packet(start, stop, PLOC_SPV::MramCmd::MramAction::DUMP); packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + if ((stop - start) <= 0) { + return INVALID_MRAM_ADDRESSES; + } expectedMramDumpPackets = (stop - start) / PLOC_SPV::MAX_DATA_CAPACITY; if ((stop - start) % PLOC_SPV::MAX_DATA_CAPACITY) { expectedMramDumpPackets++; - mramLastPktLen = (stop - start) % PLOC_SPV::MAX_DATA_CAPACITY; - } - else { - mramLastPktLen = 0; } + receivedMramDumpPackets = 0; + return RETURN_OK; } void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { @@ -1182,13 +1184,6 @@ void PlocSupervisorHandler::disableAllReplies() { info->command = deviceCommandMap.end(); break; } - case PLOC_SPV::DUMP_MRAM: { - iter = deviceReplyMap.find(PLOC_SPV::DUMP_MRAM); - info = &(iter->second); - info->delayCycles = 0; - info->command = deviceCommandMap.end(); - break; - } default: { break; } @@ -1231,7 +1226,9 @@ void PlocSupervisorHandler::disableExeReportReply() { ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t *packet, size_t remainingSize, size_t* foundLen) { + ReturnValue_t result = IGNORE_FULL_PACKET; uint16_t packetLen = 0; + *foundLen = 0; for (size_t idx = 0; idx < remainingSize; idx++) { std::memcpy(spacePacketBuffer + bufferTop, packet + idx, 1); @@ -1244,7 +1241,7 @@ ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t *packet, siz if (bufferTop == PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1) { packetInBuffer = true; bufferTop = 0; - return RETURN_OK; + return checkMramPacketApid(); } if (bufferTop == PLOC_SPV::MAX_PACKET_SIZE) { @@ -1255,12 +1252,12 @@ ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t *packet, siz } } - return IGNORE_FULL_PACKET; + return result; } ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket() { - ReturnValue_t result = RETURN_OK; + ReturnValue_t result = RETURN_FAILED; // Prepare packet for downlink if (packetInBuffer) { @@ -1268,10 +1265,74 @@ ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket() { result = verifyPacket(spacePacketBuffer, PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1); if (result != RETURN_OK) { sif::warning << "PlocSupervisorHandler::handleMramDumpPacket: CRC failure" << std::endl; + return result; } + //TODO: Write MRAM dump to SD card handler handleDeviceTM(spacePacketBuffer + PLOC_SPV::SPACE_PACKET_HEADER_LENGTH, packetLen - 1, PLOC_SPV::DUMP_MRAM); packetInBuffer = false; + receivedMramDumpPackets++; + if (expectedMramDumpPackets == receivedMramDumpPackets) { + nextReplyId = PLOC_SPV::EXE_REPORT; + } + increaseExpectedMramReplies(); + return RETURN_OK; } - return RETURN_OK; + return result; +} + +void PlocSupervisorHandler::increaseExpectedMramReplies() { + DeviceReplyMap::iterator mramDumpIter = deviceReplyMap.find(PLOC_SPV::DUMP_MRAM); + DeviceReplyMap::iterator exeReportIter = deviceReplyMap.find(PLOC_SPV::EXE_REPORT); + if (mramDumpIter == deviceReplyMap.end()) { + sif::debug << "PlocSupervisorHandler::increaseExpectedMramReplies: Dump MRAM reply not " + << "in reply map" << std::endl; + return; + } + if (exeReportIter == deviceReplyMap.end()) { + sif::debug << "PlocSupervisorHandler::increaseExpectedMramReplies: Execution report not " + << "in reply map" << std::endl; + return; + } + DeviceReplyInfo *mramReplyInfo = &(mramDumpIter->second); + if (mramReplyInfo == nullptr) { + sif::debug << "PlocSupervisorHandler::increaseExpectedReplies: MRAM reply info nullptr" + << std::endl; + return; + } + DeviceReplyInfo *exeReplyInfo = &(exeReportIter->second); + if (exeReplyInfo == nullptr) { + sif::debug << "PlocSupervisorHandler::increaseExpectedReplies: Execution reply info" + << " nullptr" << std::endl; + return; + } + DeviceCommandInfo* info = &(mramReplyInfo->command->second); + if (info == nullptr){ + sif::debug << "PlocSupervisorHandler::increaseExpectedReplies: Command info nullptr" + << std::endl; + return; + } + uint8_t sequenceFlags = spacePacketBuffer[2] >> 6; + if (sequenceFlags != static_cast(PLOC_SPV::SequenceFlags::LAST_PKT)) { + // Command expects at least one MRAM packet more and the execution report + info->expectedReplies = 2; + // Wait maximum of 2 cycles for next MRAM packet + mramReplyInfo->delayCycles = 2; + // Also adapting delay cycles for execution report + exeReplyInfo->delayCycles = 3; + } + else { + // Command expects the execution report + info->expectedReplies = 1; + mramReplyInfo->delayCycles = 0; + } + return; +} + +ReturnValue_t PlocSupervisorHandler::checkMramPacketApid() { + uint16_t apid = (spacePacketBuffer[0] << 8 | spacePacketBuffer[1]) & PLOC_SPV::APID_MASK; + if (apid != PLOC_SPV::APID_MRAM_DUMP_TM) { + return NO_MRAM_PACKET; + } + return APERIODIC_REPLY; } diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index 35098ffb..f316544f 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -75,6 +75,10 @@ private: static const ReturnValue_t INVALID_TEST_PARAM = MAKE_RETURN_CODE(0xAA); //! [EXPORT] : [COMMENT] Returned when scanning for MRAM dump packets failed. static const ReturnValue_t MRAM_PACKET_PARSING_FAILURE = MAKE_RETURN_CODE(0xAB); + //! [EXPORT] : [COMMENT] Returned when the start and stop addresses of the MRAM dump or MRAM wipe commands are invalid (e.g. start address bigger than stop address) + static const ReturnValue_t INVALID_MRAM_ADDRESSES = MAKE_RETURN_CODE(0xAC); + //! [EXPORT] : [COMMENT] Expect reception of an MRAM dump packet but received space packet with other apid. + static const ReturnValue_t NO_MRAM_PACKET = MAKE_RETURN_CODE(0xAD); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; @@ -107,7 +111,7 @@ private: /** Number of expected replies following the MRAM dump command */ uint32_t expectedMramDumpPackets = 0; - size_t mramLastPktLen = 0; + uint32_t receivedMramDumpPackets = 0; /** Set to true as soon as a complete space packet is present in the spacePacketBuffer */ bool packetInBuffer = false; /** Points to the next free position in the space packet buffer */ @@ -237,8 +241,8 @@ private: void prepareEnableNvmsCmd(const uint8_t* commandData); void prepareSelectNvmCmd(const uint8_t* commandData); ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData); - void prepareWipeMramCmd(const uint8_t* commandData); - void prepareDumpMramCmd(const uint8_t* commandData); + ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData); + ReturnValue_t prepareDumpMramCmd(const uint8_t* commandData); /** @@ -274,7 +278,23 @@ private: */ ReturnValue_t parseMramPackets(const uint8_t *packet, size_t remainingSize, size_t* foundlen); + /** + * @brief This function generates the Service 8 packets for the MRAM dump data. + */ ReturnValue_t handleMramDumpPacket(); + + /** + * @brief With this function the number of expected replies following an MRAM dump command + * will be increased. This is necessary to release the command in case not all replies + * have been received. + */ + void increaseExpectedMramReplies(); + + /** + * @brief Function checks if the packet written to the space packet buffer is really a + * MRAM dump packet. + */ + ReturnValue_t checkMramPacketApid(); }; #endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index ff0f7bd9..dc7c792f 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -127,6 +127,8 @@ static const uint16_t APID_REQUEST_LOGGING_DATA = 0xFD; static const uint16_t APID_GET_HK_REPORT = 0xC6; +static const uint16_t APID_MASK = 0x3FF; + /** Offset from first byte in Space packet to first byte of data field */ static const uint8_t DATA_FIELD_OFFSET = 6; @@ -137,7 +139,6 @@ static const uint8_t DATA_FIELD_OFFSET = 6; static const uint16_t LENGTH_EMPTY_TC = 2; // Only CRC will be transported with the data field /** This is the maximum length of a space packet as defined by the TAS ICD */ -//static const size_t MAX_REPLY_SIZE = 1024; static const size_t MAX_COMMAND_SIZE = 1024; static const size_t MAX_DATA_CAPACITY = 1016; /** This is the maximum size of a space packet for the supervisor */ @@ -145,7 +146,7 @@ static const size_t MAX_PACKET_SIZE = 1024; static const uint8_t SPACE_PACKET_HEADER_LENGTH = 6; -enum SequenceFlags { +enum class SequenceFlags: uint8_t { CONTINUED_PKT = 0b00, FIRST_PKT = 0b01, LAST_PKT = 0b10, STANDALONE_PKT = 0b11 }; -- 2.43.0 From 4b4cfc09c5e2dccc3563e66808a970197b5d7958 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 2 Aug 2021 11:43:49 +0200 Subject: [PATCH 076/116] update fsfwgen --- .gitignore | 14 +- generators/.run/events.run.xml | 24 +++ generators/bsp_q7s_events.csv | 192 ++++++++++---------- generators/definitions.py | 5 + generators/events/event_parser.py | 81 +++++---- generators/events/translateEvents.cpp | 2 +- generators/events/translateEvents.h | 2 +- generators/fsfwgen | 2 +- generators/fsfwgen.py | 33 ++++ linux/fsfwconfig/events/translateEvents.cpp | 2 +- linux/fsfwconfig/events/translateEvents.h | 2 +- 11 files changed, 209 insertions(+), 150 deletions(-) create mode 100644 generators/.run/events.run.xml create mode 100755 generators/fsfwgen.py diff --git a/.gitignore b/.gitignore index 564a96fd..c51106ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,15 @@ /build* -Debug -Debug* -Release -Release* - +# Eclipse .settings .metadata .project .cproject -__pycache__ - -.idea - !misc/eclipse/**/.cproject !misc/eclipse/**/.project +# Python +__pycache__ +.idea + generators/*.db diff --git a/generators/.run/events.run.xml b/generators/.run/events.run.xml new file mode 100644 index 00000000..18f71033 --- /dev/null +++ b/generators/.run/events.run.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index d19a79a3..4635788b 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -1,96 +1,96 @@ -2200;STORE_SEND_WRITE_FAILED;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2201;STORE_WRITE_FAILED;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2202;STORE_SEND_READ_FAILED;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2203;STORE_READ_FAILED;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2204;UNEXPECTED_MSG;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2205;STORING_FAILED;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2206;TM_DUMP_FAILED;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2207;STORE_INIT_FAILED;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2208;STORE_INIT_EMPTY;INFO; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2209;STORE_CONTENT_CORRUPTED;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2210;STORE_INITIALIZE;INFO; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2211;INIT_DONE;INFO; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2212;DUMP_FINISHED;INFO; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2213;DELETION_FINISHED;INFO; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2214;DELETION_FAILED;LOW; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2215;AUTO_CATALOGS_SENDING_FAILED;INFO; ;../../fsfw/tmstorage/TmStoreBackendIF.h -2600;GET_DATA_FAILED;LOW; ;../../fsfw/storagemanager/StorageManagerIF.h -2601;STORE_DATA_FAILED;LOW; ;../../fsfw/storagemanager/StorageManagerIF.h -2800;DEVICE_BUILDING_COMMAND_FAILED;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2801;DEVICE_SENDING_COMMAND_FAILED;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2802;DEVICE_REQUESTING_REPLY_FAILED;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2803;DEVICE_READING_REPLY_FAILED;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2805;DEVICE_MISSED_REPLY;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2806;DEVICE_UNKNOWN_REPLY;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2807;DEVICE_UNREQUESTED_REPLY;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2808;INVALID_DEVICE_COMMAND;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2809;MONITORING_LIMIT_EXCEEDED;LOW; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -2810;MONITORING_AMBIGUOUS;HIGH; ;../../fsfw/devicehandlers/DeviceHandlerIF.h -4201;FUSE_CURRENT_HIGH;LOW; ;../../fsfw/power/Fuse.h -4202;FUSE_WENT_OFF;LOW; ;../../fsfw/power/Fuse.h -4204;POWER_ABOVE_HIGH_LIMIT;LOW; ;../../fsfw/power/Fuse.h -4205;POWER_BELOW_LOW_LIMIT;LOW; ;../../fsfw/power/Fuse.h -4300;SWITCH_WENT_OFF;LOW; ;../../fsfw/power/PowerSwitchIF.h -5000;HEATER_ON;INFO; ;../../fsfw/thermal/Heater.h -5001;HEATER_OFF;INFO; ;../../fsfw/thermal/Heater.h -5002;HEATER_TIMEOUT;LOW; ;../../fsfw/thermal/Heater.h -5003;HEATER_STAYED_ON;LOW; ;../../fsfw/thermal/Heater.h -5004;HEATER_STAYED_OFF;LOW; ;../../fsfw/thermal/Heater.h -5200;TEMP_SENSOR_HIGH;LOW; ;../../fsfw/thermal/AbstractTemperatureSensor.h -5201;TEMP_SENSOR_LOW;LOW; ;../../fsfw/thermal/AbstractTemperatureSensor.h -5202;TEMP_SENSOR_GRADIENT;LOW; ;../../fsfw/thermal/AbstractTemperatureSensor.h -5901;COMPONENT_TEMP_LOW;LOW; ;../../fsfw/thermal/ThermalComponentIF.h -5902;COMPONENT_TEMP_HIGH;LOW; ;../../fsfw/thermal/ThermalComponentIF.h -5903;COMPONENT_TEMP_OOL_LOW;LOW; ;../../fsfw/thermal/ThermalComponentIF.h -5904;COMPONENT_TEMP_OOL_HIGH;LOW; ;../../fsfw/thermal/ThermalComponentIF.h -5905;TEMP_NOT_IN_OP_RANGE;LOW; ;../../fsfw/thermal/ThermalComponentIF.h -7101;FDIR_CHANGED_STATE;INFO; ;../../fsfw/fdir/FailureIsolationBase.h -7102;FDIR_STARTS_RECOVERY;MEDIUM; ;../../fsfw/fdir/FailureIsolationBase.h -7103;FDIR_TURNS_OFF_DEVICE;MEDIUM; ;../../fsfw/fdir/FailureIsolationBase.h -7201;MONITOR_CHANGED_STATE;LOW; ;../../fsfw/monitoring/MonitoringIF.h -7202;VALUE_BELOW_LOW_LIMIT;LOW; ;../../fsfw/monitoring/MonitoringIF.h -7203;VALUE_ABOVE_HIGH_LIMIT;LOW; ;../../fsfw/monitoring/MonitoringIF.h -7204;VALUE_OUT_OF_RANGE;LOW; ;../../fsfw/monitoring/MonitoringIF.h -7301;SWITCHING_TM_FAILED;LOW; ;../../fsfw/datapool/HkSwitchHelper.h -7400;CHANGING_MODE;INFO; ;../../fsfw/modes/HasModesIF.h -7401;MODE_INFO;INFO; ;../../fsfw/modes/HasModesIF.h -7402;FALLBACK_FAILED;HIGH; ;../../fsfw/modes/HasModesIF.h -7403;MODE_TRANSITION_FAILED;LOW; ;../../fsfw/modes/HasModesIF.h -7404;CANT_KEEP_MODE;HIGH; ;../../fsfw/modes/HasModesIF.h -7405;OBJECT_IN_INVALID_MODE;LOW; ;../../fsfw/modes/HasModesIF.h -7406;FORCING_MODE;MEDIUM; ;../../fsfw/modes/HasModesIF.h -7407;MODE_CMD_REJECTED;LOW; ;../../fsfw/modes/HasModesIF.h -7506;HEALTH_INFO;INFO; ;../../fsfw/health/HasHealthIF.h -7507;CHILD_CHANGED_HEALTH;INFO; ;../../fsfw/health/HasHealthIF.h -7508;CHILD_PROBLEMS;LOW; ;../../fsfw/health/HasHealthIF.h -7509;OVERWRITING_HEALTH;LOW; ;../../fsfw/health/HasHealthIF.h -7510;TRYING_RECOVERY;MEDIUM; ;../../fsfw/health/HasHealthIF.h -7511;RECOVERY_STEP;MEDIUM; ;../../fsfw/health/HasHealthIF.h -7512;RECOVERY_DONE;MEDIUM; ;../../fsfw/health/HasHealthIF.h -7900;RF_AVAILABLE;INFO; ;../../fsfw/datalinklayer/DataLinkLayer.h -7901;RF_LOST;INFO; ;../../fsfw/datalinklayer/DataLinkLayer.h -7902;BIT_LOCK;INFO; ;../../fsfw/datalinklayer/DataLinkLayer.h -7903;BIT_LOCK_LOST;INFO; ;../../fsfw/datalinklayer/DataLinkLayer.h -7905;FRAME_PROCESSING_FAILED;LOW; ;../../fsfw/datalinklayer/DataLinkLayer.h -8900;CLOCK_SET;INFO; ;../../fsfw/pus/Service9TimeManagement.h -8901;CLOCK_SET_FAILURE;LOW; ;../../fsfw/pus/Service9TimeManagement.h -9700;TEST;INFO; ;../../fsfw/pus/Service17Test.h -10600;CHANGE_OF_SETUP_PARAMETER;LOW; ;../../mission/devices/MGMHandlerLIS3MDL.h -11101;MEMORY_READ_RPT_CRC_FAILURE;LOW; ;../../mission/devices/PlocMPSoCHandler.h -11102;ACK_FAILURE;LOW; ;../../mission/devices/PlocMPSoCHandler.h -11103;EXE_FAILURE;LOW; ;../../mission/devices/PlocMPSoCHandler.h -11104;CRC_FAILURE_EVENT;LOW; ;../../mission/devices/PlocMPSoCHandler.h -11201;SELF_TEST_I2C_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h -11202;SELF_TEST_SPI_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h -11203;SELF_TEST_ADC_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h -11204;SELF_TEST_PWM_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h -11205;SELF_TEST_TC_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h -11206;SELF_TEST_MTM_RANGE_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h -11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW; ;../../mission/devices/IMTQHandler.h -11208;INVALID_ERROR_BYTE;LOW; ;../../mission/devices/IMTQHandler.h -11301;ERROR_STATE;HIGH; ;../../mission/devices/RwHandler.h -11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW; ;../../mission/devices/PlocSupervisorHandler.h -11502;SUPV_ACK_FAILURE;LOW; ;../../mission/devices/PlocSupervisorHandler.h -11503;SUPV_EXE_FAILURE;LOW; ;../../mission/devices/PlocSupervisorHandler.h -11504;SUPV_CRC_FAILURE_EVENT;LOW; ;../../mission/devices/PlocSupervisorHandler.h +2200;STORE_SEND_WRITE_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2201;STORE_WRITE_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2202;STORE_SEND_READ_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2203;STORE_READ_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2204;UNEXPECTED_MSG;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2205;STORING_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2206;TM_DUMP_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2207;STORE_INIT_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2208;STORE_INIT_EMPTY;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2209;STORE_CONTENT_CORRUPTED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2210;STORE_INITIALIZE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2211;INIT_DONE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2212;DUMP_FINISHED;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2213;DELETION_FINISHED;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2214;DELETION_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2600;GET_DATA_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2601;STORE_DATA_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2803;DEVICE_READING_REPLY_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2805;DEVICE_MISSED_REPLY;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2806;DEVICE_UNKNOWN_REPLY;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2807;DEVICE_UNREQUESTED_REPLY;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2809;MONITORING_LIMIT_EXCEEDED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2810;MONITORING_AMBIGUOUS;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +4201;FUSE_CURRENT_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h +4202;FUSE_WENT_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h +4204;POWER_ABOVE_HIGH_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h +4205;POWER_BELOW_LOW_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h +4300;SWITCH_WENT_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h +5000;HEATER_ON;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h +5001;HEATER_OFF;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h +5002;HEATER_TIMEOUT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h +5003;HEATER_STAYED_ON;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h +5004;HEATER_STAYED_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h +5200;TEMP_SENSOR_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5201;TEMP_SENSOR_LOW;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5202;TEMP_SENSOR_GRADIENT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5901;COMPONENT_TEMP_LOW;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5902;COMPONENT_TEMP_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5903;COMPONENT_TEMP_OOL_LOW;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5904;COMPONENT_TEMP_OOL_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5905;TEMP_NOT_IN_OP_RANGE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +7101;FDIR_CHANGED_STATE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7102;FDIR_STARTS_RECOVERY;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7201;MONITOR_CHANGED_STATE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7202;VALUE_BELOW_LOW_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7204;VALUE_OUT_OF_RANGE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7301;SWITCHING_TM_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/HkSwitchHelper.h +7400;CHANGING_MODE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h +7401;MODE_INFO;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h +7402;FALLBACK_FAILED;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h +7403;MODE_TRANSITION_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h +7404;CANT_KEEP_MODE;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h +7405;OBJECT_IN_INVALID_MODE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h +7406;FORCING_MODE;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h +7407;MODE_CMD_REJECTED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h +7506;HEALTH_INFO;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h +7507;CHILD_CHANGED_HEALTH;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h +7508;CHILD_PROBLEMS;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h +7509;OVERWRITING_HEALTH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h +7510;TRYING_RECOVERY;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h +7511;RECOVERY_STEP;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h +7512;RECOVERY_DONE;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h +7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +8900;CLOCK_SET;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +8901;CLOCK_SET_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +9700;TEST;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service17Test.h +10600;CHANGE_OF_SETUP_PARAMETER;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/MGMHandlerLIS3MDL.h +11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h +11102;ACK_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h +11103;EXE_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h +11104;CRC_FAILURE_EVENT;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h +11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h +11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h +11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h +11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h +11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h +11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h +11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h +11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h +11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h +11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervrisor crc failure in telemetry packet;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h +11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h +11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h +11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h diff --git a/generators/definitions.py b/generators/definitions.py index 42cf4f7b..528c3019 100644 --- a/generators/definitions.py +++ b/generators/definitions.py @@ -1,5 +1,10 @@ +import os import enum +from pathlib import Path +PATH_VAR_ROOT = Path(os.path.abspath(os.curdir)) +ROOT_DIR = PATH_VAR_ROOT.absolute() +OBSW_ROOT_DIR = PATH_VAR_ROOT.parent.absolute() DATABASE_NAME = "eive_mod.db" diff --git a/generators/events/event_parser.py b/generators/events/event_parser.py index 565f2240..56cc076f 100644 --- a/generators/events/event_parser.py +++ b/generators/events/event_parser.py @@ -1,23 +1,18 @@ -#! /usr/bin/python3 -""" -@file event_parser.py -@brief Part of the Mission Information Base Exporter for the SOURCE project by KSat. -@details +"""Part of the Mission Operation Database Exporter for the EVIE project. Event exporter. - -To use MySQLdb, run pip install mysqlclient or install in IDE. -On Windows, Build Tools installation might be necessary -@data 21.11.2019 """ import datetime +import time -from fsfwgen.events.event_parser import handle_csv_export, handle_cpp_export, SubsystemDefinitionParser, EventParser +from fsfwgen.events.event_parser import handle_csv_export, handle_cpp_export, \ + SubsystemDefinitionParser, EventParser from fsfwgen.parserbase.file_list_parser import FileListParser from fsfwgen.utility.printer import PrettyPrinter from fsfwgen.utility.file_management import copy_file, move_file +from fsfwgen.core import get_console_logger +from definitions import BspType, ROOT_DIR, OBSW_ROOT_DIR -from definitions import BspType - +LOGGER = get_console_logger() DATE_TODAY = datetime.datetime.now() DATE_STRING_FULL = DATE_TODAY.strftime("%Y-%m-%d %H:%M:%S") @@ -30,56 +25,67 @@ MOVE_CSV_FILE = True PARSE_HOST_BSP = True -CPP_FILENAME = "translateEvents.cpp" -CPP_H_FILENAME = "translateEvents.h" +CPP_FILENAME = f'{__package__}/translateEvents.cpp' +CPP_H_FILENAME = f'{__package__}/translateEvents.h' BSP_SELECT = BspType.BSP_Q7S BSP_DIR_NAME = BSP_SELECT.value CSV_FILENAME = f"{BSP_SELECT.value}_events.csv" -CSV_MOVE_DESTINATION = "../" +CSV_MOVE_DESTINATION = f'{ROOT_DIR}' if BSP_SELECT == BspType.BSP_Q7S or BSP_SELECT == BspType.BSP_LINUX_BOARD: - FSFW_CONFIG_ROOT = f"../../linux/fsfwconfig" + FSFW_CONFIG_ROOT = f"{OBSW_ROOT_DIR}/linux/fsfwconfig" else: - FSFW_CONFIG_ROOT = f"../../{BSP_DIR_NAME}/fsfwconfig" + FSFW_CONFIG_ROOT = f"{OBSW_ROOT_DIR}/{BSP_DIR_NAME}/fsfwconfig" CPP_COPY_DESTINATION = f"{FSFW_CONFIG_ROOT}/events/" FILE_SEPARATOR = ";" SUBSYSTEM_DEFINITION_DESTINATIONS = [ f"{FSFW_CONFIG_ROOT}/events/subsystemIdRanges.h", - "../../fsfw/events/fwSubsystemIdRanges.h", - f"../../common/config/commonSubsystemIds.h" + f"{OBSW_ROOT_DIR}/fsfw/src/fsfw/events/fwSubsystemIdRanges.h", + f"{OBSW_ROOT_DIR}/common/config/commonSubsystemIds.h" +] +HEADER_DEFINITION_DESTINATIONS = [ + f"{OBSW_ROOT_DIR}/mission/", f"{OBSW_ROOT_DIR}/fsfw/", f"{FSFW_CONFIG_ROOT}", + f"{OBSW_ROOT_DIR}/test/" ] -HEADER_DEFINITION_DESTINATIONS = ["../../mission/", "../../fsfw/", f"{FSFW_CONFIG_ROOT}", "../../test/"] -def main(): - print("EventParser: Parsing events: ") - event_list = parse_events() - if GENERATE_CSV: - handle_csv_export(file_name=CSV_FILENAME, event_list=event_list, file_separator=FILE_SEPARATOR) - if MOVE_CSV_FILE: - move_file(file_name=CSV_FILENAME, destination=CSV_MOVE_DESTINATION) - if GENERATE_CPP: +def parse_events( + generate_csv: bool = True, generate_cpp: bool = True, print_events: bool = True +): + LOGGER.info("EventParser: Parsing events: ") + # Small delay for clean printout + time.sleep(0.01) + event_list = generate_event_list() + if print_events: + PrettyPrinter.pprint(event_list) + # Delay for clean printout + time.sleep(0.1) + # xml_test() + if generate_csv: + handle_csv_export( + file_name=CSV_FILENAME, event_list=event_list, file_separator=FILE_SEPARATOR + ) + if generate_cpp: handle_cpp_export( event_list=event_list, date_string=DATE_STRING_FULL, file_name=CPP_FILENAME, generate_header=GENERATE_CPP_H, header_file_name=CPP_H_FILENAME ) if COPY_CPP_FILE: - print(f"EventParser: Copying file to {CPP_COPY_DESTINATION}") + LOGGER.info(f'EventParser: Copying file to {CPP_COPY_DESTINATION}') copy_file(CPP_FILENAME, CPP_COPY_DESTINATION) copy_file(CPP_H_FILENAME, CPP_COPY_DESTINATION) - print("") -def parse_events(): +def generate_event_list() -> list: subsystem_parser = SubsystemDefinitionParser(SUBSYSTEM_DEFINITION_DESTINATIONS) subsystem_table = subsystem_parser.parse_files() - print(f"Found {len(subsystem_table)} subsystem definitions.") + LOGGER.info(f'Found {len(subsystem_table)} subsystem definitions.') PrettyPrinter.pprint(subsystem_table) event_header_parser = FileListParser(HEADER_DEFINITION_DESTINATIONS) event_headers = event_header_parser.parse_header_files( @@ -90,11 +96,6 @@ def parse_events(): event_parser = EventParser(event_headers, subsystem_table) event_parser.set_moving_window_mode(moving_window_size=7) event_table = event_parser.parse_files() - list_items = sorted(event_table.items()) - print(f"Found {len(list_items)} entries:") - PrettyPrinter.pprint(list_items) - return list_items - - -if __name__ == "__main__": - main() + event_list = sorted(event_table.items()) + LOGGER.info(f'Found {len(event_list)} entries') + return event_list diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 20521618..0df84ad2 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 96 translations. * @details - * Generated on: 2021-07-12 15:20:38 + * Generated on: 2021-08-02 11:41:47 */ #include "translateEvents.h" diff --git a/generators/events/translateEvents.h b/generators/events/translateEvents.h index 9034dcf2..bdabb21b 100644 --- a/generators/events/translateEvents.h +++ b/generators/events/translateEvents.h @@ -1,7 +1,7 @@ #ifndef FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ #define FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ -#include +#include "fsfw/events/Event.h" const char * translateEvents(Event event); diff --git a/generators/fsfwgen b/generators/fsfwgen index 78e890f9..8e805d24 160000 --- a/generators/fsfwgen +++ b/generators/fsfwgen @@ -1 +1 @@ -Subproject commit 78e890f947f55a9417d390fea8d9bd5684d11730 +Subproject commit 8e805d24088707ad7bc49fda5f1dc5edfa1154b0 diff --git a/generators/fsfwgen.py b/generators/fsfwgen.py new file mode 100755 index 00000000..61a71925 --- /dev/null +++ b/generators/fsfwgen.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +import time + +from objects.objects import parse_objects +from events.event_parser import parse_events +from returnvalues.returnvalues_parser import parse_returnvalues +from fsfwgen.core import return_generic_args_parser, init_printout, get_console_logger, ParserTypes + + +LOGGER = get_console_logger() + + +def main(): + init_printout() + parser = return_generic_args_parser() + args = parser.parse_args() + if args.type == 'objects': + LOGGER.info(f'Generating objects data..') + time.sleep(0.05) + parse_objects() + elif args.type == 'events': + LOGGER.info(f'Generating event data') + time.sleep(0.05) + parse_events() + elif args.type == 'returnvalues': + LOGGER.info('Generating returnvalue data') + time.sleep(0.05) + parse_returnvalues() + pass + + +if __name__ == "__main__": + main() diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 20521618..0df84ad2 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 96 translations. * @details - * Generated on: 2021-07-12 15:20:38 + * Generated on: 2021-08-02 11:41:47 */ #include "translateEvents.h" diff --git a/linux/fsfwconfig/events/translateEvents.h b/linux/fsfwconfig/events/translateEvents.h index 9034dcf2..bdabb21b 100644 --- a/linux/fsfwconfig/events/translateEvents.h +++ b/linux/fsfwconfig/events/translateEvents.h @@ -1,7 +1,7 @@ #ifndef FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ #define FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ -#include +#include "fsfw/events/Event.h" const char * translateEvents(Event event); -- 2.43.0 From 528b3c861039a0f3a0c80006f02f4b17964b9d5a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 2 Aug 2021 11:49:00 +0200 Subject: [PATCH 077/116] updated object file generator --- generators/.run/objects.run.xml | 24 ++++++ generators/bsp_q7s_objects.csv | 5 +- generators/objects/objects.py | 76 +++++++++---------- generators/objects/translateObjects.cpp | 15 ++-- linux/fsfwconfig/objects/translateObjects.cpp | 15 ++-- 5 files changed, 79 insertions(+), 56 deletions(-) create mode 100644 generators/.run/objects.run.xml diff --git a/generators/.run/objects.run.xml b/generators/.run/objects.run.xml new file mode 100644 index 00000000..961b8ed9 --- /dev/null +++ b/generators/.run/objects.run.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index cf3e082a..d0e9bfb6 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -68,8 +68,9 @@ 0x49050001;CSP_COM_IF 0x50000100;CCSDS_PACKET_DISTRIBUTOR 0x50000200;PUS_PACKET_DISTRIBUTOR -0x50000300;UDP_BRIDGE -0x50000400;UDP_POLLING_TASK +0x50000300;TMTC_BRIDGE +0x50000400;TMTC_POLLING_TASK +0x50000500;FILE_SYSTEM_HANDLER 0x51000500;PUS_SERVICE_6 0x53000000;FSFW_OBJECTS_START 0x53000001;PUS_SERVICE_1_VERIFICATION diff --git a/generators/objects/objects.py b/generators/objects/objects.py index d37b80d7..194ee9da 100644 --- a/generators/objects/objects.py +++ b/generators/objects/objects.py @@ -1,22 +1,18 @@ -#! /usr/bin/env python3 -""" -@file objects.py -@brief Part of the Mission Information Base Exporter for the SOURCE project by KSat. -@details +"""Part of the Mission Information Base Exporter for the SOURCE project by KSat. Object exporter. -To use MySQLdb, run pip install mysqlclient or install in IDE. -On Windows, Build Tools installation might be necessary -@data 21.11.2019 """ import datetime -from fsfwgen.objects.objects import sql_object_exporter, ObjectDefinitionParser, write_translation_file, \ +from fsfwgen.core import get_console_logger +from fsfwgen.objects.objects import sql_object_exporter, ObjectDefinitionParser, \ + write_translation_file, \ export_object_file, write_translation_header_file from fsfwgen.utility.printer import PrettyPrinter from fsfwgen.utility.file_management import copy_file, move_file -from definitions import BspType, DATABASE_NAME +from definitions import BspType, DATABASE_NAME, OBSW_ROOT_DIR, ROOT_DIR +LOGGER = get_console_logger() DATE_TODAY = datetime.datetime.now() DATE_STRING_FULL = DATE_TODAY.strftime("%Y-%m-%d %H:%M:%S") @@ -31,23 +27,23 @@ GENERATE_HEADER = True BSP_SELECT = BspType.BSP_Q7S BSP_DIR_NAME = BSP_SELECT.value if BSP_SELECT == BspType.BSP_Q7S or BSP_SELECT == BspType.BSP_LINUX_BOARD: - FSFW_CONFIG_ROOT = f"../../linux/fsfwconfig" + FSFW_CONFIG_ROOT = f"{OBSW_ROOT_DIR}/linux/fsfwconfig" else: - FSFW_CONFIG_ROOT = f"../../{BSP_DIR_NAME}/fsfwconfig" + FSFW_CONFIG_ROOT = f"{OBSW_ROOT_DIR}/{BSP_DIR_NAME}/fsfwconfig" EXPORT_TO_SQL = True CPP_COPY_DESTINATION = f"{FSFW_CONFIG_ROOT}/objects/" -CSV_MOVE_DESTINATION = "../" -CPP_FILENAME = "translateObjects.cpp" -CPP_H_FILENAME = "translateObjects.h" +CSV_MOVE_DESTINATION = f"{ROOT_DIR}" +CPP_FILENAME = f'{__package__}/translateObjects.cpp' +CPP_H_FILENAME = f'{__package__}/translateObjects.h' CSV_OBJECT_FILENAME = f"{BSP_SELECT.value}_objects.csv" FILE_SEPARATOR = ";" OBJECTS_PATH = f"{FSFW_CONFIG_ROOT}/objects/systemObjectList.h" -FRAMEWORK_OBJECT_PATH = "../../fsfw/objectmanager/frameworkObjects.h" -COMMON_OBJECTS_PATH = "../../common/config/commonObjects.h" +FRAMEWORK_OBJECT_PATH = f'{OBSW_ROOT_DIR}/fsfw/src/fsfw/objectmanager/frameworkObjects.h' +COMMON_OBJECTS_PATH = f'{OBSW_ROOT_DIR}/common/config/commonObjects.h' OBJECTS_DEFINITIONS = [OBJECTS_PATH, FRAMEWORK_OBJECT_PATH, COMMON_OBJECTS_PATH] SQL_DELETE_OBJECTS_CMD = """ @@ -68,33 +64,33 @@ VALUES(?,?) """ -def main(): - print("Parsing objects: ") - list_items = parse_objects() - handle_file_export(list_items) - if EXPORT_TO_SQL: - print("ObjectParser: Exporting to SQL") - sql_object_exporter( - object_table=list_items, delete_cmd=SQL_DELETE_OBJECTS_CMD, insert_cmd=SQL_INSERT_INTO_OBJECTS_CMD, - create_cmd=SQL_CREATE_OBJECTS_CMD, db_filename=f"../{DATABASE_NAME}" - ) - - -def parse_objects(): +def parse_objects(print_object_list: bool = True): # fetch objects object_parser = ObjectDefinitionParser(OBJECTS_DEFINITIONS) subsystem_definitions = object_parser.parse_files() # id_subsystem_definitions.update(framework_subsystem_definitions) list_items = sorted(subsystem_definitions.items()) - PrettyPrinter.pprint(list_items) - print("ObjectParser: Number of objects: ", len(list_items)) - return list_items + LOGGER.info(f'ObjectParser: Number of objects: {len(list_items)}') + + if print_object_list: + PrettyPrinter.pprint(list_items) + + handle_file_export(list_items) + if EXPORT_TO_SQL: + LOGGER.info('ObjectParser: Exporting to SQL') + sql_object_exporter( + object_table=list_items, delete_cmd=SQL_DELETE_OBJECTS_CMD, + insert_cmd=SQL_INSERT_INTO_OBJECTS_CMD, + create_cmd=SQL_CREATE_OBJECTS_CMD, db_filename=f"{ROOT_DIR}/{DATABASE_NAME}" + ) def handle_file_export(list_items): if GENERATE_CPP: - print("ObjectParser: Generating translation C++ file.") - write_translation_file(filename=CPP_FILENAME, list_of_entries=list_items, date_string_full=DATE_STRING_FULL) + LOGGER.info('ObjectParser: Generating translation C++ file') + write_translation_file( + filename=CPP_FILENAME, list_of_entries=list_items, date_string_full=DATE_STRING_FULL + ) if COPY_CPP: print("ObjectParser: Copying object file to " + CPP_COPY_DESTINATION) copy_file(CPP_FILENAME, CPP_COPY_DESTINATION) @@ -103,10 +99,6 @@ def handle_file_export(list_items): copy_file(filename=CPP_H_FILENAME, destination=CPP_COPY_DESTINATION) if GENERATE_CSV: print("ObjectParser: Generating text export.") - export_object_file(filename=CSV_OBJECT_FILENAME, object_list=list_items, file_separator=FILE_SEPARATOR) - if MOVE_CSV: - move_file(file_name=CSV_OBJECT_FILENAME, destination=CSV_MOVE_DESTINATION) - - -if __name__ == "__main__": - main() + export_object_file( + filename=CSV_OBJECT_FILENAME, object_list=list_items, file_separator=FILE_SEPARATOR + ) diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index cf9db4ca..80bfdd60 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 102 translations. - * Generated on: 2021-07-10 16:22:55 + * Contains 103 translations. + * Generated on: 2021-08-02 11:48:50 */ #include "translateObjects.h" @@ -76,8 +76,9 @@ const char *I2C_COM_IF_STRING = "I2C_COM_IF"; const char *CSP_COM_IF_STRING = "CSP_COM_IF"; const char *CCSDS_PACKET_DISTRIBUTOR_STRING = "CCSDS_PACKET_DISTRIBUTOR"; const char *PUS_PACKET_DISTRIBUTOR_STRING = "PUS_PACKET_DISTRIBUTOR"; -const char *UDP_BRIDGE_STRING = "UDP_BRIDGE"; -const char *UDP_POLLING_TASK_STRING = "UDP_POLLING_TASK"; +const char *TMTC_BRIDGE_STRING = "TMTC_BRIDGE"; +const char *TMTC_POLLING_TASK_STRING = "TMTC_POLLING_TASK"; +const char *FILE_SYSTEM_HANDLER_STRING = "FILE_SYSTEM_HANDLER"; const char *PUS_SERVICE_6_STRING = "PUS_SERVICE_6"; const char *FSFW_OBJECTS_START_STRING = "FSFW_OBJECTS_START"; const char *PUS_SERVICE_1_VERIFICATION_STRING = "PUS_SERVICE_1_VERIFICATION"; @@ -252,9 +253,11 @@ const char* translateObject(object_id_t object) { case 0x50000200: return PUS_PACKET_DISTRIBUTOR_STRING; case 0x50000300: - return UDP_BRIDGE_STRING; + return TMTC_BRIDGE_STRING; case 0x50000400: - return UDP_POLLING_TASK_STRING; + return TMTC_POLLING_TASK_STRING; + case 0x50000500: + return FILE_SYSTEM_HANDLER_STRING; case 0x51000500: return PUS_SERVICE_6_STRING; case 0x53000000: diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index cf9db4ca..80bfdd60 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 102 translations. - * Generated on: 2021-07-10 16:22:55 + * Contains 103 translations. + * Generated on: 2021-08-02 11:48:50 */ #include "translateObjects.h" @@ -76,8 +76,9 @@ const char *I2C_COM_IF_STRING = "I2C_COM_IF"; const char *CSP_COM_IF_STRING = "CSP_COM_IF"; const char *CCSDS_PACKET_DISTRIBUTOR_STRING = "CCSDS_PACKET_DISTRIBUTOR"; const char *PUS_PACKET_DISTRIBUTOR_STRING = "PUS_PACKET_DISTRIBUTOR"; -const char *UDP_BRIDGE_STRING = "UDP_BRIDGE"; -const char *UDP_POLLING_TASK_STRING = "UDP_POLLING_TASK"; +const char *TMTC_BRIDGE_STRING = "TMTC_BRIDGE"; +const char *TMTC_POLLING_TASK_STRING = "TMTC_POLLING_TASK"; +const char *FILE_SYSTEM_HANDLER_STRING = "FILE_SYSTEM_HANDLER"; const char *PUS_SERVICE_6_STRING = "PUS_SERVICE_6"; const char *FSFW_OBJECTS_START_STRING = "FSFW_OBJECTS_START"; const char *PUS_SERVICE_1_VERIFICATION_STRING = "PUS_SERVICE_1_VERIFICATION"; @@ -252,9 +253,11 @@ const char* translateObject(object_id_t object) { case 0x50000200: return PUS_PACKET_DISTRIBUTOR_STRING; case 0x50000300: - return UDP_BRIDGE_STRING; + return TMTC_BRIDGE_STRING; case 0x50000400: - return UDP_POLLING_TASK_STRING; + return TMTC_POLLING_TASK_STRING; + case 0x50000500: + return FILE_SYSTEM_HANDLER_STRING; case 0x51000500: return PUS_SERVICE_6_STRING; case 0x53000000: -- 2.43.0 From 009234612a1c54d86996a11f00765b622d0cb61b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 2 Aug 2021 12:50:36 +0200 Subject: [PATCH 078/116] updated retval list --- common/config/commonClassIds.h | 10 +- fsfw | 2 +- generators/.run/returnvalues.run.xml | 24 + generators/bsp_q7s_returnvalues.csv | 854 +++++++++--------- generators/fsfwgen | 2 +- .../returnvalues/returnvalues_parser.py | 67 +- linux/devices/HeaterHandler.h | 15 +- linux/fsfwconfig/returnvalues/classIds.h | 1 + mission/devices/GomspaceDeviceHandler.cpp | 571 ++++++------ mission/devices/GomspaceDeviceHandler.h | 191 ++-- 10 files changed, 905 insertions(+), 832 deletions(-) create mode 100644 generators/.run/returnvalues.run.xml diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index 977cbdb2..6a27c286 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -13,12 +13,12 @@ enum commonClassIds: uint8_t { HEATER_HANDLER, //HEATER SYRLINKS_HANDLER, //SYRLINKS IMTQ_HANDLER, //IMTQ - RW_HANDLER, //Reaction Wheels - STR_HANDLER, //Star tracker - PLOC_MPSOC_HANDLER, //PLOC MPSoC - PLOC_SUPERVISOR_HANDLER, //PLOC Supervisor + RW_HANDLER, //RWHA + STR_HANDLER, //STRH + PLOC_MPSOC_HANDLER, //PLMP + PLOC_SUPERVISOR_HANDLER, //PLSV SUS_HANDLER, //SUSS - CCSDS_IP_CORE_BRIDGE, // IP Core interface + CCSDS_IP_CORE_BRIDGE, //IPCI COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/fsfw b/fsfw index 54c028f9..0ff81294 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 54c028f913e81077855aa1ed727bac43e7efea82 +Subproject commit 0ff81294e7e209bb4a26171b10d80fe522e65bcf diff --git a/generators/.run/returnvalues.run.xml b/generators/.run/returnvalues.run.xml new file mode 100644 index 00000000..51b16449 --- /dev/null +++ b/generators/.run/returnvalues.run.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index 9cad2a74..99529d17 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -1,407 +1,451 @@ 0x0;OK;System-wide code for ok.;RETURN_OK;HasReturnvaluesIF.h;HasReturnvaluesIF 0x1;Failed;Unspecified system-wide code for failed.;RETURN_FAILED;HasReturnvaluesIF.h;HasReturnvaluesIF -0xe0;_PacketTooLong;;0xE0;../../mission/devices/GomspaceDeviceHandler.h; -0xe1;_InvalidTableId;;0xE1;../../mission/devices/GomspaceDeviceHandler.h; -0xe2;_InvalidAddress;;0xE2;../../mission/devices/GomspaceDeviceHandler.h; -0xe3;_InvalidParamSize;;0xE3;../../mission/devices/GomspaceDeviceHandler.h; -0xe4;_InvalidPayloadSize;;0xE4;../../mission/devices/GomspaceDeviceHandler.h; -0xe5;_UnknownReplyId;;0xE5;../../mission/devices/GomspaceDeviceHandler.h; -0x4da0;PLOC_CrcFailure;;0xA0;../../mission/devices/PlocHandler.h;PLOC_HANDLER -0x4da1;PLOC_ReceivedAckFailure;;0xA1;../../mission/devices/PlocHandler.h;PLOC_HANDLER -0x4da2;PLOC_ReceivedExeFailure;;0xA2;../../mission/devices/PlocHandler.h;PLOC_HANDLER -0x4da3;PLOC_InvalidApid;;0xA3;../../mission/devices/PlocHandler.h;PLOC_HANDLER -0x4ca0;IMTQ_InvalidCommandCode;;0xA0;../../mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x4ca1;IMTQ_ParameterMissing;;0xA1;../../mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x4ca2;IMTQ_ParameterInvalid;;0xA2;../../mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x4ca3;IMTQ_CcUnavailable;;0xA3;../../mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x4ca4;IMTQ_InternalProcessingError;;0xA4;../../mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x4ca5;IMTQ_RejectedWithoutReason;;0xA5;../../mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x4ca6;IMTQ_CmdErrUnknown;;0xA6;../../mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x4ba0;SYRLINKS_CrcFailure;;0xA0;../../mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4ba1;SYRLINKS_UartFraminOrParityErrorAck;;0xA1;../../mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4ba2;SYRLINKS_BadCharacterAck;;0xA2;../../mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4ba3;SYRLINKS_BadParameterValueAck;;0xA3;../../mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4ba4;SYRLINKS_BadEndOfFrameAck;;0xA4;../../mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4ba5;SYRLINKS_UnknownCommandIdAck;;0xA5;../../mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4ba6;SYRLINKS_BadCrcAck;;0xA6;../../mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4ba7;SYRLINKS_ReplyWrongSize;;0xA7;../../mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4ba8;SYRLINKS_MissingStartFrameCharacter;;0xA8;../../mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x2b01;CCS_BcIsSetVrCommand;;0x01;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2b02;CCS_BcIsUnlockCommand;;0x02;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bb0;CCS_BcIllegalCommand;;0xB0;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bb1;CCS_BoardReadingNotFinished;;0xB1;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf0;CCS_NsPositiveW;;0xF0;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf1;CCS_NsNegativeW;;0xF1;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf2;CCS_NsLockout;;0xF2;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf3;CCS_FarmInLockout;;0xF3;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf4;CCS_FarmInWait;;0xF4;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be0;CCS_WrongSymbol;;0xE0;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be1;CCS_DoubleStart;;0xE1;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be2;CCS_StartSymbolMissed;;0xE2;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be3;CCS_EndWithoutStart;;0xE3;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be4;CCS_TooLarge;;0xE4;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be5;CCS_TooShort;;0xE5;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be6;CCS_WrongTfVersion;;0xE6;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be7;CCS_WrongSpacecraftId;;0xE7;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be8;CCS_NoValidFrameType;;0xE8;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be9;CCS_CrcFailed;;0xE9;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bea;CCS_VcNotFound;;0xEA;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2beb;CCS_ForwardingFailed;;0xEB;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bec;CCS_ContentTooLarge;;0xEC;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bed;CCS_ResidualData;;0xED;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bee;CCS_DataCorrupted;;0xEE;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bef;CCS_IllegalSegmentationFlag;;0xEF;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bd0;CCS_IllegalFlagCombination;;0xD0;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bd1;CCS_ShorterThanHeader;;0xD1;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bd2;CCS_TooShortBlockedPacket;;0xD2;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bd3;CCS_TooShortMapExtraction;;0xD3;../../fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2901;IEC_NoConfigurationTable;;0x01;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2902;IEC_NoCpuTable;;0x02;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2903;IEC_InvalidWorkspaceAddress;;0x03;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2904;IEC_TooLittleWorkspace;;0x04;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2905;IEC_WorkspaceAllocation;;0x05;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2906;IEC_InterruptStackTooSmall;;0x06;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2907;IEC_ThreadExitted;;0x07;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2908;IEC_InconsistentMpInformation;;0x08;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2909;IEC_InvalidNode;;0x09;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290a;IEC_NoMpci;;0x0a;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290b;IEC_BadPacket;;0x0b;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290c;IEC_OutOfPackets;;0x0c;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290d;IEC_OutOfGlobalObjects;;0x0d;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290e;IEC_OutOfProxies;;0x0e;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290f;IEC_InvalidGlobalId;;0x0f;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2910;IEC_BadStackHook;;0x10;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2911;IEC_BadAttributes;;0x11;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2912;IEC_ImplementationKeyCreateInconsistency;;0x12;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2913;IEC_ImplementationBlockingOperationCancel;;0x13;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2914;IEC_MutexObtainFromBadState;;0x14;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2915;IEC_UnlimitedAndMaximumIs0;;0x15;../../fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0xe01;HM_InvalidMode;;0x01;../../fsfw/modes/HasModesIF.h;HAS_MODES_IF -0xe02;HM_TransNotAllowed;;0x02;../../fsfw/modes/HasModesIF.h;HAS_MODES_IF -0xe03;HM_InTransition;;0x03;../../fsfw/modes/HasModesIF.h;HAS_MODES_IF -0xe04;HM_InvalidSubmode;;0x04;../../fsfw/modes/HasModesIF.h;HAS_MODES_IF -0x2d01;HPA_InvalidIdentifierId;;0x01;../../fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF -0x2d02;HPA_InvalidDomainId;;0x02;../../fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF -0x2d03;HPA_InvalidValue;;0x03;../../fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF -0x2d05;HPA_ReadOnly;;0x05;../../fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF -0x2c01;PAW_UnknownDatatype;;0x01;../../fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c02;PAW_DatatypeMissmatch;;0x02;../../fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c03;PAW_Readonly;;0x03;../../fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c04;PAW_TooBig;;0x04;../../fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c05;PAW_SourceNotSet;;0x05;../../fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c06;PAW_OutOfBounds;;0x06;../../fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c07;PAW_NotSet;;0x07;../../fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c08;PAW_ColumnOrRowsZero;;0x08;../../fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x3101;CF_ObjectHasNoFunctions;;1;../../fsfw/action/CommandsActionsIF.h;COMMANDS_ACTIONS_IF -0x3102;CF_AlreadyCommanding;;2;../../fsfw/action/CommandsActionsIF.h;COMMANDS_ACTIONS_IF -0x3201;HF_IsBusy;;1;../../fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF -0x3202;HF_InvalidParameters;;2;../../fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF -0x3203;HF_ExecutionFinished;;3;../../fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF -0x3204;HF_InvalidActionId;;4;../../fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF -0x201;OM_InsertionFailed;;1;../../fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF -0x202;OM_NotFound;;2;../../fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF -0x203;OM_ChildInitFailed;;3;../../fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF -0x204;OM_InternalErrReporterUninit;;4;../../fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF -0x2500;FDI_YourFault;;0;../../fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF -0x2501;FDI_MyFault;;1;../../fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF -0x2502;FDI_ConfirmLater;;2;../../fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF -0x2101;TMF_Busy;;1;../../fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2102;TMF_LastPacketFound;;2;../../fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2103;TMF_StopFetch;;3;../../fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2104;TMF_Timeout;;4;../../fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2105;TMF_TmChannelFull;;5;../../fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2106;TMF_NotStored;;6;../../fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2107;TMF_AllDeleted;;7;../../fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2108;TMF_InvalidData;;8;../../fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2109;TMF_NotReady;;9;../../fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2001;TMB_Busy;;1;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2002;TMB_Full;;2;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2003;TMB_Empty;;3;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2004;TMB_NullRequested;;4;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2005;TMB_TooLarge;;5;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2006;TMB_NotReady;;6;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2007;TMB_DumpError;;7;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2008;TMB_CrcError;;8;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2009;TMB_Timeout;;9;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200a;TMB_IdlePacketFound;;10;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200b;TMB_TelecommandFound;;11;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200c;TMB_NoPusATm;;12;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200d;TMB_TooSmall;;13;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200e;TMB_BlockNotFound;;14;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200f;TMB_InvalidRequest;;15;../../fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x1c01;TCD_PacketLost;;1;../../fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION -0x1c02;TCD_DestinationNotFound;;2;../../fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION -0x1c03;TCD_ServiceIdAlreadyExists;;3;../../fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION -0x1b00;TCC_IllegalApid;;0;../../fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b01;TCC_IncompletePacket;;1;../../fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b02;TCC_IncorrectChecksum;;2;../../fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b03;TCC_IllegalPacketType;;3;../../fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b04;TCC_IllegalPacketSubtype;;4;../../fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b05;TCC_IncorrectPrimaryHeader;;5;../../fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b06;TCC_IncorrectSecondaryHeader;;6;../../fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x4e1;RMP_CommandNoDescriptorsAvailable;;0xE1;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e2;RMP_CommandBufferFull;;0xE2;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e3;RMP_CommandChannelOutOfRange;;0xE3;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e6;RMP_CommandChannelDeactivated;;0xE6;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e7;RMP_CommandPortOutOfRange;;0xE7;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e8;RMP_CommandPortInUse;;0xE8;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e9;RMP_CommandNoChannel;;0xE9;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4ea;RMP_NoHwCrc;;0xEA;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d0;RMP_ReplyNoReply;;0xD0;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d1;RMP_ReplyNotSent;;0xD1;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d2;RMP_ReplyNotYetSent;;0xD2;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d3;RMP_ReplyMissmatch;;0xD3;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d4;RMP_ReplyTimeout;;0xD4;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4c0;RMP_ReplyInterfaceBusy;;0xC0;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4c1;RMP_ReplyTransmissionError;;0xC1;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4c2;RMP_ReplyInvalidData;;0xC2;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4c3;RMP_ReplyNotSupported;;0xC3;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f0;RMP_LinkDown;;0xF0;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f1;RMP_SpwCredit;;0xF1;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f2;RMP_SpwEscape;;0xF2;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f3;RMP_SpwDisconnect;;0xF3;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f4;RMP_SpwParity;;0xF4;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f5;RMP_SpwWriteSync;;0xF5;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f6;RMP_SpwInvalidAddress;;0xF6;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f7;RMP_SpwEarlyEop;;0xF7;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f8;RMP_SpwDma;;0xF8;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f9;RMP_SpwLinkError;;0xF9;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x400;RMP_ReplyOk;;0;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x401;RMP_ReplyGeneralErrorCode;;1;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x402;RMP_ReplyUnusedPacketTypeOrCommandCode;;2;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x403;RMP_ReplyInvalidKey;;3;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x404;RMP_ReplyInvalidDataCrc;;4;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x405;RMP_ReplyEarlyEop;;5;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x406;RMP_ReplyTooMuchData;;6;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x407;RMP_ReplyEep;;7;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x408;RMP_ReplyReserved;;8;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x409;RMP_ReplyVerifyBufferOverrun;;9;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x40a;RMP_ReplyCommandNotImplementedOrNotAuthorised;;10;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x40b;RMP_ReplyRmwDataLengthError;;11;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x40c;RMP_ReplyInvalidTargetLogicalAddress;;12;../../fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x2701;SM_DataTooLarge;;1;../../fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2702;SM_DataStorageFull;;2;../../fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2703;SM_IllegalStorageId;;3;../../fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2704;SM_DataDoesNotExist;;4;../../fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2705;SM_IllegalAddress;;5;../../fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2706;SM_PoolTooLarge;;6;../../fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x36a1;SGP4_InvalidEccentricity;;0xA1;../../fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a2;SGP4_InvalidMeanMotion;;0xA2;../../fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a3;SGP4_InvalidPerturbationElements;;0xA3;../../fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a4;SGP4_InvalidSemiLatusRectum;;0xA4;../../fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a5;SGP4_InvalidEpochElements;;0xA5;../../fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a6;SGP4_SatelliteHasDecayed;;0xA6;../../fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36b1;SGP4_TleTooOld;;0xB1;../../fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36b2;SGP4_TleNotInitialized;;0xB2;../../fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x2301;MT_TooDetailedRequest;;1;../../fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x2302;MT_TooGeneralRequest;;2;../../fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x2303;MT_NoMatch;;3;../../fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x2304;MT_Full;;4;../../fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x2305;MT_NewNodeCreated;;5;../../fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x3d01;DLEE_StreamTooShort;;0x01;../../fsfw/globalfunctions/DleEncoder.h;DLE_ENCODER -0x3d02;DLEE_DecodingError;;0x02;../../fsfw/globalfunctions/DleEncoder.h;DLE_ENCODER -0x2e01;ASC_TooLongForTargetType;;1;../../fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER -0x2e02;ASC_InvalidCharacters;;2;../../fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER -0x2e03;ASC_BufferTooSmall;;0x3;../../fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER -0xf01;CM_UnknownCommand;;1;../../fsfw/ipc/CommandMessageIF.h;COMMAND_MESSAGE -0x3801;MQI_Empty;;1;../../fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF -0x3802;MQI_Full; No space left for more messages;2;../../fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF -0x3803;MQI_NoReplyPartner; Returned if a reply method was called without partner;3;../../fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF -0x3804;MQI_DestinationInvalid; Returned if the target destination is invalid.;4;../../fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF -0x3701;MUX_NotEnoughResources;;1;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x3702;MUX_InsufficientMemory;;2;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x3703;MUX_NoPrivilege;;3;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x3704;MUX_WrongAttributeSetting;;4;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x3705;MUX_MutexAlreadyLocked;;5;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x3706;MUX_MutexNotFound;;6;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x3707;MUX_MutexMaxLocks;;7;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x3708;MUX_CurrThreadAlreadyOwnsMutex;;8;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x3709;MUX_CurrThreadDoesNotOwnMutex;;9;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x370a;MUX_MutexTimeout;;10;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x370b;MUX_MutexInvalidId;;11;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x370c;MUX_MutexDestroyedWhileWaiting;;12;../../fsfw/ipc/MutexIF.h;MUTEX_IF -0x3901;SPH_SemaphoreTimeout;;1;../../fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF -0x3902;SPH_SemaphoreNotOwned;;2;../../fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF -0x3903;SPH_SemaphoreInvalid;;3;../../fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF -0x2801;TC_InvalidTargetState;;1;../../fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF -0x28f1;TC_AboveOperationalLimit;;0xF1;../../fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF -0x28f2;TC_BelowOperationalLimit;;0xF2;../../fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF -0xc02;MS_InvalidEntry;;0x02;../../fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF -0xc03;MS_TooManyElements;;0x03;../../fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF -0xc04;MS_CantStoreEmpty;;0x04;../../fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF -0xd01;SS_SequenceAlreadyExists;;0x01;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd02;SS_TableAlreadyExists;;0x02;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd03;SS_TableDoesNotExist;;0x03;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd04;SS_TableOrSequenceLengthInvalid;;0x04;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd05;SS_SequenceDoesNotExist;;0x05;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd06;SS_TableContainsInvalidObjectId;;0x06;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd07;SS_FallbackSequenceDoesNotExist;;0x07;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd08;SS_NoTargetTable;;0x08;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd09;SS_SequenceOrTableTooLong;;0x09;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd0b;SS_IsFallbackSequence;;0x0B;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd0c;SS_AccessDenied;;0x0C;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd0e;SS_TableInUse;;0x0E;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xda1;SS_TargetTableNotReached;;0xA1;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xda2;SS_TableCheckFailed;;0xA2;../../fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xb01;SB_ChildNotFound;;0x01;../../fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0xb02;SB_ChildInfoUpdated;;0x02;../../fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0xb03;SB_ChildDoesntHaveModes;;0x03;../../fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0xb04;SB_CouldNotInsertChild;;0x04;../../fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0xb05;SB_TableContainsInvalidObjectId;;0x05;../../fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0x3c00;HKM_QueueOrDestinationInvalid;;0;../../fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c01;HKM_WrongHkPacketType;;1;../../fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c02;HKM_ReportingStatusUnchanged;;2;../../fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c03;HKM_PeriodicHelperInvalid;;3;../../fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c04;HKM_PoolobjectNotFound;;4;../../fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c05;HKM_DatasetNotFound;;5;../../fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3a00;LPIF_PoolEntryNotFound;;0x00;../../fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF -0x3a01;LPIF_PoolEntryTypeConflict;;0x01;../../fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF -0x3ba0;PVA_InvalidReadWriteMode;;0xA0;../../fsfw/datapool/PoolVariableIF.h;POOL_VARIABLE_IF -0x3ba1;PVA_InvalidPoolEntry;;0xA1;../../fsfw/datapool/PoolVariableIF.h;POOL_VARIABLE_IF -0x801;DPS_InvalidParameterDefinition;;1;../../fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x802;DPS_SetWasAlreadyRead;;2;../../fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x803;DPS_CommitingWithoutReading;;3;../../fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x804;DPS_DataSetUninitialised;;4;../../fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x805;DPS_DataSetFull;;5;../../fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x806;DPS_PoolVarNull;;6;../../fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x1000;TIM_UnsupportedTimeFormat;;0;../../fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1001;TIM_NotEnoughInformationForTargetFormat;;1;../../fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1002;TIM_LengthMismatch;;2;../../fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1003;TIM_InvalidTimeFormat;;3;../../fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1004;TIM_InvalidDayOfYear;;4;../../fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1005;TIM_TimeDoesNotFitFormat;;5;../../fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x3501;TSI_BadTimestamp;;1;../../fsfw/timemanager/TimeStamperIF.h;TIME_STAMPER_IF -0x1d01;PUS_ActivityStarted;;1;../../fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1d02;PUS_InvalidSubservice;;2;../../fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1d03;PUS_IllegalApplicationData;;3;../../fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1d04;PUS_SendTmFailed;;4;../../fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1d05;PUS_Timeout;;5;../../fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1f01;CSB_ExecutionComplete;;1;../../fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f02;CSB_NoStepMessage;;2;../../fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f03;CSB_ObjectBusy;;3;../../fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f04;CSB_Busy;;4;../../fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f05;CSB_InvalidTc;;5;../../fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f06;CSB_InvalidObject;;6;../../fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f07;CSB_InvalidReply;;7;../../fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1101;AL_Full;;0x01;../../fsfw/container/ArrayList.h;ARRAY_LIST -0x1801;FF_Full;;1;../../fsfw/container/FIFOBase.h;FIFO_CLASS -0x1802;FF_Empty;;2;../../fsfw/container/FIFOBase.h;FIFO_CLASS -0x1601;FMM_MapFull;;0x01;../../fsfw/container/FixedOrderedMultimap.h;FIXED_MULTIMAP -0x1602;FMM_KeyDoesNotExist;;0x02;../../fsfw/container/FixedOrderedMultimap.h;FIXED_MULTIMAP -0x1501;FM_KeyAlreadyExists;;0x01;../../fsfw/container/FixedMap.h;FIXED_MAP -0x1502;FM_MapFull;;0x02;../../fsfw/container/FixedMap.h;FIXED_MAP -0x1503;FM_KeyDoesNotExist;;0x03;../../fsfw/container/FixedMap.h;FIXED_MAP -0x2401;EV_ListenerNotFound;;1;../../fsfw/events/EventManagerIF.h;EVENT_MANAGER_IF -0x1701;HHI_ObjectNotHealthy;;1;../../fsfw/health/HasHealthIF.h;HAS_HEALTH_IF -0x1702;HHI_InvalidHealthState;;2;../../fsfw/health/HasHealthIF.h;HAS_HEALTH_IF -0x2f01;POS_InPowerTransition;;1;../../fsfw/power/PowerSwitcher.h;POWER_SWITCHER -0x2f02;POS_SwitchStateMismatch;;2;../../fsfw/power/PowerSwitcher.h;POWER_SWITCHER -0x501;PS_SwitchOn;;1;../../fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x500;PS_SwitchOff;;0;../../fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x502;PS_SwitchTimeout;;2;../../fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x503;PS_FuseOn;;3;../../fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x504;PS_FuseOff;;4;../../fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x1a01;TRC_NotEnoughSensors;;1;../../fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x1a02;TRC_LowestValueOol;;2;../../fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x1a03;TRC_HighestValueOol;;3;../../fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x1a04;TRC_BothValuesOol;;4;../../fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x1a05;TRC_DuplexOol;;5;../../fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x3001;LIM_Unchecked;;1;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3002;LIM_Invalid;;2;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3003;LIM_Unselected;;3;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3004;LIM_BelowLowLimit;;4;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3005;LIM_AboveHighLimit;;5;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3006;LIM_UnexpectedValue;;6;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3007;LIM_OutOfRange;;7;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30a0;LIM_FirstSample;;0xA0;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30e0;LIM_InvalidSize;;0xE0;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30e1;LIM_WrongType;;0xE1;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30e2;LIM_WrongPid;;0xE2;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30e3;LIM_WrongLimitId;;0xE3;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30ee;LIM_MonitorNotFound;;0xEE;../../fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x4000;FILS_GenericFileError;;0;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4001;FILS_IsBusy;;1;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4002;FILS_InvalidParameters;;2;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4005;FILS_FileDoesNotExist;;5;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4006;FILS_FileAlreadyExists;;6;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4007;FILS_FileLocked;;7;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x400a;FILS_DirectoryDoesNotExist;;10;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x400b;FILS_DirectoryAlreadyExists;;11;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x400c;FILS_DirectoryNotEmpty;;12;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x400f;FILS_SequencePacketMissingWrite;;15;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4010;FILS_SequencePacketMissingRead;;16;../../fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x601;PP_DoItMyself;;1;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x602;PP_PointsToVariable;;2;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x603;PP_PointsToMemory;;3;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x604;PP_ActivityCompleted;;4;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x605;PP_PointsToVectorUint8;;5;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x606;PP_PointsToVectorUint16;;6;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x607;PP_PointsToVectorUint32;;7;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x608;PP_PointsToVectorFloat;;8;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6a0;PP_DumpNotSupported;;0xA0;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e0;PP_InvalidSize;;0xE0;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e1;PP_InvalidAddress;;0xE1;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e2;PP_InvalidContent;;0xE2;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e3;PP_UnalignedAccess;;0xE3;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e4;PP_WriteProtected;;0xE4;../../fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x13e0;MH_UnknownCmd;;0xE0;../../fsfw/memory/MemoryHelper.h;MEMORY_HELPER -0x13e1;MH_InvalidAddress;;0xE1;../../fsfw/memory/MemoryHelper.h;MEMORY_HELPER -0x13e2;MH_InvalidSize;;0xE2;../../fsfw/memory/MemoryHelper.h;MEMORY_HELPER -0x13e3;MH_StateMismatch;;0xE3;../../fsfw/memory/MemoryHelper.h;MEMORY_HELPER -0x1201;AB_NeedSecondStep;;0x01;../../fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x1202;AB_NeedToReconfigure;;0x02;../../fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x1203;AB_ModeFallback;;0x03;../../fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x1204;AB_ChildNotCommandable;;0x04;../../fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x1205;AB_NeedToChangeHealth;;0x05;../../fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x12a1;AB_NotEnoughChildrenInCorrectState;;0xa1;../../fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x3a0;DHB_InvalidChannel;;0xA0;../../fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3b0;DHB_AperiodicReply;;0xB0;../../fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3b1;DHB_IgnoreReplyData;;0xB1;../../fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3b2;DHB_IgnoreFullPacket;;0xB2;../../fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3c0;DHB_NothingToSend;;0xC0;../../fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3c2;DHB_CommandMapError;;0xC2;../../fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3d0;DHB_NoSwitch;;0xD0;../../fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3e0;DHB_ChildTimeout;;0xE0;../../fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3e1;DHB_SwitchFailed;;0xE1;../../fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3301;DC_NoReplyReceived;;0x01;../../fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3302;DC_ProtocolError;;0x02;../../fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3303;DC_Nullpointer;;0x03;../../fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3304;DC_InvalidCookieType;;0x04;../../fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3305;DC_NotActive;;0x05;../../fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3306;DC_TooMuchData;;0x06;../../fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x26a0;DHI_NoCommandData;;0xA0;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a1;DHI_CommandNotSupported;;0xA1;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a2;DHI_CommandAlreadySent;;0xA2;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a3;DHI_CommandWasNotSent;;0xA3;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a4;DHI_CantSwitchAddress;;0xA4;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a5;DHI_WrongModeForCommand;;0xA5;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a6;DHI_Timeout;;0xA6;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a7;DHI_Busy;;0xA7;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a8;DHI_NoReplyExpected;;0xA8;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a9;DHI_NonOpTemperature;;0xA9;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26aa;DHI_CommandNotImplemented;;0xAA;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26b0;DHI_ChecksumError;;0xB0;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26b1;DHI_LengthMissmatch;;0xB1;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26b2;DHI_InvalidData;;0xB2;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26b3;DHI_ProtocolError;;0xB3;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26c0;DHI_DeviceDidNotExecute;;0xC0;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26c1;DHI_DeviceReportedError;;0xC1;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26c2;DHI_UnknownDeviceReply;;0xC2;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26c3;DHI_DeviceReplyInvalid;;0xC3;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26d0;DHI_InvalidCommandParameter;;0xD0;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26d1;DHI_InvalidNumberOrLengthOfParameters;;0xD1;../../fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x1401;SE_BufferTooShort;;1;../../fsfw/serialize/SerializeIF.h;SERIALIZE_IF -0x1402;SE_StreamTooShort;;2;../../fsfw/serialize/SerializeIF.h;SERIALIZE_IF -0x1403;SE_TooManyElements;;3;../../fsfw/serialize/SerializeIF.h;SERIALIZE_IF -0x4aa1;HEATER_CommandNotSupported;;0xA1;../../linux/devices/HeaterHandler.h;HEATER_HANDLER -0x4aa2;HEATER_InitFailed;;0xA2;../../linux/devices/HeaterHandler.h;HEATER_HANDLER -0x4aa3;HEATER_InvalidSwitchNr;;0xA3;../../linux/devices/HeaterHandler.h;HEATER_HANDLER -0x4aa4;HEATER_MainSwitchSetTimeout;;0xA4;../../linux/devices/HeaterHandler.h;HEATER_HANDLER -0x4aa5;HEATER_CommandAlreadyWaiting;;0xA5;../../linux/devices/HeaterHandler.h;HEATER_HANDLER -0x4ea0;SUSS_ErrorUnlockMutex;;0xA0;../../linux/devices/SusHandler.h;SUS_HANDLER -0x4ea1;SUSS_ErrorLockMutex;;0xA1;../../linux/devices/SusHandler.h;SUS_HANDLER -0x57a0;SADPL_CommandNotSupported;;0xA0;../../linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x57a1;SADPL_DeploymentAlreadyExecuting;;0xA1;../../linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x57a2;SADPL_MainSwitchTimeoutFailure;;0xA2;../../linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x57a3;SADPL_SwitchingDeplSa1Failed;;0xA3;../../linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x57a4;SADPL_SwitchingDeplSa2Failed;;0xA4;../../linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5d00;GOMS_PacketTooLong;;0;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5d01;GOMS_InvalidTableId;;1;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5d02;GOMS_InvalidAddress;;2;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5d03;GOMS_InvalidParamSize;;3;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5d04;GOMS_InvalidPayloadSize;;4;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5d05;GOMS_UnknownReplyId;;5;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x54a0;PLSV_CrcFailure;Space Packet received from PLOC supervisor has invalid CRC;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a1;PLSV_ReceivedAckFailure;Received ACK failure reply from PLOC supervisor;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a2;PLSV_ReceivedExeFailure;Received execution failure reply from PLOC supervisor;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a3;PLSV_InvalidApid;Received space packet with invalid APID from PLOC supervisor;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a4;PLSV_GetTimeFailure;Failed to read current system time;0xA4;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a5;PLSV_InvalidUartComIf;Invalid communication interface specified;0xA5;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x51b0;RWHA_SpiWriteFailure;;0xB0;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;0xB1;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;0xB2;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b3;RWHA_InvalidSubstitute;Can be used by the HDLC decoding mechanism to inform about an invalid substitution combination;0xB3;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b4;RWHA_MissingEndSign;HDLC decoding mechanism never receives the end sign 0x7E;0xB4;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b5;RWHA_NoReply;Reaction wheel only responds with empty frames.;0xB5;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a0;RWHA_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000; 1000] or [1000; 65000];0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a1;RWHA_InvalidRampTime;Action Message with invalid ramp time was received.;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a2;RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a3;RWHA_ExecutionFailed;Command execution failed;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a4;RWHA_CrcError;Reaction wheel reply has invalid crc;0xA4;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER +0x52b0;STRH_CrcFailure;Received reply with invalid CRC;0xB0;/home/rmueller/EIVE/eive-obsw/mission/devices/StarTrackerHandler.h;STR_HANDLER +0x52a0;STRH_TmReplyError;Result code of tm reply indicates an error;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/StarTrackerHandler.h;STR_HANDLER +0x50a0;IMTQ_InvalidCommandCode;;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a1;IMTQ_ParameterMissing;;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a2;IMTQ_ParameterInvalid;;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a3;IMTQ_CcUnavailable;;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a4;IMTQ_InternalProcessingError;;0xA4;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a5;IMTQ_RejectedWithoutReason;;0xA5;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a6;IMTQ_CmdErrUnknown;;0xA6;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a7;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;0xA7;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x4fa0;SYRLINKS_CrcFailure;;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa1;SYRLINKS_UartFraminOrParityErrorAck;;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa2;SYRLINKS_BadCharacterAck;;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa3;SYRLINKS_BadParameterValueAck;;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa4;SYRLINKS_BadEndOfFrameAck;;0xA4;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa5;SYRLINKS_UnknownCommandIdAck;;0xA5;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa6;SYRLINKS_BadCrcAck;;0xA6;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa7;SYRLINKS_ReplyWrongSize;;0xA7;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa8;SYRLINKS_MissingStartFrameCharacter;;0xA8;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x53a0;PLMP_CrcFailure;;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER +0x53a1;PLMP_ReceivedAckFailure;;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER +0x53a2;PLMP_ReceivedExeFailure;;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER +0x53a3;PLMP_InvalidApid;;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER +0x4100;HSPI_HalTimeoutRetval;;0;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/stm32h7/spi/spiDefinitions.h;HAL_SPI +0x4101;HSPI_HalBusyRetval;;1;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/stm32h7/spi/spiDefinitions.h;HAL_SPI +0x4102;HSPI_HalErrorRetval;;2;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/stm32h7/spi/spiDefinitions.h;HAL_SPI +0x4201;HURT_UartReadFailure;;1;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/uart/UartComIF.h;HAL_UART +0x4202;HURT_UartReadSizeMissmatch;;2;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/uart/UartComIF.h;HAL_UART +0x4203;HURT_UartRxBufferTooSmall;;3;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/uart/UartComIF.h;HAL_UART +0x4401;HGIO_UnknownGpioId;;1;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4402;HGIO_DriveGpioFailure;;2;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4403;HGIO_GpioTypeFailure;;3;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4404;HGIO_GpioInvalidInstance;;4;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x2b01;CCS_BcIsSetVrCommand;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2b02;CCS_BcIsUnlockCommand;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bb0;CCS_BcIllegalCommand;;0xB0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bb1;CCS_BoardReadingNotFinished;;0xB1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf0;CCS_NsPositiveW;;0xF0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf1;CCS_NsNegativeW;;0xF1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf2;CCS_NsLockout;;0xF2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf3;CCS_FarmInLockout;;0xF3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf4;CCS_FarmInWait;;0xF4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be0;CCS_WrongSymbol;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be1;CCS_DoubleStart;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be2;CCS_StartSymbolMissed;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be3;CCS_EndWithoutStart;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be4;CCS_TooLarge;;0xE4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be5;CCS_TooShort;;0xE5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be6;CCS_WrongTfVersion;;0xE6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be7;CCS_WrongSpacecraftId;;0xE7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be8;CCS_NoValidFrameType;;0xE8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be9;CCS_CrcFailed;;0xE9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bea;CCS_VcNotFound;;0xEA;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2beb;CCS_ForwardingFailed;;0xEB;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bec;CCS_ContentTooLarge;;0xEC;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bed;CCS_ResidualData;;0xED;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bee;CCS_DataCorrupted;;0xEE;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bef;CCS_IllegalSegmentationFlag;;0xEF;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bd0;CCS_IllegalFlagCombination;;0xD0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bd1;CCS_ShorterThanHeader;;0xD1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bd2;CCS_TooShortBlockedPacket;;0xD2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bd3;CCS_TooShortMapExtraction;;0xD3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2901;IEC_NoConfigurationTable;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2902;IEC_NoCpuTable;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2903;IEC_InvalidWorkspaceAddress;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2904;IEC_TooLittleWorkspace;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2905;IEC_WorkspaceAllocation;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2906;IEC_InterruptStackTooSmall;;0x06;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2907;IEC_ThreadExitted;;0x07;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2908;IEC_InconsistentMpInformation;;0x08;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2909;IEC_InvalidNode;;0x09;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290a;IEC_NoMpci;;0x0a;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290b;IEC_BadPacket;;0x0b;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290c;IEC_OutOfPackets;;0x0c;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290d;IEC_OutOfGlobalObjects;;0x0d;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290e;IEC_OutOfProxies;;0x0e;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290f;IEC_InvalidGlobalId;;0x0f;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2910;IEC_BadStackHook;;0x10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2911;IEC_BadAttributes;;0x11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2912;IEC_ImplementationKeyCreateInconsistency;;0x12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2913;IEC_ImplementationBlockingOperationCancel;;0x13;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2914;IEC_MutexObtainFromBadState;;0x14;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2915;IEC_UnlimitedAndMaximumIs0;;0x15;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0xe01;HM_InvalidMode;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF +0xe02;HM_TransNotAllowed;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF +0xe03;HM_InTransition;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF +0xe04;HM_InvalidSubmode;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF +0x2d01;HPA_InvalidIdentifierId;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF +0x2d02;HPA_InvalidDomainId;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF +0x2d03;HPA_InvalidValue;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF +0x2d05;HPA_ReadOnly;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF +0x2c01;PAW_UnknownDatatype;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c02;PAW_DatatypeMissmatch;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c03;PAW_Readonly;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c04;PAW_TooBig;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c05;PAW_SourceNotSet;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c06;PAW_OutOfBounds;;0x06;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c07;PAW_NotSet;;0x07;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c08;PAW_ColumnOrRowsZero;;0x08;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x3101;CF_ObjectHasNoFunctions;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/CommandsActionsIF.h;COMMANDS_ACTIONS_IF +0x3102;CF_AlreadyCommanding;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/CommandsActionsIF.h;COMMANDS_ACTIONS_IF +0x3201;HF_IsBusy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF +0x3202;HF_InvalidParameters;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF +0x3203;HF_ExecutionFinished;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF +0x3204;HF_InvalidActionId;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF +0x201;OM_InsertionFailed;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF +0x202;OM_NotFound;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF +0x203;OM_ChildInitFailed;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF +0x204;OM_InternalErrReporterUninit;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF +0x2500;FDI_YourFault;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF +0x2501;FDI_MyFault;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF +0x2502;FDI_ConfirmLater;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF +0x2101;TMF_Busy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2102;TMF_LastPacketFound;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2103;TMF_StopFetch;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2104;TMF_Timeout;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2105;TMF_TmChannelFull;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2106;TMF_NotStored;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2107;TMF_AllDeleted;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2108;TMF_InvalidData;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2109;TMF_NotReady;;9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2001;TMB_Busy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2002;TMB_Full;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2003;TMB_Empty;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2004;TMB_NullRequested;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2005;TMB_TooLarge;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2006;TMB_NotReady;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2007;TMB_DumpError;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2008;TMB_CrcError;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2009;TMB_Timeout;;9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200a;TMB_IdlePacketFound;;10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200b;TMB_TelecommandFound;;11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200c;TMB_NoPusATm;;12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200d;TMB_TooSmall;;13;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200e;TMB_BlockNotFound;;14;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200f;TMB_InvalidRequest;;15;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x1c01;TCD_PacketLost;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION +0x1c02;TCD_DestinationNotFound;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION +0x1c03;TCD_ServiceIdAlreadyExists;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION +0x1b00;TCC_IllegalApid;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b01;TCC_IncompletePacket;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b02;TCC_IncorrectChecksum;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b03;TCC_IllegalPacketType;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b04;TCC_IllegalPacketSubtype;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b05;TCC_IncorrectPrimaryHeader;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b06;TCC_IncorrectSecondaryHeader;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x4e1;RMP_CommandNoDescriptorsAvailable;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e2;RMP_CommandBufferFull;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e3;RMP_CommandChannelOutOfRange;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e6;RMP_CommandChannelDeactivated;;0xE6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e7;RMP_CommandPortOutOfRange;;0xE7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e8;RMP_CommandPortInUse;;0xE8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e9;RMP_CommandNoChannel;;0xE9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4ea;RMP_NoHwCrc;;0xEA;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d0;RMP_ReplyNoReply;;0xD0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d1;RMP_ReplyNotSent;;0xD1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d2;RMP_ReplyNotYetSent;;0xD2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d3;RMP_ReplyMissmatch;;0xD3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d4;RMP_ReplyTimeout;;0xD4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4c0;RMP_ReplyInterfaceBusy;;0xC0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4c1;RMP_ReplyTransmissionError;;0xC1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4c2;RMP_ReplyInvalidData;;0xC2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4c3;RMP_ReplyNotSupported;;0xC3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f0;RMP_LinkDown;;0xF0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f1;RMP_SpwCredit;;0xF1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f2;RMP_SpwEscape;;0xF2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f3;RMP_SpwDisconnect;;0xF3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f4;RMP_SpwParity;;0xF4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f5;RMP_SpwWriteSync;;0xF5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f6;RMP_SpwInvalidAddress;;0xF6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f7;RMP_SpwEarlyEop;;0xF7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f8;RMP_SpwDma;;0xF8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f9;RMP_SpwLinkError;;0xF9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x400;RMP_ReplyOk;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x401;RMP_ReplyGeneralErrorCode;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x402;RMP_ReplyUnusedPacketTypeOrCommandCode;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x403;RMP_ReplyInvalidKey;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x404;RMP_ReplyInvalidDataCrc;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x405;RMP_ReplyEarlyEop;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x406;RMP_ReplyTooMuchData;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x407;RMP_ReplyEep;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x408;RMP_ReplyReserved;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x409;RMP_ReplyVerifyBufferOverrun;;9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x40a;RMP_ReplyCommandNotImplementedOrNotAuthorised;;10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x40b;RMP_ReplyRmwDataLengthError;;11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x40c;RMP_ReplyInvalidTargetLogicalAddress;;12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x2701;SM_DataTooLarge;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2702;SM_DataStorageFull;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2703;SM_IllegalStorageId;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2704;SM_DataDoesNotExist;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2705;SM_IllegalAddress;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2706;SM_PoolTooLarge;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x36a1;SGP4_InvalidEccentricity;;0xA1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a2;SGP4_InvalidMeanMotion;;0xA2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a3;SGP4_InvalidPerturbationElements;;0xA3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a4;SGP4_InvalidSemiLatusRectum;;0xA4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a5;SGP4_InvalidEpochElements;;0xA5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a6;SGP4_SatelliteHasDecayed;;0xA6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36b1;SGP4_TleTooOld;;0xB1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36b2;SGP4_TleNotInitialized;;0xB2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x2301;MT_TooDetailedRequest;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x2302;MT_TooGeneralRequest;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x2303;MT_NoMatch;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x2304;MT_Full;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x2305;MT_NewNodeCreated;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x3d01;DLEE_StreamTooShort;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/DleEncoder.h;DLE_ENCODER +0x3d02;DLEE_DecodingError;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/DleEncoder.h;DLE_ENCODER +0x2e01;ASC_TooLongForTargetType;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER +0x2e02;ASC_InvalidCharacters;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER +0x2e03;ASC_BufferTooSmall;;0x3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER +0xf01;CM_UnknownCommand;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/CommandMessageIF.h;COMMAND_MESSAGE +0x3801;MQI_Empty;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF +0x3802;MQI_Full;No space left for more messages;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF +0x3803;MQI_NoReplyPartner;Returned if a reply method was called without partner;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF +0x3804;MQI_DestinationInvalid;Returned if the target destination is invalid.;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF +0x3701;MUX_NotEnoughResources;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3702;MUX_InsufficientMemory;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3703;MUX_NoPrivilege;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3704;MUX_WrongAttributeSetting;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3705;MUX_MutexAlreadyLocked;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3706;MUX_MutexNotFound;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3707;MUX_MutexMaxLocks;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3708;MUX_CurrThreadAlreadyOwnsMutex;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3709;MUX_CurrThreadDoesNotOwnMutex;;9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x370a;MUX_MutexTimeout;;10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x370b;MUX_MutexInvalidId;;11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x370c;MUX_MutexDestroyedWhileWaiting;;12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3901;SPH_SemaphoreTimeout;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF +0x3902;SPH_SemaphoreNotOwned;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF +0x3903;SPH_SemaphoreInvalid;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF +0x2801;TC_InvalidTargetState;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF +0x28f1;TC_AboveOperationalLimit;;0xF1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF +0x28f2;TC_BelowOperationalLimit;;0xF2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF +0xc02;MS_InvalidEntry;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF +0xc03;MS_TooManyElements;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF +0xc04;MS_CantStoreEmpty;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF +0xd01;SS_SequenceAlreadyExists;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd02;SS_TableAlreadyExists;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd03;SS_TableDoesNotExist;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd04;SS_TableOrSequenceLengthInvalid;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd05;SS_SequenceDoesNotExist;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd06;SS_TableContainsInvalidObjectId;;0x06;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd07;SS_FallbackSequenceDoesNotExist;;0x07;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd08;SS_NoTargetTable;;0x08;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd09;SS_SequenceOrTableTooLong;;0x09;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd0b;SS_IsFallbackSequence;;0x0B;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd0c;SS_AccessDenied;;0x0C;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd0e;SS_TableInUse;;0x0E;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xda1;SS_TargetTableNotReached;;0xA1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xda2;SS_TableCheckFailed;;0xA2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xb01;SB_ChildNotFound;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0xb02;SB_ChildInfoUpdated;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0xb03;SB_ChildDoesntHaveModes;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0xb04;SB_CouldNotInsertChild;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0xb05;SB_TableContainsInvalidObjectId;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0x3c00;HKM_QueueOrDestinationInvalid;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c01;HKM_WrongHkPacketType;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c02;HKM_ReportingStatusUnchanged;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c03;HKM_PeriodicHelperInvalid;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c04;HKM_PoolobjectNotFound;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c05;HKM_DatasetNotFound;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3a00;LPIF_PoolEntryNotFound;;0x00;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF +0x3a01;LPIF_PoolEntryTypeConflict;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF +0x3ba0;PVA_InvalidReadWriteMode;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/PoolVariableIF.h;POOL_VARIABLE_IF +0x3ba1;PVA_InvalidPoolEntry;;0xA1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/PoolVariableIF.h;POOL_VARIABLE_IF +0x801;DPS_InvalidParameterDefinition;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x802;DPS_SetWasAlreadyRead;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x803;DPS_CommitingWithoutReading;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x804;DPS_DataSetUninitialised;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x805;DPS_DataSetFull;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x806;DPS_PoolVarNull;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x1000;TIM_UnsupportedTimeFormat;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1001;TIM_NotEnoughInformationForTargetFormat;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1002;TIM_LengthMismatch;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1003;TIM_InvalidTimeFormat;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1004;TIM_InvalidDayOfYear;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1005;TIM_TimeDoesNotFitFormat;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x3501;TSI_BadTimestamp;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/TimeStamperIF.h;TIME_STAMPER_IF +0x1d01;PUS_ActivityStarted;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1d02;PUS_InvalidSubservice;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1d03;PUS_IllegalApplicationData;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1d04;PUS_SendTmFailed;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1d05;PUS_Timeout;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1f01;CSB_ExecutionComplete;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f02;CSB_NoStepMessage;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f03;CSB_ObjectBusy;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f04;CSB_Busy;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f05;CSB_InvalidTc;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f06;CSB_InvalidObject;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f07;CSB_InvalidReply;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1101;AL_Full;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/ArrayList.h;ARRAY_LIST +0x1801;FF_Full;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FIFOBase.h;FIFO_CLASS +0x1802;FF_Empty;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FIFOBase.h;FIFO_CLASS +0x1601;FMM_MapFull;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedOrderedMultimap.h;FIXED_MULTIMAP +0x1602;FMM_KeyDoesNotExist;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedOrderedMultimap.h;FIXED_MULTIMAP +0x1501;FM_KeyAlreadyExists;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedMap.h;FIXED_MAP +0x1502;FM_MapFull;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedMap.h;FIXED_MAP +0x1503;FM_KeyDoesNotExist;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedMap.h;FIXED_MAP +0x2401;EV_ListenerNotFound;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/events/EventManagerIF.h;EVENT_MANAGER_IF +0x1701;HHI_ObjectNotHealthy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h;HAS_HEALTH_IF +0x1702;HHI_InvalidHealthState;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h;HAS_HEALTH_IF +0x2f01;POS_InPowerTransition;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitcher.h;POWER_SWITCHER +0x2f02;POS_SwitchStateMismatch;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitcher.h;POWER_SWITCHER +0x501;PS_SwitchOn;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x500;PS_SwitchOff;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x502;PS_SwitchTimeout;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x503;PS_FuseOn;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x504;PS_FuseOff;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x1a01;TRC_NotEnoughSensors;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x1a02;TRC_LowestValueOol;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x1a03;TRC_HighestValueOol;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x1a04;TRC_BothValuesOol;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x1a05;TRC_DuplexOol;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x3001;LIM_Unchecked;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3002;LIM_Invalid;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3003;LIM_Unselected;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3004;LIM_BelowLowLimit;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3005;LIM_AboveHighLimit;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3006;LIM_UnexpectedValue;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3007;LIM_OutOfRange;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30a0;LIM_FirstSample;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30e0;LIM_InvalidSize;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30e1;LIM_WrongType;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30e2;LIM_WrongPid;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30e3;LIM_WrongLimitId;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30ee;LIM_MonitorNotFound;;0xEE;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x4000;FILS_GenericFileError;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4001;FILS_IsBusy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4002;FILS_InvalidParameters;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4005;FILS_FileDoesNotExist;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4006;FILS_FileAlreadyExists;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4007;FILS_FileLocked;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x400a;FILS_DirectoryDoesNotExist;;10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x400b;FILS_DirectoryAlreadyExists;;11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x400c;FILS_DirectoryNotEmpty;;12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x400f;FILS_SequencePacketMissingWrite;;15;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4010;FILS_SequencePacketMissingRead;;16;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x601;PP_DoItMyself;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x602;PP_PointsToVariable;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x603;PP_PointsToMemory;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x604;PP_ActivityCompleted;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x605;PP_PointsToVectorUint8;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x606;PP_PointsToVectorUint16;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x607;PP_PointsToVectorUint32;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x608;PP_PointsToVectorFloat;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6a0;PP_DumpNotSupported;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e0;PP_InvalidSize;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e1;PP_InvalidAddress;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e2;PP_InvalidContent;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e3;PP_UnalignedAccess;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e4;PP_WriteProtected;;0xE4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x13e0;MH_UnknownCmd;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER +0x13e1;MH_InvalidAddress;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER +0x13e2;MH_InvalidSize;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER +0x13e3;MH_StateMismatch;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER +0x1201;AB_NeedSecondStep;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x1202;AB_NeedToReconfigure;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x1203;AB_ModeFallback;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x1204;AB_ChildNotCommandable;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x1205;AB_NeedToChangeHealth;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x12a1;AB_NotEnoughChildrenInCorrectState;;0xa1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x3a0;DHB_InvalidChannel;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3b0;DHB_AperiodicReply;;0xB0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3b1;DHB_IgnoreReplyData;;0xB1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3b2;DHB_IgnoreFullPacket;;0xB2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3c0;DHB_NothingToSend;;0xC0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3c2;DHB_CommandMapError;;0xC2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3d0;DHB_NoSwitch;;0xD0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3e0;DHB_ChildTimeout;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3e1;DHB_SwitchFailed;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3301;DC_NoReplyReceived;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3302;DC_ProtocolError;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3303;DC_Nullpointer;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3304;DC_InvalidCookieType;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3305;DC_NotActive;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3306;DC_TooMuchData;;0x06;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x26a0;DHI_NoCommandData;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a1;DHI_CommandNotSupported;;0xA1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a2;DHI_CommandAlreadySent;;0xA2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a3;DHI_CommandWasNotSent;;0xA3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a4;DHI_CantSwitchAddress;;0xA4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a5;DHI_WrongModeForCommand;;0xA5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a6;DHI_Timeout;;0xA6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a7;DHI_Busy;;0xA7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a8;DHI_NoReplyExpected;;0xA8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a9;DHI_NonOpTemperature;;0xA9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26aa;DHI_CommandNotImplemented;;0xAA;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26b0;DHI_ChecksumError;;0xB0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26b1;DHI_LengthMissmatch;;0xB1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26b2;DHI_InvalidData;;0xB2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26b3;DHI_ProtocolError;;0xB3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26c0;DHI_DeviceDidNotExecute;;0xC0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26c1;DHI_DeviceReportedError;;0xC1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26c2;DHI_UnknownDeviceReply;;0xC2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26c3;DHI_DeviceReplyInvalid;;0xC3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26d0;DHI_InvalidCommandParameter;;0xD0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26d1;DHI_InvalidNumberOrLengthOfParameters;;0xD1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x1401;SE_BufferTooShort;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF +0x1402;SE_StreamTooShort;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF +0x1403;SE_TooManyElements;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF +0x5f00;SDMA_AlreadyOn;;0;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x5f01;SDMA_AlreadyMounted;;1;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x5f02;SDMA_AlreadyOff;;2;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x5f0a;SDMA_StatusFileNexists;;10;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x5f0b;SDMA_StatusFileFormatInvalid;;11;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x5f0c;SDMA_MountError;;12;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x5f0d;SDMA_UnmountError;;13;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x5f0e;SDMA_SystemCallError;;14;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x6000;SCBU_KeyNotFound;;0;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/scratchApi.h;SCRATCH_BUFFER +0x4ea1;HEATER_CommandNotSupported;;0xA1;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x4ea2;HEATER_InitFailed;;0xA2;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x4ea3;HEATER_InvalidSwitchNr;;0xA3;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x4ea4;HEATER_MainSwitchSetTimeout;;0xA4;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x4ea5;HEATER_CommandAlreadyWaiting;;0xA5;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x55a0;SUSS_ErrorUnlockMutex;;0xA0;/home/rmueller/EIVE/eive-obsw/linux/devices/SusHandler.h;SUS_HANDLER +0x55a1;SUSS_ErrorLockMutex;;0xA1;/home/rmueller/EIVE/eive-obsw/linux/devices/SusHandler.h;SUS_HANDLER +0x5ea0;SADPL_CommandNotSupported;;0xA0;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5ea1;SADPL_DeploymentAlreadyExecuting;;0xA1;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5ea2;SADPL_MainSwitchTimeoutFailure;;0xA2;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5ea3;SADPL_SwitchingDeplSa1Failed;;0xA3;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5ea4;SADPL_SwitchingDeplSa2Failed;;0xA4;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5e01;SADPL_UnknownGpioId;;1;/home/rmueller/EIVE/eive-obsw/linux/archive/gpio/LinuxLibgpioIF.h;SA_DEPL_HANDLER +0x5e02;SADPL_DriveGpioFailure;;2;/home/rmueller/EIVE/eive-obsw/linux/archive/gpio/LinuxLibgpioIF.h;SA_DEPL_HANDLER +0x5e03;SADPL_GpioTypeFailure;;3;/home/rmueller/EIVE/eive-obsw/linux/archive/gpio/LinuxLibgpioIF.h;SA_DEPL_HANDLER +0x5e04;SADPL_GpioInvalidInstance;;4;/home/rmueller/EIVE/eive-obsw/linux/archive/gpio/LinuxLibgpioIF.h;SA_DEPL_HANDLER +0x56a0;IPCI_PapbBusy;;0xA0;/home/rmueller/EIVE/eive-obsw/linux/obc/CCSDSIPCoreBridge.h;CCSDS_IP_CORE_BRIDGE diff --git a/generators/fsfwgen b/generators/fsfwgen index 8e805d24..16280cc1 160000 --- a/generators/fsfwgen +++ b/generators/fsfwgen @@ -1 +1 @@ -Subproject commit 8e805d24088707ad7bc49fda5f1dc5edfa1154b0 +Subproject commit 16280cc1df2ac4c5e872a761d2cf6276cf1ef0d3 diff --git a/generators/returnvalues/returnvalues_parser.py b/generators/returnvalues/returnvalues_parser.py index 772e0bf1..eadb035f 100644 --- a/generators/returnvalues/returnvalues_parser.py +++ b/generators/returnvalues/returnvalues_parser.py @@ -9,13 +9,15 @@ Returnvalue exporter. To use MySQLdb, run pip install mysqlclient or install in IDE. On Windows, Build Tools installation might be necessary. :data: 21.11.2019 """ +from fsfwgen.core import get_console_logger from fsfwgen.parserbase.file_list_parser import FileListParser from fsfwgen.returnvalues.returnvalues_parser import InterfaceParser, ReturnValueParser from fsfwgen.utility.sql_writer import SqlWriter -from fsfwgen.utility.file_management import move_file +from fsfwgen.utility.printer import PrettyPrinter -from definitions import BspType, DATABASE_NAME +from definitions import BspType, DATABASE_NAME, ROOT_DIR, OBSW_ROOT_DIR +LOGGER = get_console_logger() EXPORT_TO_FILE = True MOVE_CSV_FILE = True EXPORT_TO_SQL = True @@ -27,28 +29,28 @@ MAX_STRING_LENGTH = 32 BSP_SELECT = BspType.BSP_Q7S BSP_DIR_NAME = BSP_SELECT.value -CSV_RETVAL_FILENAME = f"{BSP_SELECT.value}_returnvalues.csv" -CSV_MOVE_DESTINATION = "../" +CSV_RETVAL_FILENAME = f'{BSP_SELECT.value}_returnvalues.csv' +CSV_MOVE_DESTINATION = f'{ROOT_DIR}' ADD_LINUX_FOLDER = False if BSP_SELECT == BspType.BSP_Q7S or BSP_SELECT == BspType.BSP_LINUX_BOARD: - FSFW_CONFIG_ROOT = f"../../linux/fsfwconfig" + FSFW_CONFIG_ROOT = f'{OBSW_ROOT_DIR}/linux/fsfwconfig' ADD_LINUX_FOLDER = True else: - FSFW_CONFIG_ROOT = f"../../{BSP_DIR_NAME}/fsfwconfig" -BSP_PATH = f"../../{BSP_DIR_NAME}" + FSFW_CONFIG_ROOT = f'{OBSW_ROOT_DIR}/{BSP_DIR_NAME}/fsfwconfig' +BSP_PATH = f"{OBSW_ROOT_DIR}/{BSP_DIR_NAME}" INTERFACE_DEFINITION_FILES = [ - "../../fsfw/returnvalues/FwClassIds.h", - "../../common/config/commonClassIds.h", - f"{FSFW_CONFIG_ROOT}/returnvalues/classIds.h" + f'{OBSW_ROOT_DIR}/fsfw/src/fsfw/returnvalues/FwClassIds.h', + f'{OBSW_ROOT_DIR}/common/config/commonClassIds.h', + f'{FSFW_CONFIG_ROOT}/returnvalues/classIds.h' ] -RETURNVALUE_DESTINATIONS = [ - "../../mission/", "../../fsfw/", f"{BSP_PATH}" +RETURNVALUE_SOURCES = [ + f'{OBSW_ROOT_DIR}/mission/', f'{OBSW_ROOT_DIR}/fsfw/', f'{BSP_PATH}' ] if ADD_LINUX_FOLDER: - RETURNVALUE_DESTINATIONS.append("../../linux") + RETURNVALUE_SOURCES.append(f'{OBSW_ROOT_DIR}/linux') SQL_DELETE_RETURNVALUES_CMD = """ DROP TABLE IF EXISTS Returnvalues @@ -71,42 +73,41 @@ VALUES(?,?,?,?,?) """ -def main(): - returnvalue_table = parse_returnvalues() - print("") +def parse_returnvalues(): + returnvalue_table = generate_returnvalue_table() if EXPORT_TO_FILE: ReturnValueParser.export_to_file(CSV_RETVAL_FILENAME, returnvalue_table, FILE_SEPARATOR) - if MOVE_CSV_FILE: - move_file(file_name=CSV_RETVAL_FILENAME, destination=CSV_MOVE_DESTINATION) + # if MOVE_CSV_FILE: + # move_file(file_name=CSV_RETVAL_FILENAME, destination=CSV_MOVE_DESTINATION) if EXPORT_TO_SQL: - print("ReturnvalueParser: Exporting to SQL") - sql_retval_exporter(returnvalue_table=returnvalue_table, db_file_dest=f"../{DATABASE_NAME}") + LOGGER.info('ReturnvalueParser: Exporting to SQL') + sql_retval_exporter(returnvalue_table, db_filename=f"{ROOT_DIR}/{DATABASE_NAME}") -def parse_returnvalues(): +def generate_returnvalue_table(): """ Core function to parse for the return values """ - interface_parser = InterfaceParser(file_list=INTERFACE_DEFINITION_FILES, print_table=PRINT_TABLES) + interface_parser = InterfaceParser( + file_list=INTERFACE_DEFINITION_FILES, print_table=PRINT_TABLES + ) interfaces = interface_parser.parse_files() - header_parser = FileListParser(RETURNVALUE_DESTINATIONS) + header_parser = FileListParser(RETURNVALUE_SOURCES) header_list = header_parser.parse_header_files(True, "Parsing header file list: ") - print("") returnvalue_parser = ReturnValueParser(interfaces, header_list, PRINT_TABLES) returnvalue_parser.set_moving_window_mode(moving_window_size=7) returnvalue_table = returnvalue_parser.parse_files(True) - print(f"ReturnvalueParser: Found {len(returnvalue_table)} returnvalues.") + LOGGER.info(f"ReturnvalueParser: Found {len(returnvalue_table)} returnvalues") return returnvalue_table -def sql_retval_exporter(returnvalue_table, db_file_dest: str): - sql_writer = SqlWriter(db_filename=db_file_dest) +def sql_retval_exporter(returnvalue_table, db_filename: str): + sql_writer = SqlWriter(db_filename=db_filename) sql_writer.open(SQL_CREATE_RETURNVALUES_CMD) for entry in returnvalue_table.items(): sql_writer.write_entries( - SQL_INSERT_RETURNVALUES_CMD, - (entry[0], entry[1][2], entry[1][4], entry[1][3], entry[1][1])) + SQL_INSERT_RETURNVALUES_CMD, (entry[0], + entry[1][2], + entry[1][4], + entry[1][3], + entry[1][1])) sql_writer.commit() sql_writer.close() - - -if __name__ == "__main__": - main() diff --git a/linux/devices/HeaterHandler.h b/linux/devices/HeaterHandler.h index 5734a2b6..ebb267f6 100644 --- a/linux/devices/HeaterHandler.h +++ b/linux/devices/HeaterHandler.h @@ -24,6 +24,13 @@ class HeaterHandler: public ExecutableObjectIF, public SystemObject, public HasActionsIF { public: + static const uint8_t INTERFACE_ID = CLASS_ID::HEATER_HANDLER; + + static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); + static const ReturnValue_t INIT_FAILED = MAKE_RETURN_CODE(0xA2); + static const ReturnValue_t INVALID_SWITCH_NR = MAKE_RETURN_CODE(0xA3); + static const ReturnValue_t MAIN_SWITCH_SET_TIMEOUT = MAKE_RETURN_CODE(0xA4); + static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5); /** Device command IDs */ static const DeviceCommandId_t SWITCH_HEATER = 0x0; @@ -52,14 +59,6 @@ public: private: - static const uint8_t INTERFACE_ID = CLASS_ID::HEATER_HANDLER; - - static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); - static const ReturnValue_t INIT_FAILED = MAKE_RETURN_CODE(0xA2); - static const ReturnValue_t INVALID_SWITCH_NR = MAKE_RETURN_CODE(0xA3); - static const ReturnValue_t MAIN_SWITCH_SET_TIMEOUT = MAKE_RETURN_CODE(0xA4); - static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5); - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HEATER_HANDLER; static const Event GPIO_PULL_HIGH_FAILED = MAKE_EVENT(0, severity::LOW); static const Event GPIO_PULL_LOW_FAILED = MAKE_EVENT(1, severity::LOW); diff --git a/linux/fsfwconfig/returnvalues/classIds.h b/linux/fsfwconfig/returnvalues/classIds.h index b98801e2..e7c2ae74 100644 --- a/linux/fsfwconfig/returnvalues/classIds.h +++ b/linux/fsfwconfig/returnvalues/classIds.h @@ -12,6 +12,7 @@ namespace CLASS_ID { enum { CLASS_ID_START = COMMON_CLASS_ID_END, + GOM_SPACE_HANDLER, //GOMS SA_DEPL_HANDLER, //SADPL SD_CARD_MANAGER, //SDMA SCRATCH_BUFFER, //SCBU diff --git a/mission/devices/GomspaceDeviceHandler.cpp b/mission/devices/GomspaceDeviceHandler.cpp index 44ede8b7..d83de9fe 100644 --- a/mission/devices/GomspaceDeviceHandler.cpp +++ b/mission/devices/GomspaceDeviceHandler.cpp @@ -5,7 +5,8 @@ GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t c CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16_t hkTableReplySize, LocalPoolDataSetBase* hkTableDataset) : DeviceHandlerBase(objectId, comIF, comCookie), maxConfigTableAddress(maxConfigTableAddress), - maxHkTableAddress(maxHkTableAddress), hkTableReplySize(hkTableReplySize), hkTableDataset(hkTableDataset) { + maxHkTableAddress(maxHkTableAddress), hkTableReplySize(hkTableReplySize), + hkTableDataset(hkTableDataset) { if (comCookie == NULL) { sif::error << "GomspaceDeviceHandler::GomspaceDeviceHandler: Invalid com cookie" << std::endl; @@ -28,157 +29,157 @@ void GomspaceDeviceHandler::doShutDown(){ } ReturnValue_t GomspaceDeviceHandler::buildNormalDeviceCommand( - DeviceCommandId_t * id) { - return HasReturnvaluesIF::RETURN_OK; + DeviceCommandId_t * id) { + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t GomspaceDeviceHandler::buildTransitionDeviceCommand( - DeviceCommandId_t * id){ - return HasReturnvaluesIF::RETURN_OK; + DeviceCommandId_t * id){ + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand( - DeviceCommandId_t deviceCommand, const uint8_t * commandData, - size_t commandDataLen) { - ReturnValue_t result; - switch(deviceCommand) { - case(GOMSPACE::PING): { - result = generatePingCommand(commandData, commandDataLen); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - break; - } - case(GOMSPACE::REBOOT): { - generateRebootCommand(); - break; - } - case(GOMSPACE::PARAM_SET):{ - result = generateSetParamCommand(commandData, commandDataLen); - if(result != HasReturnvaluesIF::RETURN_OK){ - return result; - } - break; - } - case(GOMSPACE::PARAM_GET):{ - result = generateGetParamCommand(commandData, commandDataLen); - if(result != HasReturnvaluesIF::RETURN_OK){ - return result; - } - break; - } - case(GOMSPACE::GNDWDT_RESET): { - result = generateResetWatchdogCmd(); - if(result != HasReturnvaluesIF::RETURN_OK){ - return result; - } - break; - } - case(GOMSPACE::REQUEST_HK_TABLE): { - result = generateRequestFullHkTableCmd(hkTableReplySize); - if(result != HasReturnvaluesIF::RETURN_OK){ + DeviceCommandId_t deviceCommand, const uint8_t * commandData, + size_t commandDataLen) { + ReturnValue_t result; + switch(deviceCommand) { + case(GOMSPACE::PING): { + result = generatePingCommand(commandData, commandDataLen); + if(result != HasReturnvaluesIF::RETURN_OK) { return result; } break; - } - default: - return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; - } - return HasReturnvaluesIF::RETURN_OK; + } + case(GOMSPACE::REBOOT): { + generateRebootCommand(); + break; + } + case(GOMSPACE::PARAM_SET):{ + result = generateSetParamCommand(commandData, commandDataLen); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + break; + } + case(GOMSPACE::PARAM_GET):{ + result = generateGetParamCommand(commandData, commandDataLen); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + break; + } + case(GOMSPACE::GNDWDT_RESET): { + result = generateResetWatchdogCmd(); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + break; + } + case(GOMSPACE::REQUEST_HK_TABLE): { + result = generateRequestFullHkTableCmd(hkTableReplySize); + if(result != HasReturnvaluesIF::RETURN_OK){ + return result; + } + break; + } + default: + return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; + } + return HasReturnvaluesIF::RETURN_OK; } void GomspaceDeviceHandler::fillCommandAndReplyMap(){ - this->insertInCommandAndReplyMap(GOMSPACE::PING, 3); - this->insertInCommandMap(GOMSPACE::REBOOT); - this->insertInCommandAndReplyMap(GOMSPACE::PARAM_SET, 3); - this->insertInCommandAndReplyMap(GOMSPACE::PARAM_GET, 3); - this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_HK_TABLE, 3); - this->insertInCommandMap(GOMSPACE::GNDWDT_RESET); + this->insertInCommandAndReplyMap(GOMSPACE::PING, 3); + this->insertInCommandMap(GOMSPACE::REBOOT); + this->insertInCommandAndReplyMap(GOMSPACE::PARAM_SET, 3); + this->insertInCommandAndReplyMap(GOMSPACE::PARAM_GET, 3); + this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_HK_TABLE, 3); + this->insertInCommandMap(GOMSPACE::GNDWDT_RESET); } ReturnValue_t GomspaceDeviceHandler::scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) { - switch(rememberCommandId) { - case(GOMSPACE::PING): - *foundId = GOMSPACE::PING; - *foundLen = PING_REPLY_SIZE; - rememberCommandId = GOMSPACE::NONE; - break; - case(GOMSPACE::PARAM_GET): { - *foundId = GOMSPACE::PARAM_GET; - *foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH; - rememberCommandId = GOMSPACE::NONE; - break; - } - case(GOMSPACE::PARAM_SET): { - *foundId = GOMSPACE::PARAM_SET; - *foundLen = rememberRequestedSize; - rememberCommandId = GOMSPACE::NONE; - break; - } - case(GOMSPACE::REQUEST_HK_TABLE): { - *foundId = GOMSPACE::REQUEST_HK_TABLE; - *foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH; - rememberCommandId = GOMSPACE::NONE; - break; - } - default: - return IGNORE_REPLY_DATA; - } + switch(rememberCommandId) { + case(GOMSPACE::PING): + *foundId = GOMSPACE::PING; + *foundLen = PING_REPLY_SIZE; + rememberCommandId = GOMSPACE::NONE; + break; + case(GOMSPACE::PARAM_GET): { + *foundId = GOMSPACE::PARAM_GET; + *foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH; + rememberCommandId = GOMSPACE::NONE; + break; + } + case(GOMSPACE::PARAM_SET): { + *foundId = GOMSPACE::PARAM_SET; + *foundLen = rememberRequestedSize; + rememberCommandId = GOMSPACE::NONE; + break; + } + case(GOMSPACE::REQUEST_HK_TABLE): { + *foundId = GOMSPACE::REQUEST_HK_TABLE; + *foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH; + rememberCommandId = GOMSPACE::NONE; + break; + } + default: + return IGNORE_REPLY_DATA; + } return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { - switch(id) { - case(GOMSPACE::PING): { - SerializeElement replyTime = *packet; - handleDeviceTM(&replyTime, id, true); - break; - } - case(GOMSPACE::PARAM_GET): { - // -2 to subtract address size from gomspace parameter reply packet - uint16_t payloadLength = (*(packet + 2) << 8 | *(packet + 3)) - 2; - if(payloadLength > sizeof(uint32_t)){ - sif::error << "GomspaceDeviceHandler: PARAM_GET: Invalid payload " - << "size in reply" << std::endl; - return INVALID_PAYLOAD_SIZE; - } - uint8_t tempPayloadBuffer[payloadLength]; - /* Extract information from received data */ - CspGetParamReply cspGetParamReply(tempPayloadBuffer, payloadLength); - size_t size = GOMSPACE::GS_HDR_LENGTH + payloadLength; - ReturnValue_t result = cspGetParamReply.deSerialize(&packet, &size, - SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "GomspaceDeviceHandler: Failed to deserialize get parameter" - << "reply" << std::endl; - return result; - } - uint8_t action = cspGetParamReply.getAction(); - uint8_t tableId = cspGetParamReply.getTableId(); - uint16_t address = cspGetParamReply.getAddress(); - /* Pack relevant information into a tm packet */ - ParamReply paramReply(action, tableId, address, payloadLength, - tempPayloadBuffer); - handleDeviceTM(¶mReply, id, true); - break; - } - case(GOMSPACE::PARAM_SET): { - /* When setting a parameter, the p60dock sends back the state of the - * operation */ - if(*packet != PARAM_SET_OK){ - return HasReturnvaluesIF::RETURN_FAILED; - } - break; - } - case(GOMSPACE::REQUEST_HK_TABLE): { - letChildHandleHkReply(id, packet); - break; - } - default: - break; - } + switch(id) { + case(GOMSPACE::PING): { + SerializeElement replyTime = *packet; + handleDeviceTM(&replyTime, id, true); + break; + } + case(GOMSPACE::PARAM_GET): { + // -2 to subtract address size from gomspace parameter reply packet + uint16_t payloadLength = (*(packet + 2) << 8 | *(packet + 3)) - 2; + if(payloadLength > sizeof(uint32_t)){ + sif::error << "GomspaceDeviceHandler: PARAM_GET: Invalid payload " + << "size in reply" << std::endl; + return INVALID_PAYLOAD_SIZE; + } + uint8_t tempPayloadBuffer[payloadLength]; + /* Extract information from received data */ + CspGetParamReply cspGetParamReply(tempPayloadBuffer, payloadLength); + size_t size = GOMSPACE::GS_HDR_LENGTH + payloadLength; + ReturnValue_t result = cspGetParamReply.deSerialize(&packet, &size, + SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "GomspaceDeviceHandler: Failed to deserialize get parameter" + << "reply" << std::endl; + return result; + } + uint8_t action = cspGetParamReply.getAction(); + uint8_t tableId = cspGetParamReply.getTableId(); + uint16_t address = cspGetParamReply.getAddress(); + /* Pack relevant information into a tm packet */ + ParamReply paramReply(action, tableId, address, payloadLength, + tempPayloadBuffer); + handleDeviceTM(¶mReply, id, true); + break; + } + case(GOMSPACE::PARAM_SET): { + /* When setting a parameter, the p60dock sends back the state of the + * operation */ + if(*packet != PARAM_SET_OK){ + return HasReturnvaluesIF::RETURN_FAILED; + } + break; + } + case(GOMSPACE::REQUEST_HK_TABLE): { + letChildHandleHkReply(id, packet); + break; + } + default: + break; + } return HasReturnvaluesIF::RETURN_OK; } @@ -187,173 +188,173 @@ void GomspaceDeviceHandler::setNormalDatapoolEntriesInvalid(){ } ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand( - const uint8_t * commandData, size_t commandDataLen) { - SetParamMessageUnpacker setParamMessageUnpacker; - ReturnValue_t result = setParamMessageUnpacker.deSerialize(&commandData, - &commandDataLen, SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter " - "message" << std::endl; - return result; - } - /* Get and check address */ - uint16_t address = setParamMessageUnpacker.getAddress(); - if(address > maxConfigTableAddress){ - sif::error << "GomspaceDeviceHandler: Invalid address for set parameter " - << "action" << std::endl; - return INVALID_ADDRESS; - } - uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM; - uint16_t seq = 0; - uint16_t total = 0; - /* CSP reply only contains the transaction state */ - uint16_t querySize = 1; - const uint8_t* parameterPtr = setParamMessageUnpacker.getParameter(); - uint8_t parameterSize = setParamMessageUnpacker.getParameterSize(); - uint16_t payloadlength = sizeof(address) + parameterSize; + const uint8_t * commandData, size_t commandDataLen) { + SetParamMessageUnpacker setParamMessageUnpacker; + ReturnValue_t result = setParamMessageUnpacker.deSerialize(&commandData, + &commandDataLen, SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter " + "message" << std::endl; + return result; + } + /* Get and check address */ + uint16_t address = setParamMessageUnpacker.getAddress(); + if(address > maxConfigTableAddress){ + sif::error << "GomspaceDeviceHandler: Invalid address for set parameter " + << "action" << std::endl; + return INVALID_ADDRESS; + } + uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM; + uint16_t seq = 0; + uint16_t total = 0; + /* CSP reply only contains the transaction state */ + uint16_t querySize = 1; + const uint8_t* parameterPtr = setParamMessageUnpacker.getParameter(); + uint8_t parameterSize = setParamMessageUnpacker.getParameterSize(); + uint16_t payloadlength = sizeof(address) + parameterSize; - /* Generate command for CspComIF */ - CspSetParamCommand setParamCmd(querySize, payloadlength, checksum, seq, - total, address, parameterPtr, parameterSize); - size_t cspPacketLen = 0; - uint8_t* buffer = cspPacket; - result = setParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket), - SerializeIF::Endianness::BIG); + /* Generate command for CspComIF */ + CspSetParamCommand setParamCmd(querySize, payloadlength, checksum, seq, + total, address, parameterPtr, parameterSize); + size_t cspPacketLen = 0; + uint8_t* buffer = cspPacket; + result = setParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket), + SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "GomspaceDeviceHandler: Failed to serialize command for " - << "CspComIF" << std::endl; - return result; - } - if(cspPacketLen > MAX_PACKET_LEN){ - sif::error << "GomspaceDeviceHandler: Invalid length of set parameter " - "command" << std::endl; - return PACKET_TOO_LONG; - } - rawPacket = cspPacket; - rawPacketLen = cspPacketLen; - rememberRequestedSize = querySize; - rememberCommandId = GOMSPACE::PARAM_SET; - return HasReturnvaluesIF::RETURN_OK; + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "GomspaceDeviceHandler: Failed to serialize command for " + << "CspComIF" << std::endl; + return result; + } + if(cspPacketLen > MAX_PACKET_LEN){ + sif::error << "GomspaceDeviceHandler: Invalid length of set parameter " + "command" << std::endl; + return PACKET_TOO_LONG; + } + rawPacket = cspPacket; + rawPacketLen = cspPacketLen; + rememberRequestedSize = querySize; + rememberCommandId = GOMSPACE::PARAM_SET; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand( - const uint8_t * commandData, size_t commandDataLen){ - ReturnValue_t result; - /* Unpack the received action message */ - GetParamMessageUnpacker getParamMessage; - result = getParamMessage.deSerialize(&commandData, &commandDataLen, - SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Failed to deserialize message to extract information " - "from get parameter message" << std::endl; - return result; - } - /* Get an check table id to read from */ - uint8_t tableId = getParamMessage.getTableId(); - if(tableId != CONFIG_TABLE_ID && tableId != HK_TABLE_ID){ - sif::error << "GomspaceDeviceHandler: Invalid table id in get parameter" - " message" << std::endl; - return INVALID_TABLE_ID; - } - /* Get and check address */ - uint16_t address = getParamMessage.getAddress(); - if(address > maxHkTableAddress && tableId == HK_TABLE_ID){ - sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from " - << "housekeeping table" << std::endl; - return INVALID_ADDRESS; - } - if(address > maxConfigTableAddress && tableId == CONFIG_TABLE_ID){ - sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from " - << "configuration table" << std::endl; - return INVALID_ADDRESS; - } - uint16_t length = sizeof(address); - uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM; - uint16_t seq = 0; - uint16_t total = 0; - uint8_t parameterSize = getParamMessage.getParameterSize(); - if(parameterSize > sizeof(uint32_t)) { - sif::error << "GomspaceDeviceHandler: GET_PARAM: Invalid parameter " - << "size" << std::endl; - return INVALID_PARAM_SIZE; - } - uint16_t querySize = parameterSize + GOMSPACE::GS_HDR_LENGTH; + const uint8_t * commandData, size_t commandDataLen){ + ReturnValue_t result; + /* Unpack the received action message */ + GetParamMessageUnpacker getParamMessage; + result = getParamMessage.deSerialize(&commandData, &commandDataLen, + SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Failed to deserialize message to extract information " + "from get parameter message" << std::endl; + return result; + } + /* Get an check table id to read from */ + uint8_t tableId = getParamMessage.getTableId(); + if(tableId != CONFIG_TABLE_ID && tableId != HK_TABLE_ID){ + sif::error << "GomspaceDeviceHandler: Invalid table id in get parameter" + " message" << std::endl; + return INVALID_TABLE_ID; + } + /* Get and check address */ + uint16_t address = getParamMessage.getAddress(); + if(address > maxHkTableAddress && tableId == HK_TABLE_ID){ + sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from " + << "housekeeping table" << std::endl; + return INVALID_ADDRESS; + } + if(address > maxConfigTableAddress && tableId == CONFIG_TABLE_ID){ + sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from " + << "configuration table" << std::endl; + return INVALID_ADDRESS; + } + uint16_t length = sizeof(address); + uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM; + uint16_t seq = 0; + uint16_t total = 0; + uint8_t parameterSize = getParamMessage.getParameterSize(); + if(parameterSize > sizeof(uint32_t)) { + sif::error << "GomspaceDeviceHandler: GET_PARAM: Invalid parameter " + << "size" << std::endl; + return INVALID_PARAM_SIZE; + } + uint16_t querySize = parameterSize + GOMSPACE::GS_HDR_LENGTH; - /* Generate the CSP command to send to the P60 Dock */ - CspGetParamCommand getParamCmd(querySize, tableId, length, - checksum, seq, total, address); - size_t cspPacketLen = 0; - uint8_t* buffer = cspPacket; - result = getParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket), - SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "GomspaceDeviceHandler: Failed to serialize command to " - << "get parameter" << std::endl; - } - if(cspPacketLen > MAX_PACKET_LEN){ - sif::error << "GomspaceDeviceHandler: Received invalid get parameter " - "command" << std::endl; - return PACKET_TOO_LONG; - } - rawPacket = cspPacket; - rawPacketLen = cspPacketLen; - rememberRequestedSize = querySize; - rememberCommandId = GOMSPACE::PARAM_GET; - return HasReturnvaluesIF::RETURN_OK; + /* Generate the CSP command to send to the P60 Dock */ + CspGetParamCommand getParamCmd(querySize, tableId, length, + checksum, seq, total, address); + size_t cspPacketLen = 0; + uint8_t* buffer = cspPacket; + result = getParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket), + SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "GomspaceDeviceHandler: Failed to serialize command to " + << "get parameter" << std::endl; + } + if(cspPacketLen > MAX_PACKET_LEN){ + sif::error << "GomspaceDeviceHandler: Received invalid get parameter " + "command" << std::endl; + return PACKET_TOO_LONG; + } + rawPacket = cspPacket; + rawPacketLen = cspPacketLen; + rememberRequestedSize = querySize; + rememberCommandId = GOMSPACE::PARAM_GET; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t GomspaceDeviceHandler::generatePingCommand( - const uint8_t * commandData, size_t commandDataLen) { - CspPingCommand cspPingCommand(commandData, commandDataLen); - size_t cspPacketLen = 0; - uint8_t* buffer = cspPacket; - ReturnValue_t result = cspPingCommand.serialize(&buffer, &cspPacketLen, - sizeof(cspPacket), - SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "GomspaceDeviceHandler: Failed to serialize ping command" - << std::endl; - return result; - } - if(cspPacketLen > MAX_PACKET_LEN){ - sif::error << "GomspaceDeviceHandler: Received invalid ping message" - << std::endl; - return PACKET_TOO_LONG; - } - rawPacket = cspPacket; - rawPacketLen = cspPacketLen; - rememberCommandId = GOMSPACE::PING; - return HasReturnvaluesIF::RETURN_OK; + const uint8_t * commandData, size_t commandDataLen) { + CspPingCommand cspPingCommand(commandData, commandDataLen); + size_t cspPacketLen = 0; + uint8_t* buffer = cspPacket; + ReturnValue_t result = cspPingCommand.serialize(&buffer, &cspPacketLen, + sizeof(cspPacket), + SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "GomspaceDeviceHandler: Failed to serialize ping command" + << std::endl; + return result; + } + if(cspPacketLen > MAX_PACKET_LEN){ + sif::error << "GomspaceDeviceHandler: Received invalid ping message" + << std::endl; + return PACKET_TOO_LONG; + } + rawPacket = cspPacket; + rawPacketLen = cspPacketLen; + rememberCommandId = GOMSPACE::PING; + return HasReturnvaluesIF::RETURN_OK; } void GomspaceDeviceHandler::generateRebootCommand(){ - uint8_t cspPort = GOMSPACE::REBOOT_PORT; - uint16_t querySize = 0; - *cspPacket = GOMSPACE::REBOOT_PORT; - *(cspPacket + 1) = querySize; - size_t cspPacketLen = sizeof(cspPort) + sizeof(cspPacketLen); - rawPacket = cspPacket; - rawPacketLen = cspPacketLen; + uint8_t cspPort = GOMSPACE::REBOOT_PORT; + uint16_t querySize = 0; + *cspPacket = GOMSPACE::REBOOT_PORT; + *(cspPacket + 1) = querySize; + size_t cspPacketLen = sizeof(cspPort) + sizeof(cspPacketLen); + rawPacket = cspPacket; + rawPacketLen = cspPacketLen; } ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd(){ - WatchdogResetCommand watchdogResetCommand; - size_t cspPacketLen = 0; - uint8_t* buffer = cspPacket; - ReturnValue_t result = watchdogResetCommand.serialize(&buffer, - &cspPacketLen, sizeof(cspPacket), SerializeIF::Endianness::BIG); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "GomspaceDeviceHandler: Failed to serialize watchdog reset " - << "command" << std::endl; - return result; - } - rawPacket = cspPacket; - rawPacketLen = cspPacketLen; - rememberRequestedSize = 0; // No bytes will be queried with the ground - // watchdog command. - rememberCommandId = GOMSPACE::GNDWDT_RESET; - return HasReturnvaluesIF::RETURN_OK; + WatchdogResetCommand watchdogResetCommand; + size_t cspPacketLen = 0; + uint8_t* buffer = cspPacket; + ReturnValue_t result = watchdogResetCommand.serialize(&buffer, + &cspPacketLen, sizeof(cspPacket), SerializeIF::Endianness::BIG); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "GomspaceDeviceHandler: Failed to serialize watchdog reset " + << "command" << std::endl; + return result; + } + rawPacket = cspPacket; + rawPacketLen = cspPacketLen; + rememberRequestedSize = 0; // No bytes will be queried with the ground + // watchdog command. + rememberCommandId = GOMSPACE::GNDWDT_RESET; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t GomspaceDeviceHandler::generateRequestFullHkTableCmd(uint16_t hkTableReplySize) { @@ -379,8 +380,8 @@ ReturnValue_t GomspaceDeviceHandler::generateRequestFullHkTableCmd(uint16_t hkTa } uint32_t GomspaceDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, - Mode_t modeTo) { - return 0; + Mode_t modeTo) { + return 0; } LocalPoolDataSetBase* GomspaceDeviceHandler::getDataSetHandle(sid_t sid) { diff --git a/mission/devices/GomspaceDeviceHandler.h b/mission/devices/GomspaceDeviceHandler.h index 8130d8f7..b73f3bb7 100644 --- a/mission/devices/GomspaceDeviceHandler.h +++ b/mission/devices/GomspaceDeviceHandler.h @@ -1,8 +1,9 @@ #ifndef MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_ #define MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_ -#include -#include +#include "fsfw/devicehandlers/DeviceHandlerBase.h" +#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" +#include "returnvalues/classIds.h" /** * @brief This is the device handler class for all gomspace devices. @@ -18,117 +19,119 @@ class GomspaceDeviceHandler: public DeviceHandlerBase { public: - static const ReturnValue_t PACKET_TOO_LONG = MAKE_RETURN_CODE(0xE0); - static const ReturnValue_t INVALID_TABLE_ID = MAKE_RETURN_CODE(0xE1); - static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0xE2); - static const ReturnValue_t INVALID_PARAM_SIZE = MAKE_RETURN_CODE(0xE3); - static const ReturnValue_t INVALID_PAYLOAD_SIZE = MAKE_RETURN_CODE(0xE4); - static const ReturnValue_t UNKNOWN_REPLY_ID = MAKE_RETURN_CODE(0xE5); + static constexpr uint8_t CLASS_ID = CLASS_ID::GOM_SPACE_HANDLER; + static const ReturnValue_t PACKET_TOO_LONG = HasReturnvaluesIF::makeReturnCode(CLASS_ID, 0); + static const ReturnValue_t INVALID_TABLE_ID = HasReturnvaluesIF::makeReturnCode(CLASS_ID, 1); + static const ReturnValue_t INVALID_ADDRESS = HasReturnvaluesIF::makeReturnCode(CLASS_ID, 2); + static const ReturnValue_t INVALID_PARAM_SIZE = HasReturnvaluesIF::makeReturnCode(CLASS_ID, 3); + static const ReturnValue_t INVALID_PAYLOAD_SIZE = + HasReturnvaluesIF::makeReturnCode(CLASS_ID, 4); + static const ReturnValue_t UNKNOWN_REPLY_ID = HasReturnvaluesIF::makeReturnCode(CLASS_ID, 5); - /** - * @brief Constructor - * - * @param maxConfigTableAddress The maximum memory address of the configu- - * ration table of a gomspace device. - * @param maxHkTableAddress The maximum memory address of a value in the - * houskeeping (telemetry) table of a gomspace - * device. - */ - GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF, - CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, - uint16_t hkTableReplySize, LocalPoolDataSetBase* hkTableDataset); - virtual ~GomspaceDeviceHandler(); + /** + * @brief Constructor + * + * @param maxConfigTableAddress The maximum memory address of the configu- + * ration table of a gomspace device. + * @param maxHkTableAddress The maximum memory address of a value in the + * houskeeping (telemetry) table of a gomspace + * device. + */ + GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF, + CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, + uint16_t hkTableReplySize, LocalPoolDataSetBase* hkTableDataset); + virtual ~GomspaceDeviceHandler(); - /** - * @brief This function can be used to set a gomspace device to normal mode immediately after - * object creation. - */ - void setModeNormal(); + /** + * @brief This function can be used to set a gomspace device to normal mode immediately after + * object creation. + */ + void setModeNormal(); protected: - static const uint8_t MAX_PACKET_LEN = 36; - static const uint8_t PARAM_SET_OK = 1; - static const uint8_t PING_REPLY_SIZE = 2; - static const uint8_t CONFIG_TABLE_ID = 1; - static const uint8_t HK_TABLE_ID = 4; + static const uint8_t MAX_PACKET_LEN = 36; + static const uint8_t PARAM_SET_OK = 1; + static const uint8_t PING_REPLY_SIZE = 2; + static const uint8_t CONFIG_TABLE_ID = 1; + static const uint8_t HK_TABLE_ID = 4; - uint8_t rememberRequestedSize = 0; - uint8_t rememberCommandId = GOMSPACE::NONE; - uint8_t cspPacket[MAX_PACKET_LEN]; + uint8_t rememberRequestedSize = 0; + uint8_t rememberCommandId = GOMSPACE::NONE; + uint8_t cspPacket[MAX_PACKET_LEN]; - uint16_t maxConfigTableAddress; - uint16_t maxHkTableAddress; + uint16_t maxConfigTableAddress; + uint16_t maxHkTableAddress; - /** The size of the reply following a full hk table request.*/ - uint16_t hkTableReplySize; + /** The size of the reply following a full hk table request.*/ + uint16_t hkTableReplySize; - LocalPoolDataSetBase* hkTableDataset = nullptr; + LocalPoolDataSetBase* hkTableDataset = nullptr; - void doStartUp() override; - void doShutDown() override; - virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) - override; - ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override; - void fillCommandAndReplyMap() override; - ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, - const uint8_t * commandData,size_t commandDataLen) override; - ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize, - DeviceCommandId_t *foundId, size_t *foundLen) override; - ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) override; - void setNormalDatapoolEntriesInvalid() override; - uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; - /** - * @brief The command to generate a request to receive the full housekeeping table is device - * specific. Thus the child has to build this command. - */ - virtual ReturnValue_t generateRequestFullHkTableCmd(uint16_t hkTableSize); + void doStartUp() override; + void doShutDown() override; + virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) + override; + ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override; + void fillCommandAndReplyMap() override; + ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t * commandData,size_t commandDataLen) override; + ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize, + DeviceCommandId_t *foundId, size_t *foundLen) override; + ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, + const uint8_t *packet) override; + void setNormalDatapoolEntriesInvalid() override; + uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; + /** + * @brief The command to generate a request to receive the full housekeeping table is device + * specific. Thus the child has to build this command. + */ + virtual ReturnValue_t generateRequestFullHkTableCmd(uint16_t hkTableSize); - /** - * @brief Because housekeeping tables are device specific the handling of the reply is - * given to the child class. - * @param id The id of the command which initiates the full table request. - * @param packet Pointer to the reply containing the hk table. - */ - virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) = 0; + /** + * @brief Because housekeeping tables are device specific the handling of the reply is + * given to the child class. + * @param id The id of the command which initiates the full table request. + * @param packet Pointer to the reply containing the hk table. + */ + virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) = 0; - virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; private: - /** - * @brief Function to generate the command to set a parameter. Command - * will be sent to the ComIF over the rawPacket buffer. - */ - ReturnValue_t generateSetParamCommand(const uint8_t * commandData, - size_t commandDataLen); + /** + * @brief Function to generate the command to set a parameter. Command + * will be sent to the ComIF over the rawPacket buffer. + */ + ReturnValue_t generateSetParamCommand(const uint8_t * commandData, + size_t commandDataLen); - /** - * @brief Function to generate the command to get a parameter from a - * gomspace device. Command will be sent to the ComIF over the - * rawPacket buffer. - */ - ReturnValue_t generateGetParamCommand(const uint8_t * commandData, - size_t commandDataLen); + /** + * @brief Function to generate the command to get a parameter from a + * gomspace device. Command will be sent to the ComIF over the + * rawPacket buffer. + */ + ReturnValue_t generateGetParamCommand(const uint8_t * commandData, + size_t commandDataLen); - /** - * @brief Function to generate the ping command for the ComIF. - */ - ReturnValue_t generatePingCommand(const uint8_t * commandData, - size_t commandDataLen); + /** + * @brief Function to generate the ping command for the ComIF. + */ + ReturnValue_t generatePingCommand(const uint8_t * commandData, + size_t commandDataLen); - /** - * @brief Function to generate the command to reboot a gomspace device - * via the ComIF. - */ - void generateRebootCommand(); + /** + * @brief Function to generate the command to reboot a gomspace device + * via the ComIF. + */ + void generateRebootCommand(); - /** - * @brief Function to generate the command to force a ground watchdog - * reset in a gomspace device. - */ - ReturnValue_t generateResetWatchdogCmd(); + /** + * @brief Function to generate the command to force a ground watchdog + * reset in a gomspace device. + */ + ReturnValue_t generateResetWatchdogCmd(); }; -- 2.43.0 From 9edd6fc3be78b016fe715cc1d301d242512134f3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 2 Aug 2021 13:02:50 +0200 Subject: [PATCH 079/116] supplying project string now --- generators/fsfwgen | 2 +- generators/fsfwgen.py | 2 +- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- tmtc | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/generators/fsfwgen b/generators/fsfwgen index 16280cc1..636670f7 160000 --- a/generators/fsfwgen +++ b/generators/fsfwgen @@ -1 +1 @@ -Subproject commit 16280cc1df2ac4c5e872a761d2cf6276cf1ef0d3 +Subproject commit 636670f7a0075533974ca0a668efa9b623a52749 diff --git a/generators/fsfwgen.py b/generators/fsfwgen.py index 61a71925..04c38d24 100755 --- a/generators/fsfwgen.py +++ b/generators/fsfwgen.py @@ -11,7 +11,7 @@ LOGGER = get_console_logger() def main(): - init_printout() + init_printout(project_string='EIVE') parser = return_generic_args_parser() args = parser.parse_args() if args.type == 'objects': diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 80bfdd60..7be16027 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 103 translations. - * Generated on: 2021-08-02 11:48:50 + * Generated on: 2021-08-02 13:00:48 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 80bfdd60..7be16027 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 103 translations. - * Generated on: 2021-08-02 11:48:50 + * Generated on: 2021-08-02 13:00:48 */ #include "translateObjects.h" diff --git a/tmtc b/tmtc index 8b7331c2..477743f6 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 8b7331c210e44bf2a60e5834f5f253514dae29fe +Subproject commit 477743f6264689327528beb5344c39247af6c49e -- 2.43.0 From aeecf33763926602997a6bea348f11428dbbaccb Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Mon, 2 Aug 2021 15:28:57 +0200 Subject: [PATCH 080/116] supervisor added debug TCs --- mission/devices/PlocSupervisorHandler.cpp | 82 +++++- mission/devices/PlocSupervisorHandler.h | 4 + .../PlocSupervisorDefinitions.h | 249 +++++++++++++++++- tmtc | 2 +- 4 files changed, 334 insertions(+), 3 deletions(-) diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 17ef9a5f..9c4dc73e 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -197,6 +197,49 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( case(PLOC_SPV::DUMP_MRAM): { result = prepareDumpMramCmd(commandData); break; + } + case(PLOC_SPV::PRINT_CPU_STATS): { + preparePrintCpuStatsCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::SET_DBG_VERBOSITY): { + prepareSetDbgVerbosityCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::SET_GPIO): { + prepareSetGpioCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::READ_GPIO): { + prepareReadGpioCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::RESTART_SUPERVISOR): { + prepareEmptyCmd(PLOC_SPV::APID_RESTART_SUPERVISOR); + result = RETURN_OK; + break; + } + case(PLOC_SPV::FACTORY_RESET_CLEAR_ALL): { + PLOC_SPV::FactoryReset packet(PLOC_SPV::FactoryReset::Op::CLEAR_ALL); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + result = RETURN_OK; + break; + } + case(PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR): { + PLOC_SPV::FactoryReset packet(PLOC_SPV::FactoryReset::Op::MIRROR_ENTRIES); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + result = RETURN_OK; + break; + } + case(PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR): { + PLOC_SPV::FactoryReset packet(PLOC_SPV::FactoryReset::Op::CIRCULAR_ENTRIES); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + result = RETURN_OK; + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -245,6 +288,14 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::SELECT_NVM); this->insertInCommandMap(PLOC_SPV::RUN_AUTO_EM_TESTS); this->insertInCommandMap(PLOC_SPV::WIPE_MRAM); + this->insertInCommandMap(PLOC_SPV::PRINT_CPU_STATS); + this->insertInCommandMap(PLOC_SPV::SET_DBG_VERBOSITY); + this->insertInCommandMap(PLOC_SPV::SET_GPIO); + this->insertInCommandMap(PLOC_SPV::READ_GPIO); + this->insertInCommandMap(PLOC_SPV::RESTART_SUPERVISOR); + this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_ALL); + this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR); + this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR); this->insertInCommandAndReplyMap(PLOC_SPV::DUMP_MRAM, 3); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); @@ -477,7 +528,9 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite case PLOC_SPV::SET_GPIO: case PLOC_SPV::READ_GPIO: case PLOC_SPV::RESTART_SUPERVISOR: - case PLOC_SPV::FACTORY_RESET: + case PLOC_SPV::FACTORY_RESET_CLEAR_ALL: + case PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR: + case PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR: case PLOC_SPV::REQUEST_LOGGING_DATA: enabledReplies = 2; break; @@ -1156,6 +1209,33 @@ ReturnValue_t PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandDa return RETURN_OK; } +void PlocSupervisorHandler::preparePrintCpuStatsCmd(const uint8_t* commandData) { + uint8_t en = *commandData; + PLOC_SPV::PrintCpuStats packet(en); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + +void PlocSupervisorHandler::prepareSetDbgVerbosityCmd(const uint8_t* commandData) { + uint8_t vb = *commandData; + PLOC_SPV::SetDbgVerbosity packet(vb); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + +void PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandData) { + uint8_t port = *commandData; + uint8_t pin = *(commandData + 1); + uint8_t val = *(commandData + 2); + PLOC_SPV::SetGpio packet(port, pin, val); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + +void PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandData) { + uint8_t port = *commandData; + uint8_t pin = *(commandData + 1); + PLOC_SPV::ReadGpio packet(port, pin); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { memcpy(commandBuffer, packetData, fullSize); rawPacket = commandBuffer; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index f316544f..edc46c85 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -243,6 +243,10 @@ private: ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData); ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData); ReturnValue_t prepareDumpMramCmd(const uint8_t* commandData); + void preparePrintCpuStatsCmd(const uint8_t* commandData); + void prepareSetDbgVerbosityCmd(const uint8_t* commandData); + void prepareSetGpioCmd(const uint8_t* commandData); + void prepareReadGpioCmd(const uint8_t* commandData); /** diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index dc7c792f..cc7be993 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -47,9 +47,11 @@ static const DeviceCommandId_t PRINT_CPU_STATS = 33; static const DeviceCommandId_t SET_GPIO = 34; static const DeviceCommandId_t READ_GPIO = 35; static const DeviceCommandId_t RESTART_SUPERVISOR = 36; -static const DeviceCommandId_t FACTORY_RESET = 37; +static const DeviceCommandId_t FACTORY_RESET_CLEAR_ALL = 37; static const DeviceCommandId_t REQUEST_LOGGING_DATA = 38; static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39; +static const DeviceCommandId_t FACTORY_RESET_CLEAR_MIRROR = 40; +static const DeviceCommandId_t FACTORY_RESET_CLEAR_CIRCULAR = 41; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; @@ -1095,6 +1097,89 @@ private: } }; +/** + * @brief This class packages the space packet causing the supervisor to print the CPU load to + * the debug output. + */ +class PrintCpuStats: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param en Print is enabled if en != 0 + */ + PrintCpuStats(uint8_t en) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_PRINT_CPU_STATS, + DEFAULT_SEQUENCE_COUNT), en(en) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 3; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t en = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&en, &data_field_ptr, &serializedSize, + sizeof(en), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet to set the print verbosity in the supervisor + * software. + */ +class SetDbgVerbosity: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param vb 0: None, 1: Error, 2: Warn, 3: Info + */ + SetDbgVerbosity(uint8_t vb) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_DBG_VERBOSITY, + DEFAULT_SEQUENCE_COUNT), vb(vb) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 3; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t vb = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&vb, &data_field_ptr, &serializedSize, + sizeof(vb), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + + /** * @brief This class packages the space packet to wipe or dump parts of the MRAM. */ @@ -1159,6 +1244,168 @@ private: } }; +/** + * @brief This class packages the space packet change the state of a GPIO. This command is only + * required for ground testing. + */ +class SetGpio: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param port + * @param pin + * @param val + */ + SetGpio(uint8_t port, uint8_t pin, uint8_t val) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_GPIO, + DEFAULT_SEQUENCE_COUNT), port(port), pin(pin), val(val) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 5; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t port = 0; + uint8_t pin = 0; + uint8_t val = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&port, &data_field_ptr, &serializedSize, + sizeof(port), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&pin, &data_field_ptr, &serializedSize, + sizeof(pin), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&val, &data_field_ptr, &serializedSize, + sizeof(val), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet causing the supervisor print the state of a GPIO + * to the debug output. + */ +class ReadGpio: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param port + * @param pin + */ + ReadGpio(uint8_t port, uint8_t pin) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_READ_GPIO, + DEFAULT_SEQUENCE_COUNT), port(port), pin(pin) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 4; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t port = 0; + uint8_t pin = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&port, &data_field_ptr, &serializedSize, + sizeof(port), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&pin, &data_field_ptr, &serializedSize, + sizeof(pin), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet to perform the factory reset. The op parameter is + * optional. + * + * @details: Without OP: All MRAM entries will be cleared. + * OP = 0x01: Only the mirror entries will be wiped. + * OP = 0x02: Only the circular entries will be wiped. + */ +class FactoryReset: public SpacePacket { +public: + + enum class Op { + CLEAR_ALL, + MIRROR_ENTRIES, + CIRCULAR_ENTRIES + }; + + /** + * @brief Constructor + * + * @param op + */ + FactoryReset(Op op) : + SpacePacket(0, true, APID_FACTORY_RESET, + DEFAULT_SEQUENCE_COUNT), op(op) { + initPacket(); + } + +private: + + uint16_t packetLen = 1; // only CRC in data field + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + uint8_t crcOffset = 0; + + Op op = Op::CLEAR_ALL; + + void initPacket() { + + uint8_t* data_field_ptr = this->localData.fields.buffer; + + switch(op) { + case Op::MIRROR_ENTRIES: + *data_field_ptr = 1; + packetLen = 2; + crcOffset = 1; + break; + case Op::CIRCULAR_ENTRIES: + *data_field_ptr = 2; + packetLen = 2; + crcOffset = 1; + break; + default: + break; + } + this->setPacketDataLength(packetLen); + size_t serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + packetLen - 1); + uint8_t* crcPos = this->localData.fields.buffer + crcOffset; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + /** * @brief This dataset stores the boot status report of the supervisor. */ diff --git a/tmtc b/tmtc index 6fcd52da..4aebf4c0 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6fcd52daa693040099cac85367863ad24e477f9a +Subproject commit 4aebf4c0d9a4a094e1a18753bca77d6a3b993378 -- 2.43.0 From ba51ca58f3947e31a71db9ec8716e87e6495c3e3 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Mon, 2 Aug 2021 15:58:17 +0200 Subject: [PATCH 081/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 4aebf4c0..477743f6 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 4aebf4c0d9a4a094e1a18753bca77d6a3b993378 +Subproject commit 477743f6264689327528beb5344c39247af6c49e -- 2.43.0 From f8f0032d1e50b41b43c8e1bae70f96e42e6d4def Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 3 Aug 2021 11:18:24 +0200 Subject: [PATCH 082/116] reboot feature finished --- bsp_q7s/core/CoreController.cpp | 30 ++++++++++++++++++++++++++++-- bsp_q7s/core/CoreController.h | 3 ++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 72171c65..69c234f5 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -159,8 +159,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ return actionListDirectoryIntoFile(actionId, commandedBy, data, size); } case(REBOOT_OBC): { - return HasReturnvaluesIF::RETURN_OK; - break; + return actionPerformReboot(data, size); } default: { return HasActionsIF::INVALID_ACTION_ID; @@ -457,6 +456,33 @@ void CoreController::initPrint() { #endif } +ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t size) { + if(size < 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + bool rebootSameBootCopy = data[0]; + if(rebootSameBootCopy) { + int result = std::system("xsc_boot_copy -r"); + if(result != 0) { + utility::handleSystemError(result, "CoreController::executeAction"); + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasActionsIF::EXECUTION_FINISHED; + } + if(size < 3) { + return HasActionsIF::INVALID_PARAMETERS; + } + // The second byte in data is the target chip, the third byte is the target copy + std::string cmdString = "xsc_boot_copy " + std::to_string(data[1]) + + std::to_string(data[2]); + int result = std::system(cmdString.c_str()); + if(result != 0) { + utility::handleSystemError(result, "CoreController::executeAction"); + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasActionsIF::EXECUTION_FINISHED; +} + void CoreController::performWatchdogControlOperation() { // Only perform each fifth iteration if(watchdogFifoFd != 0 and opDivider.checkAndIncrement()) { diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 92b22dd4..4a71e6e7 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -24,7 +24,7 @@ public: }; static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0; - static constexpr ActionId_t REBOOT_OBC = 1; + static constexpr ActionId_t REBOOT_OBC = 32; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; @@ -68,6 +68,7 @@ private: ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size); + ReturnValue_t actionPerformReboot(const uint8_t *data, size_t size); void initPrint(); -- 2.43.0 From 59c4ed74e030dfead7d639700230600939fa8cbc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 3 Aug 2021 11:21:28 +0200 Subject: [PATCH 083/116] minor bugfix --- bsp_q7s/core/CoreController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 69c234f5..847f6a52 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -473,7 +473,7 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si return HasActionsIF::INVALID_PARAMETERS; } // The second byte in data is the target chip, the third byte is the target copy - std::string cmdString = "xsc_boot_copy " + std::to_string(data[1]) + + std::string cmdString = "xsc_boot_copy " + std::to_string(data[1]) + " " + std::to_string(data[2]); int result = std::system(cmdString.c_str()); if(result != 0) { -- 2.43.0 From 3cc37865056d3527f876e9c808e9e2d836f24670 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 3 Aug 2021 15:29:45 +0200 Subject: [PATCH 084/116] TCP default now, bugfixes in CoreController --- bsp_q7s/boardtest/FileSystemTest.cpp | 5 +++++ bsp_q7s/boardtest/FileSystemTest.h | 5 ----- bsp_q7s/boardtest/Q7STestTask.cpp | 4 ++-- bsp_q7s/core/CoreController.cpp | 18 ++++++++++++++---- bsp_q7s/memory/FileSystemHandler.cpp | 4 ++-- common/config/commonConfig.h.in | 2 +- fsfw | 2 +- tmtc | 2 +- 8 files changed, 26 insertions(+), 16 deletions(-) diff --git a/bsp_q7s/boardtest/FileSystemTest.cpp b/bsp_q7s/boardtest/FileSystemTest.cpp index 1de5bb7a..92c4cf3d 100644 --- a/bsp_q7s/boardtest/FileSystemTest.cpp +++ b/bsp_q7s/boardtest/FileSystemTest.cpp @@ -4,6 +4,11 @@ #include #include +enum SdCard { + SDC0, + SDC1 +}; + FileSystemTest::FileSystemTest() { using namespace std; SdCard sdCard = SdCard::SDC0; diff --git a/bsp_q7s/boardtest/FileSystemTest.h b/bsp_q7s/boardtest/FileSystemTest.h index 907c86ca..256a0b36 100644 --- a/bsp_q7s/boardtest/FileSystemTest.h +++ b/bsp_q7s/boardtest/FileSystemTest.h @@ -1,11 +1,6 @@ #ifndef BSP_Q7S_BOARDTEST_FILESYSTEMTEST_H_ #define BSP_Q7S_BOARDTEST_FILESYSTEMTEST_H_ -enum SdCard { - SDC0, - SDC1 -}; - class FileSystemTest { public: FileSystemTest(); diff --git a/bsp_q7s/boardtest/Q7STestTask.cpp b/bsp_q7s/boardtest/Q7STestTask.cpp index 4e763641..f9439fc1 100644 --- a/bsp_q7s/boardtest/Q7STestTask.cpp +++ b/bsp_q7s/boardtest/Q7STestTask.cpp @@ -24,8 +24,8 @@ ReturnValue_t Q7STestTask::performOneShotAction() { //testScratchApi(); //testJsonLibDirect(); //testDummyParams(); - FsOpCodes opCode = FsOpCodes::ATTEMPT_DIR_REMOVAL_NON_EMPTY; - testFileSystemHandlerDirect(opCode); + //FsOpCodes opCode = FsOpCodes::ATTEMPT_DIR_REMOVAL_NON_EMPTY; + //testFileSystemHandlerDirect(opCode); return TestTask::performOneShotAction(); } diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 847f6a52..b1ca47d9 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -23,8 +23,8 @@ CoreController::Chip CoreController::currentChip = Chip::NO_CHIP; CoreController::Copy CoreController::currentCopy = Copy::NO_COPY; CoreController::CoreController(object_id_t objectId): - ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), - opDivider(5) { + ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), + opDivider(5) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; try { result = initWatchdogFifo(); @@ -49,7 +49,7 @@ CoreController::CoreController(object_id_t objectId): } ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { - return HasReturnvaluesIF::RETURN_OK; + return ExtendedControllerBase::handleCommandMessage(message); } void CoreController::performControlOperation() { @@ -74,7 +74,7 @@ ReturnValue_t CoreController::initialize() { "count failed" << std::endl; } - return HasReturnvaluesIF::RETURN_OK; + return ExtendedControllerBase::initialize(); } ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, @@ -462,6 +462,12 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si } bool rebootSameBootCopy = data[0]; if(rebootSameBootCopy) { +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "CoreController::actionPerformReboot: Rebooting on current image" << std::endl; +#endif + // Attempt graceful shutdown by unmounting and switching off SD cards + SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_0); + SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_1); int result = std::system("xsc_boot_copy -r"); if(result != 0) { utility::handleSystemError(result, "CoreController::executeAction"); @@ -472,6 +478,10 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si if(size < 3) { return HasActionsIF::INVALID_PARAMETERS; } +#if OBSW_VERBOSE_LEVEL >= 1 + sif::info << "CoreController::actionPerformReboot: Rebooting on " << + static_cast(data[1]) << " " << static_cast(data[2]) << std::endl; +#endif // The second byte in data is the target chip, the third byte is the target copy std::string cmdString = "xsc_boot_copy " + std::to_string(data[1]) + " " + std::to_string(data[2]); diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 159512a0..5a7895da 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -226,7 +226,7 @@ ReturnValue_t FileSystemHandler::removeDirectory(const char *repositoryPath, else { // Check error code. Most probably denied permissions because folder is not empty sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with " - "code" << err.value() << ": " << strerror(err.value()) << std::endl; + "code " << err.value() << ": " << strerror(err.value()) << std::endl; if(err.value() == ENOTEMPTY) { return DIRECTORY_NOT_EMPTY; } @@ -242,7 +242,7 @@ ReturnValue_t FileSystemHandler::removeDirectory(const char *repositoryPath, } else { sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with " - "code" << err.value() << ": " << strerror(err.value()) << std::endl; + "code " << err.value() << ": " << strerror(err.value()) << std::endl; // Check error code if(err.value() == ENOTEMPTY) { return DIRECTORY_NOT_EMPTY; diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index 2b0590c8..52b5dd45 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -5,6 +5,6 @@ // Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally // because UDP packets are not allowed in the VPN -#define OBSW_USE_TMTC_TCP_BRIDGE 0 +#define OBSW_USE_TMTC_TCP_BRIDGE 1 #endif /* COMMON_CONFIG_COMMONCONFIG_H_ */ diff --git a/fsfw b/fsfw index 0ff81294..296c587e 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 0ff81294e7e209bb4a26171b10d80fe522e65bcf +Subproject commit 296c587e3de10c579847e04af3176b3acaa2d701 diff --git a/tmtc b/tmtc index 477743f6..bc32472d 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 477743f6264689327528beb5344c39247af6c49e +Subproject commit bc32472d88a0d7a1566f53c05a1bc49f3c377985 -- 2.43.0 From 9790b395e6a50e515f0957d50f8a0d84ba9b3394 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 3 Aug 2021 15:58:01 +0200 Subject: [PATCH 085/116] include replacements --- bsp_linux_board/ObjectFactory.cpp | 16 ++++++++-------- bsp_q7s/core/ObjectFactory.cpp | 18 +++++++++--------- bsp_q7s/gpio/gpioCallbacks.cpp | 4 ++-- bsp_q7s/gpio/gpioCallbacks.h | 4 ++-- bsp_q7s/spi/Q7sSpiComIF.h | 2 +- bsp_q7s/spiCallbacks/rwSpiCallback.cpp | 4 ++-- bsp_q7s/spiCallbacks/rwSpiCallback.h | 4 ++-- common/config/spiConf.h | 2 +- fsfw | 2 +- linux/boardtest/LibgpiodTest.h | 4 ++-- linux/boardtest/SpiTestClass.cpp | 8 ++++---- linux/boardtest/SpiTestClass.h | 4 ++-- linux/devices/HeaterHandler.cpp | 2 +- linux/devices/HeaterHandler.h | 2 +- linux/devices/SolarArrayDeploymentHandler.cpp | 2 +- linux/devices/SolarArrayDeploymentHandler.h | 2 +- linux/devices/SusHandler.cpp | 2 +- linux/devices/SusHandler.h | 2 +- linux/fsfwconfig/devices/gpioIds.h | 2 +- linux/obc/CCSDSIPCoreBridge.h | 4 ++-- mission/devices/GyroADIS16507Handler.cpp | 8 ++++---- mission/devices/PlocSupervisorHandler.h | 2 +- mission/devices/RwHandler.h | 2 +- 23 files changed, 51 insertions(+), 51 deletions(-) diff --git a/bsp_linux_board/ObjectFactory.cpp b/bsp_linux_board/ObjectFactory.cpp index 0d3e8ce5..b24b633f 100644 --- a/bsp_linux_board/ObjectFactory.cpp +++ b/bsp_linux_board/ObjectFactory.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #include "ObjectFactory.h" @@ -31,12 +31,12 @@ #include "fsfw/osal/common/UdpTmTcBridge.h" #include "fsfw/osal/common/UdpTcPollingTask.h" -#include "fsfw/hal/devicehandlers/GyroL3GD20Handler.h" -#include "fsfw/hal/linux/gpio/LinuxLibgpioIF.h" -#include "fsfw/hal/linux/rpi/GpioRPi.h" -#include "fsfw/hal/common/gpio/GpioCookie.h" -#include "fsfw/hal/linux/spi/SpiCookie.h" -#include "fsfw/hal/linux/spi/SpiComIF.h" +#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" +#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" +#include "fsfw_hal/linux/rpi/GpioRPi.h" +#include "fsfw_hal/common/gpio/GpioCookie.h" +#include "fsfw_hal/linux/spi/SpiCookie.h" +#include "fsfw_hal/linux/spi/SpiComIF.h" void Factory::setStaticFrameworkObjectIds() { PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 53da02c5..a1ac3868 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -48,15 +48,15 @@ #include "mission/utility/TmFunnel.h" #include "linux/obc/CCSDSIPCoreBridge.h" -#include "fsfw/hal/linux/uart/UartComIF.h" -#include "fsfw/hal/linux/uart/UartCookie.h" -#include "fsfw/hal/devicehandlers/GyroL3GD20Handler.h" -#include "fsfw/hal/linux/i2c/I2cCookie.h" -#include "fsfw/hal/linux/i2c/I2cComIF.h" -#include "fsfw/hal/linux/spi/SpiCookie.h" -#include "fsfw/hal/linux/spi/SpiComIF.h" -#include "fsfw/hal/linux/gpio/LinuxLibgpioIF.h" -#include "fsfw/hal/common/gpio/GpioCookie.h" +#include "fsfw_hal/linux/uart/UartComIF.h" +#include "fsfw_hal/linux/uart/UartCookie.h" +#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" +#include "fsfw_hal/linux/i2c/I2cCookie.h" +#include "fsfw_hal/linux/i2c/I2cComIF.h" +#include "fsfw_hal/linux/spi/SpiCookie.h" +#include "fsfw_hal/linux/spi/SpiComIF.h" +#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" +#include "fsfw_hal/common/gpio/GpioCookie.h" #include "fsfw/datapoollocal/LocalDataPoolManager.h" #include "fsfw/tmtcservices/CommandingServiceBase.h" diff --git a/bsp_q7s/gpio/gpioCallbacks.cpp b/bsp_q7s/gpio/gpioCallbacks.cpp index 29e7f86d..5499517b 100644 --- a/bsp_q7s/gpio/gpioCallbacks.cpp +++ b/bsp_q7s/gpio/gpioCallbacks.cpp @@ -1,8 +1,8 @@ #include "gpioCallbacks.h" #include -#include -#include +#include +#include #include diff --git a/bsp_q7s/gpio/gpioCallbacks.h b/bsp_q7s/gpio/gpioCallbacks.h index 55e67895..eaf9a701 100644 --- a/bsp_q7s/gpio/gpioCallbacks.h +++ b/bsp_q7s/gpio/gpioCallbacks.h @@ -1,8 +1,8 @@ #ifndef LINUX_GPIO_GPIOCALLBACKS_H_ #define LINUX_GPIO_GPIOCALLBACKS_H_ -#include -#include +#include +#include namespace gpioCallbacks { diff --git a/bsp_q7s/spi/Q7sSpiComIF.h b/bsp_q7s/spi/Q7sSpiComIF.h index 4326bf8c..a10d63dd 100644 --- a/bsp_q7s/spi/Q7sSpiComIF.h +++ b/bsp_q7s/spi/Q7sSpiComIF.h @@ -1,7 +1,7 @@ #ifndef BSP_Q7S_SPI_Q7SSPICOMIF_H_ #define BSP_Q7S_SPI_Q7SSPICOMIF_H_ -#include +#include /** diff --git a/bsp_q7s/spiCallbacks/rwSpiCallback.cpp b/bsp_q7s/spiCallbacks/rwSpiCallback.cpp index 0f60288f..f05fbbdf 100644 --- a/bsp_q7s/spiCallbacks/rwSpiCallback.cpp +++ b/bsp_q7s/spiCallbacks/rwSpiCallback.cpp @@ -1,8 +1,8 @@ #include #include #include -#include -#include +#include +#include #include "devices/gpioIds.h" namespace rwSpiCallback { diff --git a/bsp_q7s/spiCallbacks/rwSpiCallback.h b/bsp_q7s/spiCallbacks/rwSpiCallback.h index fd7f1592..e5a79e64 100644 --- a/bsp_q7s/spiCallbacks/rwSpiCallback.h +++ b/bsp_q7s/spiCallbacks/rwSpiCallback.h @@ -2,8 +2,8 @@ #define BSP_Q7S_RW_SPI_CALLBACK_H_ #include -#include -#include +#include +#include namespace rwSpiCallback { diff --git a/common/config/spiConf.h b/common/config/spiConf.h index 05866555..47600eb3 100644 --- a/common/config/spiConf.h +++ b/common/config/spiConf.h @@ -2,7 +2,7 @@ #define COMMON_CONFIG_SPICONF_H_ #include -#include +#include /** * SPI configuration will be contained here to let the device handlers remain independent diff --git a/fsfw b/fsfw index 296c587e..bb88490c 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 296c587e3de10c579847e04af3176b3acaa2d701 +Subproject commit bb88490cc6cda5474d1d4913452eeb758da8cc25 diff --git a/linux/boardtest/LibgpiodTest.h b/linux/boardtest/LibgpiodTest.h index 38325622..a18c618e 100644 --- a/linux/boardtest/LibgpiodTest.h +++ b/linux/boardtest/LibgpiodTest.h @@ -2,8 +2,8 @@ #define TEST_TESTTASKS_LIBGPIODTEST_H_ #include "TestTask.h" -#include -#include +#include +#include #include /** diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index 6f634168..84750f66 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -8,10 +8,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h index 7982c601..dd112a0e 100644 --- a/linux/boardtest/SpiTestClass.h +++ b/linux/boardtest/SpiTestClass.h @@ -1,8 +1,8 @@ #ifndef LINUX_BOARDTEST_SPITESTCLASS_H_ #define LINUX_BOARDTEST_SPITESTCLASS_H_ -#include -#include +#include +#include #include #include diff --git a/linux/devices/HeaterHandler.cpp b/linux/devices/HeaterHandler.cpp index c821aa6c..60a60328 100644 --- a/linux/devices/HeaterHandler.cpp +++ b/linux/devices/HeaterHandler.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_) : diff --git a/linux/devices/HeaterHandler.h b/linux/devices/HeaterHandler.h index ebb267f6..b52e22d4 100644 --- a/linux/devices/HeaterHandler.h +++ b/linux/devices/HeaterHandler.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include /** diff --git a/linux/devices/SolarArrayDeploymentHandler.cpp b/linux/devices/SolarArrayDeploymentHandler.cpp index 05052c61..eea546f6 100644 --- a/linux/devices/SolarArrayDeploymentHandler.cpp +++ b/linux/devices/SolarArrayDeploymentHandler.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/linux/devices/SolarArrayDeploymentHandler.h b/linux/devices/SolarArrayDeploymentHandler.h index 97cb48c7..5e573128 100644 --- a/linux/devices/SolarArrayDeploymentHandler.h +++ b/linux/devices/SolarArrayDeploymentHandler.h @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include /** diff --git a/linux/devices/SusHandler.cpp b/linux/devices/SusHandler.cpp index bf06e031..c31160c4 100644 --- a/linux/devices/SusHandler.cpp +++ b/linux/devices/SusHandler.cpp @@ -2,7 +2,7 @@ #include "OBSWConfig.h" #include -#include +#include SusHandler::SusHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie, LinuxLibgpioIF* gpioComIF, gpioId_t chipSelectId) : diff --git a/linux/devices/SusHandler.h b/linux/devices/SusHandler.h index d40d9371..ca9a5c45 100644 --- a/linux/devices/SusHandler.h +++ b/linux/devices/SusHandler.h @@ -3,7 +3,7 @@ #include "devicedefinitions/SusDefinitions.h" #include -#include +#include /** * @brief This is the device handler class for the SUS sensor. The sensor is diff --git a/linux/fsfwconfig/devices/gpioIds.h b/linux/fsfwconfig/devices/gpioIds.h index 4b222b97..aad06629 100644 --- a/linux/fsfwconfig/devices/gpioIds.h +++ b/linux/fsfwconfig/devices/gpioIds.h @@ -1,7 +1,7 @@ #ifndef FSFWCONFIG_DEVICES_GPIOIDS_H_ #define FSFWCONFIG_DEVICES_GPIOIDS_H_ -#include +#include namespace gpioIds { enum gpioId_t { diff --git a/linux/obc/CCSDSIPCoreBridge.h b/linux/obc/CCSDSIPCoreBridge.h index f5127828..2ba68a3a 100644 --- a/linux/obc/CCSDSIPCoreBridge.h +++ b/linux/obc/CCSDSIPCoreBridge.h @@ -3,8 +3,8 @@ #include "OBSWConfig.h" #include -#include -#include +#include +#include #include diff --git a/mission/devices/GyroADIS16507Handler.cpp b/mission/devices/GyroADIS16507Handler.cpp index 7b45b8c5..ac49a89d 100644 --- a/mission/devices/GyroADIS16507Handler.cpp +++ b/mission/devices/GyroADIS16507Handler.cpp @@ -4,10 +4,10 @@ #include "GyroADIS16507Handler.h" #if OBSW_ADIS16507_LINUX_COM_IF == 1 -#include "fsfw/hal/linux/utility.h" -#include "fsfw/hal/linux/spi/SpiCookie.h" -#include "fsfw/hal/linux/spi/SpiComIF.h" -#include "fsfw/hal/linux/UnixFileGuard.h" +#include "fsfw_hal/linux/utility.h" +#include "fsfw_hal/linux/spi/SpiCookie.h" +#include "fsfw_hal/linux/spi/SpiComIF.h" +#include "fsfw_hal/linux/UnixFileGuard.h" #include #include #endif diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index d4ad811c..041989a3 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include /** * @brief This is the device handler for the supervisor of the PLOC which is programmed by diff --git a/mission/devices/RwHandler.h b/mission/devices/RwHandler.h index a0577043..cd753be0 100644 --- a/mission/devices/RwHandler.h +++ b/mission/devices/RwHandler.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include /** -- 2.43.0 From c431deede06be85333f85bc55ac40615e561c25a Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Wed, 4 Aug 2021 10:20:36 +0200 Subject: [PATCH 086/116] ploc udpdater wip --- bsp_q7s/memory/SdCardManager.h | 2 +- common/config/commonClassIds.h | 1 + common/config/commonObjects.h | 4 ++- linux/fsfwconfig/OBSWConfig.h.in | 1 + mission/devices/CMakeLists.txt | 1 + mission/devices/PlocUpdater.cpp | 59 ++++++++++++++++++++++++++++++++ mission/devices/PlocUpdater.h | 45 ++++++++++++++++++++++++ 7 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 mission/devices/PlocUpdater.cpp create mode 100644 mission/devices/PlocUpdater.h diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 7af57a67..d882aa8e 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -153,7 +153,7 @@ public: sd::SdCard prefSdCard = sd::SdCard::NONE); /** - * If sd::SdCard::NONE is passed as an argument, this funtion will get the currently + * If sd::SdCard::NONE is passed as an argument, this function will get the currently * preferred SD card from the scratch buffer. * @param prefSdCardPtr * @return diff --git a/common/config/commonClassIds.h b/common/config/commonClassIds.h index 6a27c286..d35b01dc 100644 --- a/common/config/commonClassIds.h +++ b/common/config/commonClassIds.h @@ -19,6 +19,7 @@ enum commonClassIds: uint8_t { PLOC_SUPERVISOR_HANDLER, //PLSV SUS_HANDLER, //SUSS CCSDS_IP_CORE_BRIDGE, //IPCI + PLOC_UPDATER, //PLUD COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 8c9a83b9..2a2a25b9 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -80,7 +80,9 @@ enum commonObjects: uint32_t { RW3 = 0x44120003, RW4 = 0x44120004, - START_TRACKER = 0x44130001 + START_TRACKER = 0x44130001, + + PLOC_UPDATER = 0x44300000 }; } diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 778a1611..6a83a874 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -76,6 +76,7 @@ namespace config { /* Add mission configuration flags here */ static constexpr uint32_t OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE = 50; +static constexpr uint32_t PLOC_UPDATER_QUEUE_SIZE = 50; #ifdef __cplusplus } diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 63b417e9..5b1f5533 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -18,6 +18,7 @@ target_sources(${TARGET_NAME} PUBLIC GyroADIS16507Handler.cpp RwHandler.cpp StarTrackerHandler.cpp + PlocUpdater.cpp ) diff --git a/mission/devices/PlocUpdater.cpp b/mission/devices/PlocUpdater.cpp new file mode 100644 index 00000000..d1a44783 --- /dev/null +++ b/mission/devices/PlocUpdater.cpp @@ -0,0 +1,59 @@ +#include + +PlocUpdater::PlocUpdater() : commandActionHelper(this) { + commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); +} + +PlocUpdater::~PlocUpdater() { +} + +ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) { + if (state == BUSY) { + return UPDATER_BUSY; + } + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + dumpData.address = 0; + receivedDataSize = 0; + timer.resetTimer(); + switch (actionId) { + case UPDATE_NVM0_A: + break; + case UPDATE_NVM0_B: + break; + case UPDATE_NVM1_A: + break; + case UPDATE_NVM1_B: + break; + dumpData.size = STRHandler::IMAGE_HEADER_SIZE; + dumpData.memoryId = STRHandler::ASC_MID_IMAGE; + result = commandActionHelper.commandAction(objects::STR_HANDLER, + STRHandler::ASC_SEND_IMAGE_TC_ID, &dumpData); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + state = EXPECT_IMAGE_SIZE; + break; + case FETCH_MIRU_DATA: + dumpData.memoryId = STRHandler::ASC_MID_MASSMEMORY; + dumpData.size = chunkSize; + result = commandActionHelper.commandAction(objects::STR_HANDLER, + STRHandler::ASC_MIRU_DUMP_DATA_TC_ID, &dumpData); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + state = MIRU_DATA_REQUESTED; + break; + default: + return INVALID_ACTION_ID; + } + return EXECUTION_FINISHED; +} + +MessageQueueId_t PlocUpdater::getCommandQueue() const { + return commandQueue.getId(); +} + +PlocUpdater::prepare +getCurrentMountPrefix + diff --git a/mission/devices/PlocUpdater.h b/mission/devices/PlocUpdater.h new file mode 100644 index 00000000..ae3edf1f --- /dev/null +++ b/mission/devices/PlocUpdater.h @@ -0,0 +1,45 @@ +#ifndef MISSION_DEVICES_PLOCUPDATER_H_ +#define MISSION_DEVICES_PLOCUPDATER_H_ + +#include "fsfw/action/CommandActionHelper.h" + +/** + * @brief An object of this class can be used to perform the software updates of the PLOC. The + * software update will be fetched via file system messages from the SD card handler, + * split into multiple space packets and sent to the PlocSupervisorHandler. + * + * @details The MPSoC has to boot memories (NVM0 and NVM1) where each stores two images (Partition A + * and Partition B) + * + * @author J. Meier + */ +class PlocUpdater : public SystemObject, + public HasActionsIF, + public ExecutableObjectIF { +public: + + static const ActionId_t UPDATE_NVM0_A = 0; + static const ActionId_t UPDATE_NVM0_B = 0; + static const ActionId_t UPDATE_NVM1_A = 0; + static const ActionId_t UPDATE_NVM1_B = 0; + + PlocUpdater(); + virtual ~PlocUpdater(); + + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size); + MessageQueueId_t getCommandQueue() const; + +private: + + static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_UPDATER; + + //! [EXPORT] : [COMMENT] Updater is already performing an update + static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0); + + static constexpr uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE; + + CommandActionHelper commandActionHelper; +}; + +#endif /* MISSION_DEVICES_PLOCUPDATER_H_ */ -- 2.43.0 From 3a88a435058b0a41db365f6e03f23884bfdb5cfc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 4 Aug 2021 13:18:09 +0200 Subject: [PATCH 087/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index bc32472d..a226bf65 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit bc32472d88a0d7a1566f53c05a1bc49f3c377985 +Subproject commit a226bf659eeadd3ad300b249d2659043317e2245 -- 2.43.0 From 2700d4d28c1641431c0ad966ab2924aa6cfc14de Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Wed, 4 Aug 2021 13:20:28 +0200 Subject: [PATCH 088/116] ploc updater wip --- fsfw | 2 +- mission/devices/PlocUpdater.cpp | 47 +++++++++++++++------------------ mission/devices/PlocUpdater.h | 11 ++++++-- tmtc | 2 +- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/fsfw b/fsfw index 0ff81294..296c587e 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 0ff81294e7e209bb4a26171b10d80fe522e65bcf +Subproject commit 296c587e3de10c579847e04af3176b3acaa2d701 diff --git a/mission/devices/PlocUpdater.cpp b/mission/devices/PlocUpdater.cpp index d1a44783..c7310298 100644 --- a/mission/devices/PlocUpdater.cpp +++ b/mission/devices/PlocUpdater.cpp @@ -8,52 +8,47 @@ PlocUpdater::~PlocUpdater() { } ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) { + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { + ReturnValue_t result = RETURN_FAILED; + if (state == BUSY) { - return UPDATER_BUSY; + return IS_BUSY; } - ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; - dumpData.address = 0; - receivedDataSize = 0; - timer.resetTimer(); + + if (size > MAX_PLOC_UPDATE_PATH) { + return PATH_TOO_LONG; + } + switch (actionId) { case UPDATE_NVM0_A: + result = prepareNvm0AUpdate(std::string(data, size)); break; case UPDATE_NVM0_B: + result = prepareNvm0BUpdate(); break; case UPDATE_NVM1_A: + result = prepareNvm1AUpdate(); break; case UPDATE_NVM1_B: - break; - dumpData.size = STRHandler::IMAGE_HEADER_SIZE; - dumpData.memoryId = STRHandler::ASC_MID_IMAGE; - result = commandActionHelper.commandAction(objects::STR_HANDLER, - STRHandler::ASC_SEND_IMAGE_TC_ID, &dumpData); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - state = EXPECT_IMAGE_SIZE; - break; - case FETCH_MIRU_DATA: - dumpData.memoryId = STRHandler::ASC_MID_MASSMEMORY; - dumpData.size = chunkSize; - result = commandActionHelper.commandAction(objects::STR_HANDLER, - STRHandler::ASC_MIRU_DUMP_DATA_TC_ID, &dumpData); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } - state = MIRU_DATA_REQUESTED; + result = prepareNvm1BUpdate(); break; default: return INVALID_ACTION_ID; } - return EXECUTION_FINISHED; + return result; } MessageQueueId_t PlocUpdater::getCommandQueue() const { return commandQueue.getId(); } +ReturnValue_t PlocUpdater::checkPath(size_t size) { + if (size > MAX_PLOC_UPDATE_PATH) { + return PATH_TOO_LONG; + } + return RETURN_OK; +} + PlocUpdater::prepare getCurrentMountPrefix diff --git a/mission/devices/PlocUpdater.h b/mission/devices/PlocUpdater.h index ae3edf1f..dd37898e 100644 --- a/mission/devices/PlocUpdater.h +++ b/mission/devices/PlocUpdater.h @@ -2,6 +2,7 @@ #define MISSION_DEVICES_PLOCUPDATER_H_ #include "fsfw/action/CommandActionHelper.h" +#include "fsfw/returnvalues/HasReturnValuesIF.h" /** * @brief An object of this class can be used to perform the software updates of the PLOC. The @@ -15,7 +16,8 @@ */ class PlocUpdater : public SystemObject, public HasActionsIF, - public ExecutableObjectIF { + public ExecutableObjectIF, + public HasReturnvaluesIF { public: static const ActionId_t UPDATE_NVM0_A = 0; @@ -36,10 +38,15 @@ private: //! [EXPORT] : [COMMENT] Updater is already performing an update static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0); + //! [EXPORT] : [COMMENT] Received update command with invalid path string (too long). + static const ReturnValue_t PATH_TOO_LONG = MAKE_RETURN_CODE(0xA0); - static constexpr uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE; + static const uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE; + static const size_t MAX_PLOC_UPDATE_PATH = 20; CommandActionHelper commandActionHelper; + + ReturnValue_t checkPath(size_t size); }; #endif /* MISSION_DEVICES_PLOCUPDATER_H_ */ diff --git a/tmtc b/tmtc index 477743f6..4aebf4c0 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 477743f6264689327528beb5344c39247af6c49e +Subproject commit 4aebf4c0d9a4a094e1a18753bca77d6a3b993378 -- 2.43.0 From 1cfb9250fa32e878b4f4419a745c00fb8d866486 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 10:14:17 +0200 Subject: [PATCH 089/116] SDC manager non-blocking mode --- bsp_q7s/core/CoreController.cpp | 20 +++-- bsp_q7s/memory/SdCardManager.cpp | 136 ++++++++++++++++++++++++++----- bsp_q7s/memory/SdCardManager.h | 50 +++++++++++- fsfw | 2 +- tmtc | 2 +- 5 files changed, 180 insertions(+), 30 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index b1ca47d9..e49f0007 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -4,6 +4,7 @@ #include "watchdogConf.h" #include "fsfw/FSFWVersion.h" +#include "fsfw/timemanager/Stopwatch.h" #include "fsfw/serviceinterface/ServiceInterface.h" #if OBSW_USE_TMTC_TCP_BRIDGE == 0 #include "fsfw/osal/common/UdpTmTcBridge.h" @@ -32,15 +33,11 @@ CoreController::CoreController(object_id_t objectId): sif::warning << "CoreController::CoreController: Watchdog FIFO init failed" << std::endl; } - result = initSdCard(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; - } + result = initBootCopy(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::CoreController: Boot copy init" << std::endl; } - } catch(const std::filesystem::filesystem_error& e) { sif::error << "CoreController::CoreController: Failed with exception " << @@ -91,6 +88,7 @@ ReturnValue_t CoreController::initSdCard() { if(sdcMan == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } + // Create update status file ReturnValue_t result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -168,7 +166,17 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ } ReturnValue_t CoreController::initializeAfterTaskCreation() { - ReturnValue_t result = initVersionFile(); + + // TODO: Do this here because this can take a longer time. Later, use non-blocking mode + // to start doing stuff in ctor and initialize function. + // This operation can take 1-2 seconds on reboot, and around 50-100ms if the SD + // card is already on. + ReturnValue_t result = initSdCard(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; + } + + result = initVersionFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; } diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 3dfa0b10..4e9ce6c8 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -6,13 +6,17 @@ #include "fsfw/ipc/MutexFactory.h" #include "fsfw/serviceinterface/ServiceInterface.h" +#include + #include #include #include +#include SdCardManager* SdCardManager::factoryInstance = nullptr; SdCardManager::SdCardManager() { + waiter.events = POLLIN; } SdCardManager::~SdCardManager() { @@ -128,6 +132,9 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { using namespace std; string sdstring = ""; string statestring = ""; + if(currentOp != Operations::IDLE) { + return OP_ONGOING; + } if(sdCard == sd::SdCard::SLOT_0) { sdstring = "0"; } @@ -135,20 +142,16 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { sdstring = "1"; } if(on) { + currentOp = Operations::SWITCHING_ON; statestring = "on"; } else { + currentOp = Operations::SWITCHING_OFF; statestring = "off"; } ostringstream command; command << "q7hw sd set " << sdstring << " " << statestring; - int result = system(command.str().c_str()); - if(result == 0) { - return HasReturnvaluesIF::RETURN_OK; - } - sif::warning << "SdCardManager::setSdCardState: system call failed with code " << - result << std::endl; - return SYSTEM_CALL_ERROR; + return handleCommand(command.str(), "SdCardManager::setSdCardState"); } ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { @@ -174,6 +177,9 @@ ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { using namespace std; + if(currentOp != Operations::IDLE) { + return OP_ONGOING; + } if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::mountSdCard: API does not allow sd::SdStatus::BOTH" << std::endl; @@ -196,12 +202,7 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { } string sdMountCommand = "mount " + mountDev + " " + mountPoint; - int result = system(sdMountCommand.c_str()); - if (result != 0) { - utility::handleSystemError(result, "SdCardManager::mountSdCard"); - return SYSTEM_CALL_ERROR; - } - return HasReturnvaluesIF::RETURN_OK; + return handleCommand(sdMountCommand, "SdCardManager::mountSdCard"); } ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { @@ -229,12 +230,7 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; } string sdUnmountCommand = "umount " + mountPoint; - int result = system(sdUnmountCommand.c_str()); - if (result != 0) { - utility::handleSystemError(result, "SdCardManager::unmountSdCard"); - return SYSTEM_CALL_ERROR; - } - return HasReturnvaluesIF::RETURN_OK; + return handleCommand(sdUnmountCommand, "SdCardManager::unmountSdCard"); } ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard prefSdCard) { @@ -354,3 +350,105 @@ std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { return SD_1_MOUNT_POINT; } } + +SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { + currentOp = this->currentOp; + switch(currentOpStatus) { + case(OpStatus::IDLE): + case(OpStatus::FAIL): + case(OpStatus::TIMEOUT): + case(OpStatus::SUCCESS):{ + break; + } + case(OpStatus::ONGOING): { + int result = poll(&waiter, 1, 0); + switch(result) { + case(0): { + // No data available + break; + } + case(1): { + if (waiter.revents & POLLIN) { + ssize_t readBytes = read(opFileNum, readBuf.data(), readBuf.size()); + if(readBytes == 0) { + // Should not happen.. + sif::warning << "SdCardManager::checkCurrentOp: 0 bytes read" << std::endl; + } + else if(readBytes > 0) { + sif::info << currentCmd << " | " << readBuf.data() << std::endl; + } + else { + sif::error << "SdCardManager::checkCurrentOp: Error code " << errno << + ": " << strerror(errno) << std::endl; + return OpStatus::FAIL; + } + } + else if (waiter.revents & POLLERR) { + sif::warning << "SdCardManager::checkCurrentOp: Poll error.." << std::endl; + } + else if(waiter.revents & POLLHUP) { + int result = pclose(opFile); + if(result != 0) { + sif::error << "SdCardManager::setSdCardState: pclose failed with code " << + result << ": " << strerror(result) << std::endl; + } + opFile = nullptr; + opFileNum = 0; + currentOp = Operations::IDLE; + return OpStatus::SUCCESS; + } + break; + } + default: { + sif::error << "SdCardManager::checkCurrentOp: Unexpected returnvalue " << result << + "for poll call" << std::endl; + break; + } + } + } + } + return currentOpStatus; +} + +void SdCardManager::resetState() { + currentOp = Operations::IDLE; + currentOpStatus = OpStatus::IDLE; + currentOpSdCard = sd::SdCard::NONE; +} + +void SdCardManager::setBlocking(bool blocking) { + this->blocking = blocking; + if(not blocking) { + currentOp = Operations::IDLE; + currentOpStatus = OpStatus::IDLE; + } +} + +ReturnValue_t SdCardManager::handleCommand(std::string cmd, std::string funcName) { + currentCmd = cmd; + opFile = popen(currentCmd.c_str(), "r"); + if(opFile == nullptr) { + return POPEN_CALL_ERROR; + } + if(blocking) { + return handleBlockingOperation(funcName); + } + else { + opFileNum = fileno(opFile); + waiter.fd = opFileNum; + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SdCardManager::handleBlockingOperation(std::string funcName) { + while(fgets(readBuf.data(), readBuf.size(), opFile) != nullptr) { + sif::info << currentCmd << " | " << readBuf.data() << std::endl; + } + int result = pclose(opFile); + if(result != 0) { + sif::error << "SdCardManager::setSdCardState: pclose failed with code " << + result << ": " << strerror(result) << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 7af57a67..c1832e25 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -8,10 +8,13 @@ #include "fsfw/events/Event.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include + #include #include #include #include +#include class MutexIF; @@ -22,16 +25,33 @@ class MutexIF; class SdCardManager { friend class SdCardAccess; public: + enum class Operations { + SWITCHING_ON, + SWITCHING_OFF, + MOUNTING, + IDLE + }; + + enum class OpStatus { + IDLE, + SUCCESS, + TIMEOUT, + ONGOING, + FAIL + }; + using SdStatusPair = std::pair; static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; - static constexpr ReturnValue_t ALREADY_ON = + static constexpr ReturnValue_t OP_ONGOING = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 0); - static constexpr ReturnValue_t ALREADY_MOUNTED = + static constexpr ReturnValue_t ALREADY_ON = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1); - static constexpr ReturnValue_t ALREADY_OFF = + static constexpr ReturnValue_t ALREADY_MOUNTED = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2); + static constexpr ReturnValue_t ALREADY_OFF = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3); static constexpr ReturnValue_t STATUS_FILE_NEXISTS = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 10); static constexpr ReturnValue_t STATUS_FILE_FORMAT_INVALID = @@ -42,6 +62,8 @@ public: HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 13); static constexpr ReturnValue_t SYSTEM_CALL_ERROR = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 14); + static constexpr ReturnValue_t POPEN_CALL_ERROR = + HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 15); static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM; @@ -159,7 +181,26 @@ public: * @return */ std::string getCurrentMountPrefix(sd::SdCard prefSdCardPtr = sd::SdCard::NONE); + + OpStatus checkCurrentOp(Operations& currentOp); + + /** + * If there are issues with the state machine, it can be reset with this function + */ + void resetState(); + + void setBlocking(bool blocking); private: + Operations currentOp = Operations::IDLE; + OpStatus currentOpStatus = OpStatus::IDLE; + sd::SdCard currentOpSdCard = sd::SdCard::NONE; + FILE* opFile = nullptr; + bool blocking = true; + struct pollfd waiter {}; + std::array readBuf {}; + std::string currentCmd; + int opFileNum = 0; + SdCardManager(); ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on); @@ -169,6 +210,9 @@ private: std::string currentPrefix; + ReturnValue_t handleCommand(std::string cmd, std::string funcName); + ReturnValue_t handleBlockingOperation(std::string funcName); + static SdCardManager* factoryInstance; }; diff --git a/fsfw b/fsfw index bb88490c..1a4a85ce 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit bb88490cc6cda5474d1d4913452eeb758da8cc25 +Subproject commit 1a4a85ceb2ad665e3cd3c2042925ae2f2aae70c1 diff --git a/tmtc b/tmtc index a226bf65..3e8626bf 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit a226bf659eeadd3ad300b249d2659043317e2245 +Subproject commit 3e8626bfafa561510323bf8fe3963bc2860950ed -- 2.43.0 From 8104ac0df8a9cb65bfdaab70d251898f27d7bb1e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 15:43:19 +0200 Subject: [PATCH 090/116] using new command executor --- bsp_q7s/memory/SdCardManager.cpp | 219 +++++++++++++++++-------------- bsp_q7s/memory/SdCardManager.h | 6 +- fsfw | 2 +- 3 files changed, 121 insertions(+), 106 deletions(-) diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 4e9ce6c8..83d41c36 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -15,8 +15,7 @@ SdCardManager* SdCardManager::factoryInstance = nullptr; -SdCardManager::SdCardManager() { - waiter.events = POLLIN; +SdCardManager::SdCardManager(): cmdExecutor(256) { } SdCardManager::~SdCardManager() { @@ -151,7 +150,12 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { } ostringstream command; command << "q7hw sd set " << sdstring << " " << statestring; - return handleCommand(command.str(), "SdCardManager::setSdCardState"); + cmdExecutor.load(command.str(), blocking, true); + ReturnValue_t result = cmdExecutor.execute(); + if(blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::setSdCardState"); + } + return result; } ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { @@ -202,7 +206,12 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { } string sdMountCommand = "mount " + mountDev + " " + mountPoint; - return handleCommand(sdMountCommand, "SdCardManager::mountSdCard"); + cmdExecutor.load(sdMountCommand, blocking, true); + ReturnValue_t result = cmdExecutor.execute(); + if(blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); + } + return result; } ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { @@ -230,7 +239,12 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; } string sdUnmountCommand = "umount " + mountPoint; - return handleCommand(sdUnmountCommand, "SdCardManager::unmountSdCard"); + cmdExecutor.load(sdUnmountCommand, blocking, true); + ReturnValue_t result = cmdExecutor.execute(); + if(blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::unmountSdCard"); + } + return result; } ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard prefSdCard) { @@ -327,13 +341,12 @@ ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { ReturnValue_t SdCardManager::updateSdCardStateFile() { // Use q7hw utility and pipe the command output into the state file std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); - int result = std::system(updateCmd.c_str()); - if(result == 0) { - return HasReturnvaluesIF::RETURN_OK; + cmdExecutor.load(updateCmd, blocking, true); + ReturnValue_t result = cmdExecutor.execute(); + if(blocking and result != HasReturnvaluesIF::RETURN_OK) { + utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); } - sif::warning << "SdCardManager::updateSdCardStateFile: system call failed with code " << - result << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + return result; } std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { @@ -352,103 +365,107 @@ std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { } SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { - currentOp = this->currentOp; - switch(currentOpStatus) { - case(OpStatus::IDLE): - case(OpStatus::FAIL): - case(OpStatus::TIMEOUT): - case(OpStatus::SUCCESS):{ - break; - } - case(OpStatus::ONGOING): { - int result = poll(&waiter, 1, 0); - switch(result) { - case(0): { - // No data available - break; - } - case(1): { - if (waiter.revents & POLLIN) { - ssize_t readBytes = read(opFileNum, readBuf.data(), readBuf.size()); - if(readBytes == 0) { - // Should not happen.. - sif::warning << "SdCardManager::checkCurrentOp: 0 bytes read" << std::endl; - } - else if(readBytes > 0) { - sif::info << currentCmd << " | " << readBuf.data() << std::endl; - } - else { - sif::error << "SdCardManager::checkCurrentOp: Error code " << errno << - ": " << strerror(errno) << std::endl; - return OpStatus::FAIL; - } - } - else if (waiter.revents & POLLERR) { - sif::warning << "SdCardManager::checkCurrentOp: Poll error.." << std::endl; - } - else if(waiter.revents & POLLHUP) { - int result = pclose(opFile); - if(result != 0) { - sif::error << "SdCardManager::setSdCardState: pclose failed with code " << - result << ": " << strerror(result) << std::endl; - } - opFile = nullptr; - opFileNum = 0; - currentOp = Operations::IDLE; - return OpStatus::SUCCESS; - } - break; - } - default: { - sif::error << "SdCardManager::checkCurrentOp: Unexpected returnvalue " << result << - "for poll call" << std::endl; - break; - } - } - } - } - return currentOpStatus; +// currentOp = this->currentOp; +// switch(currentOpStatus) { +// case(OpStatus::IDLE): +// case(OpStatus::FAIL): +// case(OpStatus::TIMEOUT): +// case(OpStatus::SUCCESS):{ +// break; +// } +// case(OpStatus::ONGOING): { +// int result = poll(&waiter, 1, 0); +// switch(result) { +// case(0): { +// // No data available +// break; +// } +// case(1): { +// if (waiter.revents & POLLIN) { +// ssize_t readBytes = read(opFileNum, readBuf.data(), readBuf.size()); +// if(readBytes == 0) { +// // Should not happen.. +// sif::warning << "SdCardManager::checkCurrentOp: 0 bytes read" << std::endl; +// } +// else if(readBytes > 0) { +// sif::info << currentCmd << " | " << readBuf.data() << std::endl; +// } +// else { +// sif::error << "SdCardManager::checkCurrentOp: Error code " << errno << +// ": " << strerror(errno) << std::endl; +// return OpStatus::FAIL; +// } +// } +// else if (waiter.revents & POLLERR) { +// sif::warning << "SdCardManager::checkCurrentOp: Poll error.." << std::endl; +// } +// else if(waiter.revents & POLLHUP) { +// int result = pclose(opFile); +// if(result != 0) { +// sif::error << "SdCardManager::setSdCardState: pclose failed with code " << +// result << ": " << strerror(result) << std::endl; +// } +// opFile = nullptr; +// opFileNum = 0; +// currentOp = Operations::IDLE; +// return OpStatus::SUCCESS; +// } +// break; +// } +// default: { +// sif::error << "SdCardManager::checkCurrentOp: Unexpected returnvalue " << result << +// "for poll call" << std::endl; +// break; +// } +// } +// } +// } +// return currentOpStatus; } -void SdCardManager::resetState() { - currentOp = Operations::IDLE; - currentOpStatus = OpStatus::IDLE; - currentOpSdCard = sd::SdCard::NONE; -} - -void SdCardManager::setBlocking(bool blocking) { - this->blocking = blocking; - if(not blocking) { - currentOp = Operations::IDLE; - currentOpStatus = OpStatus::IDLE; - } -} +//void SdCardManager::resetState() { +// currentOp = Operations::IDLE; +// currentOpStatus = OpStatus::IDLE; +// currentOpSdCard = sd::SdCard::NONE; +//} +// +//void SdCardManager::setBlocking(bool blocking) { +// this->blocking = blocking; +// if(not blocking) { +// currentOp = Operations::IDLE; +// currentOpStatus = OpStatus::IDLE; +// } +//} ReturnValue_t SdCardManager::handleCommand(std::string cmd, std::string funcName) { - currentCmd = cmd; - opFile = popen(currentCmd.c_str(), "r"); - if(opFile == nullptr) { - return POPEN_CALL_ERROR; - } - if(blocking) { - return handleBlockingOperation(funcName); - } - else { - opFileNum = fileno(opFile); - waiter.fd = opFileNum; - } +// currentCmd = cmd; +// opFile = popen(currentCmd.c_str(), "r"); +// if(opFile == nullptr) { +// return POPEN_CALL_ERROR; +// } +// if(blocking) { +// return handleBlockingOperation(funcName); +// } +// else { +// opFileNum = fileno(opFile); +// waiter.fd = opFileNum; +// } return HasReturnvaluesIF::RETURN_OK; } +void SdCardManager::setBlocking(bool blocking) { + this->blocking = blocking; +} + ReturnValue_t SdCardManager::handleBlockingOperation(std::string funcName) { - while(fgets(readBuf.data(), readBuf.size(), opFile) != nullptr) { - sif::info << currentCmd << " | " << readBuf.data() << std::endl; - } - int result = pclose(opFile); - if(result != 0) { - sif::error << "SdCardManager::setSdCardState: pclose failed with code " << - result << ": " << strerror(result) << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } +// while(fgets(readBuf.data(), readBuf.size(), opFile) != nullptr) { +// sif::info << currentCmd << " | " << readBuf.data() << std::endl; +// } +// int result = pclose(opFile); +// if(result != 0) { +// sif::error << "SdCardManager::setSdCardState: pclose failed with code " << +// result << ": " << strerror(result) << std::endl; +// return HasReturnvaluesIF::RETURN_FAILED; +// } return HasReturnvaluesIF::RETURN_OK; } diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index c1832e25..cd0493cf 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -1,6 +1,7 @@ #ifndef BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ #define BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ +#include #include "definitions.h" #include "returnvalues/classIds.h" #include "events/subsystemIdRanges.h" @@ -191,12 +192,9 @@ public: void setBlocking(bool blocking); private: + CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; - OpStatus currentOpStatus = OpStatus::IDLE; - sd::SdCard currentOpSdCard = sd::SdCard::NONE; - FILE* opFile = nullptr; bool blocking = true; - struct pollfd waiter {}; std::array readBuf {}; std::string currentCmd; int opFileNum = 0; diff --git a/fsfw b/fsfw index 1a4a85ce..c8472beb 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 1a4a85ceb2ad665e3cd3c2042925ae2f2aae70c1 +Subproject commit c8472beb5f31b8f33491b5fccfecdd18bce26542 -- 2.43.0 From 7f327c3900b5778604ac6220a0633a44c7838fe0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 16:02:35 +0200 Subject: [PATCH 091/116] bugfixes for sdc manager --- bsp_q7s/memory/SdCardManager.cpp | 150 ++++++++++--------------------- bsp_q7s/memory/SdCardManager.h | 15 ++-- fsfw | 2 +- 3 files changed, 55 insertions(+), 112 deletions(-) diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 83d41c36..932a4217 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -129,11 +129,11 @@ ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSd ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { using namespace std; + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } string sdstring = ""; string statestring = ""; - if(currentOp != Operations::IDLE) { - return OP_ONGOING; - } if(sdCard == sd::SdCard::SLOT_0) { sdstring = "0"; } @@ -181,8 +181,8 @@ ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { using namespace std; - if(currentOp != Operations::IDLE) { - return OP_ONGOING; + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; } if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::mountSdCard: API does not allow sd::SdStatus::BOTH" @@ -205,6 +205,9 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { return MOUNT_ERROR; } + if(not blocking) { + currentOp = Operations::MOUNTING; + } string sdMountCommand = "mount " + mountDev + " " + mountPoint; cmdExecutor.load(sdMountCommand, blocking, true); ReturnValue_t result = cmdExecutor.execute(); @@ -215,6 +218,9 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { } ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } using namespace std; if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::unmountSdCard: API does not allow sd::SdStatus::BOTH" @@ -239,6 +245,9 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl; } string sdUnmountCommand = "umount " + mountPoint; + if(not blocking) { + currentOp = Operations::UNMOUNTING; + } cmdExecutor.load(sdUnmountCommand, blocking, true); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { @@ -266,6 +275,11 @@ ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard return switchOnSdCard(prefSdCard, true, statusPair); } +void SdCardManager::resetState() { + cmdExecutor.reset(); + currentOp = Operations::IDLE; +} + void SdCardManager::processSdStatusLine(std::pair &active, std::string& line, uint8_t& idx, sd::SdCard& currentSd) { using namespace std; @@ -339,6 +353,9 @@ ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { } ReturnValue_t SdCardManager::updateSdCardStateFile() { + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { + return CommandExecutor::COMMAND_PENDING; + } // Use q7hw utility and pipe the command output into the state file std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); cmdExecutor.load(updateCmd, blocking, true); @@ -365,107 +382,36 @@ std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { } SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { -// currentOp = this->currentOp; -// switch(currentOpStatus) { -// case(OpStatus::IDLE): -// case(OpStatus::FAIL): -// case(OpStatus::TIMEOUT): -// case(OpStatus::SUCCESS):{ -// break; -// } -// case(OpStatus::ONGOING): { -// int result = poll(&waiter, 1, 0); -// switch(result) { -// case(0): { -// // No data available -// break; -// } -// case(1): { -// if (waiter.revents & POLLIN) { -// ssize_t readBytes = read(opFileNum, readBuf.data(), readBuf.size()); -// if(readBytes == 0) { -// // Should not happen.. -// sif::warning << "SdCardManager::checkCurrentOp: 0 bytes read" << std::endl; -// } -// else if(readBytes > 0) { -// sif::info << currentCmd << " | " << readBuf.data() << std::endl; -// } -// else { -// sif::error << "SdCardManager::checkCurrentOp: Error code " << errno << -// ": " << strerror(errno) << std::endl; -// return OpStatus::FAIL; -// } -// } -// else if (waiter.revents & POLLERR) { -// sif::warning << "SdCardManager::checkCurrentOp: Poll error.." << std::endl; -// } -// else if(waiter.revents & POLLHUP) { -// int result = pclose(opFile); -// if(result != 0) { -// sif::error << "SdCardManager::setSdCardState: pclose failed with code " << -// result << ": " << strerror(result) << std::endl; -// } -// opFile = nullptr; -// opFileNum = 0; -// currentOp = Operations::IDLE; -// return OpStatus::SUCCESS; -// } -// break; -// } -// default: { -// sif::error << "SdCardManager::checkCurrentOp: Unexpected returnvalue " << result << -// "for poll call" << std::endl; -// break; -// } -// } -// } -// } -// return currentOpStatus; -} + CommandExecutor::States state = cmdExecutor.getCurrentState(); + if(state == CommandExecutor::States::IDLE or state == CommandExecutor::States::COMMAND_LOADED) { + return OpStatus::IDLE; + } + currentOp = this->currentOp; + bool bytesRead = false; -//void SdCardManager::resetState() { -// currentOp = Operations::IDLE; -// currentOpStatus = OpStatus::IDLE; -// currentOpSdCard = sd::SdCard::NONE; -//} -// -//void SdCardManager::setBlocking(bool blocking) { -// this->blocking = blocking; -// if(not blocking) { -// currentOp = Operations::IDLE; -// currentOpStatus = OpStatus::IDLE; -// } -//} - -ReturnValue_t SdCardManager::handleCommand(std::string cmd, std::string funcName) { -// currentCmd = cmd; -// opFile = popen(currentCmd.c_str(), "r"); -// if(opFile == nullptr) { -// return POPEN_CALL_ERROR; -// } -// if(blocking) { -// return handleBlockingOperation(funcName); -// } -// else { -// opFileNum = fileno(opFile); -// waiter.fd = opFileNum; -// } - return HasReturnvaluesIF::RETURN_OK; + while(true) { + ReturnValue_t result = cmdExecutor.check(bytesRead); + switch(result) { + case(CommandExecutor::BYTES_READ): { + continue; + } + case(CommandExecutor::EXECUTION_FINISHED): { + return OpStatus::SUCCESS; + } + case(HasReturnvaluesIF::RETURN_OK): { + return OpStatus::ONGOING; + } + case(HasReturnvaluesIF::RETURN_FAILED): { + return OpStatus::FAIL; + } + default: { + sif::warning << "SdCardManager::checkCurrentOp: Unhandled case" << std::endl; + } + } + } } void SdCardManager::setBlocking(bool blocking) { this->blocking = blocking; } -ReturnValue_t SdCardManager::handleBlockingOperation(std::string funcName) { -// while(fgets(readBuf.data(), readBuf.size(), opFile) != nullptr) { -// sif::info << currentCmd << " | " << readBuf.data() << std::endl; -// } -// int result = pclose(opFile); -// if(result != 0) { -// sif::error << "SdCardManager::setSdCardState: pclose failed with code " << -// result << ": " << strerror(result) << std::endl; -// return HasReturnvaluesIF::RETURN_FAILED; -// } - return HasReturnvaluesIF::RETURN_OK; -} diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index cd0493cf..a6d9227a 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -30,14 +30,15 @@ public: SWITCHING_ON, SWITCHING_OFF, MOUNTING, + UNMOUNTING, IDLE }; enum class OpStatus { IDLE, - SUCCESS, TIMEOUT, ONGOING, + SUCCESS, FAIL }; @@ -130,8 +131,10 @@ public: /** * Update the state file or creates one if it does not exist. You need to call this * function before calling #sdCardActive - * @return - RETURN_OK if the state file was updated successfully - * - SYSTEM_CALL_ERROR if the call to create the status file failed + * @return + * - RETURN_OK if the state file was updated successfully + * - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending + * - RETURN_FAILED: blocking command failed */ ReturnValue_t updateSdCardStateFile(); @@ -195,9 +198,6 @@ private: CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; bool blocking = true; - std::array readBuf {}; - std::string currentCmd; - int opFileNum = 0; SdCardManager(); @@ -208,9 +208,6 @@ private: std::string currentPrefix; - ReturnValue_t handleCommand(std::string cmd, std::string funcName); - ReturnValue_t handleBlockingOperation(std::string funcName); - static SdCardManager* factoryInstance; }; diff --git a/fsfw b/fsfw index c8472beb..42022051 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c8472beb5f31b8f33491b5fccfecdd18bce26542 +Subproject commit 4202205182aa007b9be5279ce40056e18f0b8782 -- 2.43.0 From f64356d75ef889f2dbc9e2463ca5a0c005ab7fa5 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Thu, 5 Aug 2021 16:37:39 +0200 Subject: [PATCH 092/116] ploc udpater wip --- common/config/commonSubsystemIds.h | 1 + mission/devices/PlocSupervisorHandler.cpp | 6 + mission/devices/PlocSupervisorHandler.h | 2 +- mission/devices/PlocUpdater.cpp | 283 +++++++++++++++++- mission/devices/PlocUpdater.h | 92 +++++- .../PlocSupervisorDefinitions.h | 114 +++++++ 6 files changed, 484 insertions(+), 14 deletions(-) diff --git a/common/config/commonSubsystemIds.h b/common/config/commonSubsystemIds.h index 7c2cb605..ab87d119 100644 --- a/common/config/commonSubsystemIds.h +++ b/common/config/commonSubsystemIds.h @@ -17,6 +17,7 @@ enum: uint8_t { STR_HANDLER = 114, PLOC_SUPERVISOR_HANDLER = 115, FILE_SYSTEM = 116, + PLOC_UPDATER = 117, COMMON_SUBSYSTEM_ID_END }; } diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 9c4dc73e..409a48c5 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -241,6 +241,12 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( result = RETURN_OK; break; } + case(PLOC_SPV::UPDATE_AVAILABLE): + case(PLOC_SPV::UPDATE_AVAILABLE): + case(PLOC_SPV::UPDATE_AVAILABLE): + // Simply forward data from PLOC Updater to supervisor + std::memcpy(rawPacket, commandData, commandDataLen); + break; default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" << std::endl; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index df4645b2..c98cb37c 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -82,7 +82,7 @@ private: static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; - //! [EXPORT] : [COMMENT] PLOC supervrisor crc failure in telemetry packet + //! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW); //! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report static const Event SUPV_ACK_FAILURE = MAKE_EVENT(2, severity::LOW); diff --git a/mission/devices/PlocUpdater.cpp b/mission/devices/PlocUpdater.cpp index c7310298..9639ff87 100644 --- a/mission/devices/PlocUpdater.cpp +++ b/mission/devices/PlocUpdater.cpp @@ -1,4 +1,5 @@ #include +#include PlocUpdater::PlocUpdater() : commandActionHelper(this) { commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); @@ -7,11 +8,16 @@ PlocUpdater::PlocUpdater() : commandActionHelper(this) { PlocUpdater::~PlocUpdater() { } +ReturnValue_t SystemObject::initialize() { + sdcMan = SdCardManager::instance(); + return HasReturnvaluesIF::RETURN_OK; +} + ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { ReturnValue_t result = RETURN_FAILED; - if (state == BUSY) { + if (state != IDLE) { return IS_BUSY; } @@ -21,20 +27,27 @@ ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, switch (actionId) { case UPDATE_NVM0_A: - result = prepareNvm0AUpdate(std::string(data, size)); + updateImage = Image::A; + updateMemory = Memory::NVM0; break; case UPDATE_NVM0_B: - result = prepareNvm0BUpdate(); + updateImage = Image::B; + updateMemory = Memory::NVM0; break; case UPDATE_NVM1_A: - result = prepareNvm1AUpdate(); + updateImage = Image::A; + updateMemory = Memory::NVM1; break; case UPDATE_NVM1_B: - result = prepareNvm1BUpdate(); + updateImage = Image::B; + updateMemory = Memory::NVM1; break; default: return INVALID_ACTION_ID; } + + result = getImageLocation(data, size); + return result; } @@ -42,13 +55,265 @@ MessageQueueId_t PlocUpdater::getCommandQueue() const { return commandQueue.getId(); } -ReturnValue_t PlocUpdater::checkPath(size_t size) { +void PlocUpdater::readCommandQueue() { + CommandMessage message; + ReturnValue_t result = commandQueue->receiveMessage(&message); + if (result != RETURN_OK) { + return; + } + result = actionHelper.handleActionMessage(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + + result = commandActionHelper.handleReply(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + result = parameterHelper.handleParameterMessage(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + message.setToUnknownCommand(); + commandQueue.reply(&message); +} + +void PlocUpdater::doStateMachine() { + switch (state) { + case State::IDLE: + break; + case State::UPDATE_AVAILABLE: + commandUpdateAvailable(); + break; + case State::UPDATE_TRANSFER: + commandUpdatePacket(); + break; + case State::UPDATE_VERIFY: + break; + default: + sif::debug << "PlocUpdater::doStateMachine: Invalid state" << std::endl; + break; + } +} + +ReturnValue_t PlocUpdater::checkNameLength(size_t size) { if (size > MAX_PLOC_UPDATE_PATH) { - return PATH_TOO_LONG; + return NAME_TOO_LONG; } return RETURN_OK; } -PlocUpdater::prepare -getCurrentMountPrefix +ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { + ReturnValue_t result = checkNameLength(size); + if (result != RETURN_OK) { + return result; + } + // Check if file is stored on SD card and if associated SD card is mounted + if (std::string(data, SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { + if (!isSdCardMounted(sd::SLOT_0)) { + sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 0 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + else if (std::string(data, SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { + if (!isSdCardMounted(sd::SLOT_0)) { + sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 1 not mounted" << std::endl; + return SD_NOT_MOUNTED; + } + } + else { + //update image not stored on SD card + } + + updateFile = std::string(reinterpret_cast(data), size); + + // Check if file exists + if(not std::filesystem::exists(updateFile)) { + return FILE_NOT_EXISTS; + } + return RETURN_OK; +} + +bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) { + SdStatusPair active; + ReturnValue_t result = sdcMan->getSdCardActiveStatus(&active); + if (result != RETURN_OK) { + sif::debug << "PlocUpdater::isSdCardMounted: Failed to get SD card active state"; + return false; + } + if (sdCard == sd::SLOT_0) { + if (active.first == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else if (sdCard == sd::SLOT_1) { + if (active.second == sd::MOUNTED) { + return true; + } + else { + return false; + } + } + else { + sif::debug << "PlocUpdater::isSdCardMounted: Unknown SD card specified" << std::endl; + } + return false; +} + +void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId, + uint8_t step) { +} + +void PlocUpdater::stepFailedReceived(ActionId_t actionId, uint8_t step, + ReturnValue_t returnCode) { +} + +void PlocUpdater::completionSuccessfulReceived(ActionId_t actionId) { + switch (actionId) { + case UPDATE_AVAILABLE: + state = State::UPDATE_TRANSFER; + break; + case UPDATE_IMAGE_DATA: + if (remainingPackets == 0) { + packetsSent = 0; // Reset packets sent variable for next update sequence + state = State::UPDATE_VERIFY; + } + break; + case UPDATE_VERIFY: + triggerEvent(UPDATE_FINISHED); + break; + default: + sif::debug << "PlocUpdater::completionSuccessfulReceived: Action message with has unknown " + << "action id" << std::endl; + break; + } +} + +void PlocUpdater::completionFailedReceived(ActionId_t actionId, + ReturnValue_t returnCode) { + state = State::IDLE; + switch(state) { + case(State::UPDATE_AVAILABLE): { + triggerEvent(UPDATE_AVAILABLE_FAILED); + break; + } + case(State::UPDATE_TRANSFER): { + triggerEvent(UPDATE_TRANSFER_FAILED); + break; + } + case(State::UPDATE_VERIFY): { + triggerEvent(UPDATE_VERIFY_FAILED); + break; + } + default: + sif::debug << "PlocUpdater::completionFailedReceived: Action message with has unknown " + << "action id" << std::endl; + break; + } +} + +void PlocUpdater::commandUpdateAvailable() { + ReturnValue_t result = RETURN_OK; + + if (not std::filesystem::exists(updateFile)) { + triggerEvent(UPDATE_FILE_NOT_EXISTS, state); + state = State::IDLE; + return; + } + + std::ifstream file(updateFile, std::ifstream::binary); + file.seekg(0, file.end); + imageSize = static_cast(file.tellg()); + file.close(); + + numOfUpdatePackets = imageSize / MAX_SP_DATA ; + if (! imageSize % MAX_SP_DATA) { + numOfUpdatePackets++; + } + + remainingPackets = numOfUpdatePackets; + packetsSent = 0; + + uint32_t imageCrc = makeCrc(); + + PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast(updateMemory), + static_cast(updatePartition), imageSize, imageCrc, numOfUpdatePackets); + + result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, UPDATE_AVAILABLE, + packet.getFullSize()); + if (result != RETURN_OK) { + sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" + << " packet to supervisor handler" << std::endl; + triggerEvent(ACTION_COMMANDING_FAILED, result, UPDATE_AVAILABLE); + return; + } + return; +} + +void PlocUpdater::commandUpdatePacket() { + uint16_t payloadLength = 0; + + if (not std::filesystem::exists(updateFile)) { + triggerEvent(UPDATE_FILE_NOT_EXISTS, state, packetsSent); + state = State::IDLE; + return; + } + + std::ifstream file(updateFile, std::ifstream::binary); + file.seekg(packetsSent * MAX_SP_DATA, file.beg); + + if (remainingPackets == 1) { + payloadLength = static_cast(file.tellg()); + } + else { + payloadLength = MAX_SP_DATA; + } + + PLOC_SPV::UpdatePacket packet(payloadLength); + file.read(static_cast(packet.getDataFieldPointer()), payloadLength); + file.close(); + packet.updateCrc(); + + commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, UPDATE_IMAGE_DATA, + packet.getDataFieldPointer(), packet.getFullSize()); + remainingPackets--; +} + +void PlocUpdater::commandUpdateVerify() { + ReturnValue_t result = RETURN_OK; + + if (not std::filesystem::exists(updateFile)) { + triggerEvent(UPDATE_FILE_NOT_EXISTS, state); + state = State::IDLE; + return; + } + + remainingPackets = imageSize / MAX_SP_DATA ; + if (! imageSize % MAX_SP_DATA) { + remainingPackets++; + } + + uint32_t imageCrc = makeCrc(); + + PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast(updateMemory), + static_cast(updatePartition), imageSize, imageCrc, numOfUpdatePackets); + + result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, UPDATE_AVAILABLE, + packet.getFullSize()); + if (result != RETURN_OK) { + sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" + << " packet to supervisor handler" << std::endl; + triggerEvent(ACTION_COMMANDING_FAILED, result, UPDATE_AVAILABLE); + return; + } + return; +} + +ReturnValue_t PlocUpdater::makeCrc() { + //TODO: Waiting on input from TAS about the CRC to use + return 0; +} diff --git a/mission/devices/PlocUpdater.h b/mission/devices/PlocUpdater.h index dd37898e..42c855f3 100644 --- a/mission/devices/PlocUpdater.h +++ b/mission/devices/PlocUpdater.h @@ -3,13 +3,16 @@ #include "fsfw/action/CommandActionHelper.h" #include "fsfw/returnvalues/HasReturnValuesIF.h" +#include "bsp_q7s/memory/SdCardManager.h" +#include "linux/fsfwconfig/objects/systemObjectList.h" +#include "fsfw/tmtcpacket/SpacePacket.h" /** * @brief An object of this class can be used to perform the software updates of the PLOC. The * software update will be fetched via file system messages from the SD card handler, * split into multiple space packets and sent to the PlocSupervisorHandler. * - * @details The MPSoC has to boot memories (NVM0 and NVM1) where each stores two images (Partition A + * @details The MPSoC has two boot memories (NVM0 and NVM1) where each stores two images (Partition A * and Partition B) * * @author J. Meier @@ -17,7 +20,8 @@ class PlocUpdater : public SystemObject, public HasActionsIF, public ExecutableObjectIF, - public HasReturnvaluesIF { + public HasReturnvaluesIF, + public CommandsActionsIF { public: static const ActionId_t UPDATE_NVM0_A = 0; @@ -31,6 +35,12 @@ public: ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size); MessageQueueId_t getCommandQueue() const; + ReturnValue_t initialize() override; + void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; + void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override; + void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override; + void completionSuccessfulReceived(ActionId_t actionId) override; + void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override; private: @@ -39,14 +49,88 @@ private: //! [EXPORT] : [COMMENT] Updater is already performing an update static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0); //! [EXPORT] : [COMMENT] Received update command with invalid path string (too long). - static const ReturnValue_t PATH_TOO_LONG = MAKE_RETURN_CODE(0xA0); + static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA1); + //! [EXPORT] : [COMMENT] Received command to initiate update but SD card with update image not mounted. + static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA2); + //! [EXPORT] : [COMMENT] Update file received with update command does not exist. + static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA3); + + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_UPDATER; + + //! [EXPORT] : [COMMENT] Try to read update file but the file does not exist. + //! P1: Indicates in which state the file read fails + //! P2: During the update transfer the second parameter gives information about the number of already sent packets + static const Event UPDATE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW); + //! [EXPORT] : [COMMENT] Failed to send command to supervisor handler + //! P1: Return value of CommandActionHelper::commandAction + //! P2: Action ID of command to send + static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW); + //! [EXPORT] : [COMMENT] Supervisor handler replied action message indicating a command execution failure of the update available command + static const Event UPDATE_AVAILABLE_FAILED = MAKE_EVENT(2, severity::LOW); + //! [EXPORT] : [COMMENT] Supervisor handler failed to transfer an update space packet. + //! P1: Parameter holds the number of update packets already sent. + static const Event UPDATE_TRANSFER_FAILED = MAKE_EVENT(3, severity::LOW); + //! [EXPORT] : [COMMENT] Supervisor failed to execute the update verify command. + static const Event UPDATE_VERIFY_FAILED = MAKE_EVENT(4, severity::LOW); + //! [EXPORT] : [COMMENT] MPSoC update successful completed + static const Event UPDATE_FINISHED = MAKE_EVENT(5, SEVERITY::INFO); static const uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE; static const size_t MAX_PLOC_UPDATE_PATH = 20; + static const size_t SD_PREFIX_LENGTH = 8; + // Maximum size of update payload data per space packet (max size of space packet is 1024 bytes) + static const size_t MAX_SP_DATA = 1016; + + static const ActionId_t UPDATE_AVAILABLE = 12; + static const ActionId_t UPDATE_IMAGE_DATA = 39; + static const ActionId_t UPDATE_VERIFY = 42; + + SdCardManager* sdcMan = nullptr; CommandActionHelper commandActionHelper; - ReturnValue_t checkPath(size_t size); + enum class State: uint8_t { + IDLE, + UPDATE_AVAILABLE, + UPDATE_TRANSFER, + UPDATE_VERIFY + }; + + State state = State::IDLE; + + enum class Memory: uint8_t { + NVM0, + NVM1 + }; + + Memory updateMemory = Memory::NVM0; + + enum class Partition: uint8_t { + A, + B + }; + + Partition updatePartition = Partition::A; + + State state = State::IDLE; + + uint32_t packetsSent = 0; + uint32_t remainingPackets = 0; + // Number of packets required to transfer the update image + uint32_t numOfUpdatePackets = 0; + + std::string updateFile; + uint32_t imageSize = 0; + uint32_t imageCrc = 0; + + ReturnValue_t checkNameLength(size_t size); + + /** + * @brief Checks whether the SD card to read from is mounted or not. + */ + bool isSdCardMounted(sd::SdCard sdCard); + + ReturnValue_t makeCrc(); }; #endif /* MISSION_DEVICES_PLOCUPDATER_H_ */ diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index cc7be993..32e682a1 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -52,6 +52,7 @@ static const DeviceCommandId_t REQUEST_LOGGING_DATA = 38; static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39; static const DeviceCommandId_t FACTORY_RESET_CLEAR_MIRROR = 40; static const DeviceCommandId_t FACTORY_RESET_CLEAR_CIRCULAR = 41; +static const DeviceCommandId_t UPDATE_VERIFY = 42; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; @@ -1406,6 +1407,119 @@ private: } }; +class SupvTcSpacePacket : public SpacePacket { +public: + SupvTcSpacePacket(size_t payloadDataLen, uint16_t apid) : + SpacePacket(payloadLen + 1, true, apid, + DEFAULT_SEQUENCE_COUNT), payloadDataLen(payloadDataLen) { + initPacket(); + makeCrc(); + } + +protected: + void makeCrc() { + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + payloadDataLen); + uint8_t* crcPos = this->localData.fields.buffer + payloadDataLen; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } + +private: + // The sequence count of most of the TC packets for the supervisor is 1. + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + // The size of the payload data (data field without crc size) + size_t payloadDataLen = 0; + + void virtual initPacket() { + // Perform stuff to fill packet data field + } +}; + +/** + * @brief This class packages the update available space packet. This is the first packet sent + * to the supervisor in an update procedure. + */ +class UpdateInfo: public SupvTcSpacePacket { +public: + + /** + * @brief Constructor + * + * @param apid Packet can be used to generate the update available and the update verify + * packet. Thus the APID must be specified here. + * @param memory The memory to apply the update (NVM0 - 0, NVM1 - 1) + * @param partition The partition to update (A - 0, B - 1) + * @param imageSize The size of the update image + * param numPackets The number of space packets required to transfer all data. + */ + UpdateInfo(uint16_t apid, uint8_t memory, uint8_t partition, uint32_t imageSize, + uint32_t imageCrc, uint32_t numPackets) : + SupvTcSpacePacket(PAYLOAD_LENGTH, apid), memory(memory), partition(partition), imageSize( + imageSize), numPackets(numPackets) { + initPacket(); + } + +private: + + static const uint16_t PAYLOAD_LENGTH = 14; // length without CRC field + + uint8_t memory = 0; + uint8_t partition = 0; + uint32_t imageSize = 0; + uint32_t imageCrc = 0; + uint32_t numPackets = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(memory, &data_field_ptr, &serializedSize, + sizeof(memory), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&partition, &data_field_ptr, &serializedSize, + sizeof(partition), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&imageSize, &data_field_ptr, &serializedSize, + sizeof(imageSize), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&imageCrc, &data_field_ptr, &serializedSize, + sizeof(imageCrc), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&numPackets, &data_field_ptr, &serializedSize, + sizeof(numPackets), SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet transporting a part of an MPSoC update. + */ +class UpdatePacket: public SupvTcSpacePacket { +public: + + /** + * @brief Constructor + * + * @param payloadLength Update data length (data field length without CRC) + */ + UpdatePacket(uint16_t payloadLength) : + SupvTcSpacePacket(payloadLength, APID_UPDATE_IMAGE_DATA) { + initPacket(); + } + + /** + * @brief Returns the pointer to the beginning of the data field. + */ + uint8_t* getDataFieldPointer() { + return this->localData.fields.buffer; + } + + void updateCrc() { + this->makeCrc(); + } +}; + /** * @brief This dataset stores the boot status report of the supervisor. */ -- 2.43.0 From 05088ce02c1071166eb2c721f9cf1e156bb2b481 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 18:13:32 +0200 Subject: [PATCH 093/116] SDC manager and core controller refactoring --- bsp_q7s/core/CoreController.cpp | 290 +++++++++++++++++++++------ bsp_q7s/core/CoreController.h | 32 ++- bsp_q7s/memory/FileSystemHandler.cpp | 4 +- bsp_q7s/memory/SdCardManager.cpp | 71 ++++--- bsp_q7s/memory/SdCardManager.h | 4 +- bsp_q7s/memory/definitions.h | 2 +- fsfw | 2 +- 7 files changed, 303 insertions(+), 102 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index e49f0007..0516e26f 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -12,6 +12,8 @@ #include "fsfw/osal/common/TcpTmTcBridge.h" #endif +#include "fsfw/osal/linux/Timer.h" + #include "bsp_q7s/memory/scratchApi.h" #include "bsp_q7s/memory/SdCardManager.h" @@ -24,8 +26,7 @@ CoreController::Chip CoreController::currentChip = Chip::NO_CHIP; CoreController::Copy CoreController::currentCopy = Copy::NO_COPY; CoreController::CoreController(object_id_t objectId): - ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), - opDivider(5) { + ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; try { result = initWatchdogFifo(); @@ -33,6 +34,13 @@ CoreController::CoreController(object_id_t objectId): sif::warning << "CoreController::CoreController: Watchdog FIFO init failed" << std::endl; } + sdcMan = SdCardManager::instance(); + if(sdcMan == nullptr) { + sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; + } + if(not BLOCKING_SD_INIT) { + initSdCardNonBlocking(); + } result = initBootCopy(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -50,6 +58,9 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { + if(not BLOCKING_SD_INIT and not sdInitFinished) { + initSdCardNonBlocking(); + } performWatchdogControlOperation(); } @@ -71,6 +82,10 @@ ReturnValue_t CoreController::initialize() { "count failed" << std::endl; } + if(not BLOCKING_SD_INIT) { + initSdCardNonBlocking(); + } + return ExtendedControllerBase::initialize(); } @@ -79,16 +94,11 @@ ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t CoreController::initSdCard() { +ReturnValue_t CoreController::initSdCardBlocking() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE sif::info << "No SD card initialization will be performed" << std::endl; return HasReturnvaluesIF::RETURN_OK; #else - SdCardManager* sdcMan = SdCardManager::instance(); - if(sdcMan == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; - } - // Create update status file ReturnValue_t result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -96,19 +106,24 @@ ReturnValue_t CoreController::initSdCard() { << std::endl; } - auto statusPair = SdCardManager::SdStatusPair(sd::SdStatus::OFF, sd::SdStatus::OFF); + auto statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); result = sdcMan->getSdCardActiveStatus(statusPair); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - return sdCardColdRedundantInit(sdcMan, statusPair); + determinePreferredSdCard(); + sif::info << "Cold redundant SD card configuration, preferred SD card: " << + static_cast(preferredSdCard) << std::endl; + result = sdCardColdRedundantInit(sdcMan, statusPair); + // Update status file + sdcMan->updateSdCardStateFile(); + return result; #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT sif::info << "Hot redundant SD card configuration" << std::endl; - - setUpSdCard(sd::SdCard::SLOT_0, sdStatus.first, "0"); - setUpSdCard(sd::SdCard::SLOT_1, sdStatus.second, "1"); + sdCardSetup(statusPair, sd::SdCard::SLOT_0, "0"); + sdCardSetup(statusPair, sd::SdCard::SLOT_1, "1"); // Update status file sdcMan->updateSdCardStateFile(); return HasReturnvaluesIF::RETURN_OK; @@ -118,9 +133,130 @@ ReturnValue_t CoreController::initSdCard() { } -ReturnValue_t CoreController::sdCardSetup(SdCardManager& sdcMan, - SdCardManager::SdStatusPair& statusPair,sd::SdCard sdCard, sd::SdStatus status, - std::string sdString) { +ReturnValue_t CoreController::initSdCardNonBlocking() { +#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE + sif::info << "No SD card initialization will be performed" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +#else + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + if(state == SdStates::START) { + sdcInitCycleCount = 0; + commandExecuted = false; + state = SdStates::GET_INFO; + } + + if(state == SdStates::GET_INFO) { + if(not commandExecuted) { + // Create update status file + result = sdcMan->updateSdCardStateFile(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Updating SD card state file failed" + << std::endl; + } + commandExecuted = true; + } + else { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + state = SdStates::SET_STATE; + commandExecuted = false; + sdcInitCycleCount = 0; + } + else if(sdcInitCycleCount > 2) { + sif::warning << "CoreController::initSdCardNonBlocking: " + "Updating SDC file takes too long" << std::endl; + } + } + } + + if(state == SdStates::SET_STATE) { + if(not commandExecuted) { + determinePreferredSdCard(); + statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); + result = sdcMan->getSdCardActiveStatus(statusPair); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Getting SD card activity status failed" << std::endl; + } + sif::info << "Cold redundant SD card configuration, preferred SD card: " << + static_cast(preferredSdCard) << std::endl; + result = sdCardColdRedundantInit(sdcMan, statusPair); + if(result == SdCardManager::ALREADY_ON) { + state = SdStates::MOUNT; + } + if(result == SdCardManager::ALREADY_MOUNTED) { + state = SdStates::UPDATE_INFO; + } + else { + commandExecuted = true; + } + } + else { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + state = SdStates::MOUNT; + commandExecuted = false; + sdcInitCycleCount = 0; + } + else if(sdcInitCycleCount > 10) { + sif::warning << "CoreController::initSdCardNonBlocking: " + "Setting SDC state takes too long" << std::endl; + } + } + } + + if(state == SdStates::MOUNT) { + if(not commandExecuted) { + result = sdCardColdRedundantInit(sdcMan, statusPair); + commandExecuted = false; + } + else { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + state = SdStates::UPDATE_INFO; + commandExecuted = false; + sdcInitCycleCount = 0; + } + else if(sdcInitCycleCount > 5) { + sif::warning << "CoreController::initSdCardNonBlocking: " + "Mounting SD card takes too long" << std::endl; + } + } + } + + if(state == SdStates::UPDATE_INFO) { + if(not commandExecuted) { + // Update status file + result = sdcMan->updateSdCardStateFile(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Updating SD card state file failed" + << std::endl; + } + commandExecuted = true; + } + else { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + sdInitFinished = true; + state = SdStates::DONE; + } + else if(sdcInitCycleCount > 2) { + sif::warning << "CoreController::initSdCardNonBlocking: " + "Updating SDC file takes too long" << std::endl; + } + } + } + + return HasReturnvaluesIF::RETURN_OK; +#endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ +} + + +ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPair, + sd::SdCard sdCard, std::string sdString) { std::string mountString; if(sdCard == sd::SdCard::SLOT_0) { mountString = SdCardManager::SD_0_MOUNT_POINT; @@ -129,27 +265,60 @@ ReturnValue_t CoreController::sdCardSetup(SdCardManager& sdcMan, mountString = SdCardManager::SD_1_MOUNT_POINT; } - if(status == sd::SdStatus::OFF) { - sif::info << "Switching on and mounting SD card " << sdString << " at " << - mountString << std::endl; - return sdcMan.switchOnSdCard(sdCard, true, &statusPair); - } - else if(status == sd::SdStatus::ON) { - sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; - return sdcMan.mountSdCard(sdCard); + sd::SdState status = sd::SdState::OFF; + if(sdCard == sd::SdCard::SLOT_0) { + status = statusPair.first; } else { + status = statusPair.second; + } + if(status == sd::SdState::MOUNTED) { if(std::filesystem::exists(mountString)) { sif::info << "SD card " << sdString << " already on and mounted at " << mountString << std::endl; return SdCardManager::ALREADY_MOUNTED; } - sif::error << "SD card mounted but expected mount point " << mountString << " not found!" - << std::endl; + sif::error << "SD card mounted but expected mount point " << + mountString << " not found!" << std::endl; return SdCardManager::MOUNT_ERROR; } + + if(status == sd::SdState::OFF) { + if(BLOCKING_SD_INIT) { + sif::info << "Switching on and mounting SD card " << sdString << " at " << + mountString << std::endl; + return sdcMan->switchOnSdCard(sdCard, true, &statusPair); + } + else { + if(state == SdStates::SET_STATE) { + sif::info << "Switching on SD card" << std::endl; + return sdcMan->switchOnSdCard(sdCard, false, &statusPair); + } + } + } + + else if(status == sd::SdState::ON) { + if(BLOCKING_SD_INIT) { + sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; + return sdcMan->mountSdCard(sdCard); + } + else { + if(state == SdStates::SET_STATE) { + return SdCardManager::ALREADY_ON; + } + if(state == SdStates::MOUNT) { + sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; + return sdcMan->mountSdCard(sdCard); + } + } + } + else { + sif::warning << "CoreController::sdCardSetup: Invalid state for this call" << std::endl; + } +return HasReturnvaluesIF::RETURN_OK; } + ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { switch(actionId) { @@ -166,16 +335,20 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ } ReturnValue_t CoreController::initializeAfterTaskCreation() { - + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; // TODO: Do this here because this can take a longer time. Later, use non-blocking mode // to start doing stuff in ctor and initialize function. // This operation can take 1-2 seconds on reboot, and around 50-100ms if the SD // card is already on. - ReturnValue_t result = initSdCard(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; + if(BLOCKING_SD_INIT) { + ReturnValue_t result = initSdCardBlocking(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; + } + } + else { + initSdCardNonBlocking(); } - result = initVersionFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; @@ -185,29 +358,15 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { } ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, - SdCardManager::SdStatusPair& statusPair) { - sd::SdCard preferredSdCard = sd::SdCard::SLOT_0; - ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); - if(result != HasReturnvaluesIF::RETURN_OK) { - if(result == scratch::KEY_NOT_FOUND) { - sif::warning << "CoreController::sdCardInit: " - "Preferred SD card not set. Setting to 0" << std::endl; - sdcMan->setPreferredSdCard(preferredSdCard); - } - else { - sif::warning << "CoreController::sdCardInit: Could not get preferred SD card" - "information from the scratch buffer" << std::endl; - } - } + SdCardManager::SdStatusPair& statusPair, SdStates step) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; std::string preferredString; - sd::SdStatus preferredStatus = sd::SdStatus::OFF; - sd::SdStatus otherStatus = sd::SdStatus::OFF; + sd::SdState otherStatus = sd::SdState::OFF; std::string otherString; sd::SdCard otherSdc = sd::SdCard::SLOT_0; if(preferredSdCard == sd::SdCard::SLOT_0) { - preferredStatus = statusPair.first; preferredString = "0"; otherSdc = sd::SdCard::SLOT_1; otherStatus = statusPair.second; @@ -215,25 +374,21 @@ ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, } else { preferredString = "1"; - preferredStatus = statusPair.second; otherStatus = statusPair.first; otherSdc = sd::SdCard::SLOT_0; otherString = "0"; } - sif::info << "Cold redundant SD card configuration, preferred SD card " << - preferredString << std::endl; - - result = sdCardSetup(*sdcMan, statusPair, preferredSdCard, preferredStatus, preferredString); + result = sdCardSetup(statusPair, preferredSdCard, preferredString); if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Setting up preferred card " << otherString << " in cold redundant mode failed" << std::endl; // Try other SD card and mark set up operation as failed - sdCardSetup(*sdcMan, statusPair, preferredSdCard, preferredStatus, preferredString); + sdCardSetup(statusPair, preferredSdCard, preferredString); result = HasReturnvaluesIF::RETURN_FAILED; } - if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdStatus::OFF) { + if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdState::OFF) { sif::info << "Switching off secondary SD card " << otherString << std::endl; // Switch off other SD card in cold redundant mode if setting up preferred one walked // without issues @@ -243,10 +398,7 @@ ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, " in cold redundant mode failed" << std::endl; } } - - // Update status file - sdcMan->updateSdCardStateFile(); - return HasReturnvaluesIF::RETURN_OK; + return result; } ReturnValue_t CoreController::incrementAllocationFailureCount() { @@ -501,6 +653,26 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si return HasActionsIF::EXECUTION_FINISHED; } +CoreController::~CoreController() { +} + +void CoreController::determinePreferredSdCard() { + if(preferredSdCard == sd::SdCard::NONE) { + ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); + if(result != HasReturnvaluesIF::RETURN_OK) { + if(result == scratch::KEY_NOT_FOUND) { + sif::warning << "CoreController::sdCardInit: " + "Preferred SD card not set. Setting to 0" << std::endl; + sdcMan->setPreferredSdCard(preferredSdCard); + } + else { + sif::warning << "CoreController::sdCardInit: Could not get preferred SD card" + "information from the scratch buffer" << std::endl; + } + } + } +} + void CoreController::performWatchdogControlOperation() { // Only perform each fifth iteration if(watchdogFifoFd != 0 and opDivider.checkAndIncrement()) { diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 4a71e6e7..a424a615 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -8,6 +8,8 @@ #include "events/subsystemIdRanges.h" +class Timer; +class SdCardManager; class CoreController: public ExtendedControllerBase { public: @@ -32,6 +34,7 @@ public: CoreController(object_id_t objectId); + virtual~ CoreController(); ReturnValue_t initialize() override; @@ -56,11 +59,32 @@ private: ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); - ReturnValue_t initSdCard(); - ReturnValue_t sdCardSetup(SdCardManager& sdcMan, SdCardManager::SdStatusPair& statusPair, - sd::SdCard sdCard, sd::SdStatus status, std::string sdString); + // States for non-blocking setup + enum class SdStates { + NONE, + START, + GET_INFO, + SET_STATE, + MOUNT, + UPDATE_INFO, + DONE + }; + static constexpr bool BLOCKING_SD_INIT = true; + + SdCardManager* sdcMan = nullptr; + uint16_t sdcInitCycleCount = 0; + ReturnValue_t initSdCardBlocking(); + ReturnValue_t initSdCardNonBlocking(); + sd::SdCard preferredSdCard = sd::SdCard::NONE; + SdStates state = SdStates::START; + SdCardManager::SdStatusPair statusPair; + bool commandExecuted = true; + bool sdInitFinished = false; + ReturnValue_t sdCardSetup(SdCardManager::SdStatusPair& statusPair, + sd::SdCard sdCard, std::string sdString); ReturnValue_t sdCardColdRedundantInit(SdCardManager* sdcMan, - SdCardManager::SdStatusPair& statusPair); + SdCardManager::SdStatusPair& statusPair, SdStates step = SdStates::NONE); + void determinePreferredSdCard(); ReturnValue_t initVersionFile(); ReturnValue_t initBootCopy(); diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 5a7895da..82891979 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -77,11 +77,11 @@ void FileSystemHandler::fileSystemCheckup() { sd::SdCard preferredSdCard; sdcMan->getPreferredSdCard(preferredSdCard); if((preferredSdCard == sd::SdCard::SLOT_0) and - (statusPair.first == sd::SdStatus::MOUNTED)) { + (statusPair.first == sd::SdState::MOUNTED)) { currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; } else if((preferredSdCard == sd::SdCard::SLOT_1) and - (statusPair.second == sd::SdStatus::MOUNTED)) { + (statusPair.second == sd::SdState::MOUNTED)) { currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT; } else { diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 932a4217..89cdf85f 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -1,3 +1,4 @@ +#include #include "SdCardManager.h" #include "scratchApi.h" @@ -52,39 +53,35 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar return HasReturnvaluesIF::RETURN_FAILED; } - sd::SdStatus targetStatus; + sd::SdState currentState; if(sdCard == sd::SdCard::SLOT_0) { - targetStatus = statusPair->first; + currentState = statusPair->first; } else if(sdCard == sd::SdCard::SLOT_1) { - targetStatus = statusPair->second; + currentState = statusPair->second; } else { // Should not happen - targetStatus = sd::SdStatus::OFF; + currentState = sd::SdState::OFF; } - auto switchCall = [&]() { - if(targetStatus == sd::SdStatus::ON) { - if(not doMountSdCard) { - return ALREADY_ON; - } - else { - return mountSdCard(sdCard); - } - } - else if(targetStatus == sd::SdStatus::MOUNTED) { - return ALREADY_MOUNTED; - } - else if(targetStatus == sd::SdStatus::OFF) { - return setSdCardState(sdCard, true); + if(currentState == sd::SdState::ON) { + if(not doMountSdCard) { + return ALREADY_ON; } else { - return HasReturnvaluesIF::RETURN_FAILED; + return mountSdCard(sdCard); } - }; - - result = switchCall(); + } + else if(currentState == sd::SdState::MOUNTED) { + result = ALREADY_MOUNTED; + } + else if(currentState == sd::SdState::OFF) { + result = setSdCardState(sdCard, true); + } + else { + result = HasReturnvaluesIF::RETURN_FAILED; + } if(result != HasReturnvaluesIF::RETURN_OK or not doMountSdCard) { return result; @@ -95,7 +92,7 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard, SdStatusPair* statusPair) { - std::pair active; + std::pair active; ReturnValue_t result = getSdCardActiveStatus(active); if(result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -107,12 +104,12 @@ ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSd return HasReturnvaluesIF::RETURN_FAILED; } if(sdCard == sd::SdCard::SLOT_0) { - if(active.first == sd::SdStatus::OFF) { + if(active.first == sd::SdState::OFF) { return ALREADY_OFF; } } else if(sdCard == sd::SdCard::SLOT_1) { - if(active.second == sd::SdStatus::OFF) { + if(active.second == sd::SdState::OFF) { return ALREADY_OFF; } } @@ -268,7 +265,7 @@ ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard getSdCardActiveStatus(*statusPair); } - if(statusPair->first == sd::SdStatus::ON) { + if(statusPair->first == sd::SdState::ON) { return mountSdCard(prefSdCard); } @@ -280,7 +277,7 @@ void SdCardManager::resetState() { currentOp = Operations::IDLE; } -void SdCardManager::processSdStatusLine(std::pair &active, +void SdCardManager::processSdStatusLine(std::pair &active, std::string& line, uint8_t& idx, sd::SdCard& currentSd) { using namespace std; istringstream iss(line); @@ -302,28 +299,28 @@ void SdCardManager::processSdStatusLine(std::pair &a if(word == "on") { if(currentSd == sd::SdCard::SLOT_0) { - active.first = sd::SdStatus::ON; + active.first = sd::SdState::ON; } else { - active.second = sd::SdStatus::ON; + active.second = sd::SdState::ON; } } else if (word == "off") { if(currentSd == sd::SdCard::SLOT_0) { - active.first = sd::SdStatus::OFF; + active.first = sd::SdState::OFF; } else { - active.second = sd::SdStatus::OFF; + active.second = sd::SdState::OFF; } } } if(mountLine) { if(currentSd == sd::SdCard::SLOT_0) { - active.first = sd::SdStatus::MOUNTED; + active.first = sd::SdState::MOUNTED; } else { - active.second = sd::SdStatus::MOUNTED; + active.second = sd::SdState::MOUNTED; } } @@ -389,8 +386,16 @@ SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { currentOp = this->currentOp; bool bytesRead = false; + Timer timer; + timer.setTimer(200); + uint32_t remainingTimeMs = 0; while(true) { ReturnValue_t result = cmdExecutor.check(bytesRead); + timer.getTimer(&remainingTimeMs); + if(remainingTimeMs == 0) { + sif::error << "SdCardManager::checkCurrentOp: Timeout!" << std::endl; + return OpStatus::FAIL; + } switch(result) { case(CommandExecutor::BYTES_READ): { continue; diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index a6d9227a..31dc740d 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -42,7 +42,7 @@ public: FAIL }; - using SdStatusPair = std::pair; + using SdStatusPair = std::pair; static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; @@ -197,7 +197,7 @@ public: private: CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; - bool blocking = true; + bool blocking = false; SdCardManager(); diff --git a/bsp_q7s/memory/definitions.h b/bsp_q7s/memory/definitions.h index 9fcbee08..9e0bca65 100644 --- a/bsp_q7s/memory/definitions.h +++ b/bsp_q7s/memory/definitions.h @@ -5,7 +5,7 @@ namespace sd { -enum SdStatus: uint8_t { +enum SdState: uint8_t { OFF = 0, ON = 1, // A mounted SD card is on as well diff --git a/fsfw b/fsfw index 42022051..6073abb1 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 4202205182aa007b9be5279ce40056e18f0b8782 +Subproject commit 6073abb12db23decbc9d69f4b6342f4f6f1247bd -- 2.43.0 From f0e282c6e1079048ce3e2527bca1b019a0d78126 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Aug 2021 18:37:14 +0200 Subject: [PATCH 094/116] continued a bit --- bsp_q7s/core/CoreController.cpp | 50 ++++++++++++++++++-------------- bsp_q7s/core/CoreController.h | 5 ++-- bsp_q7s/memory/SdCardManager.cpp | 7 ++++- fsfw | 2 +- linux/fsfwconfig/OBSWConfig.h.in | 4 +++ 5 files changed, 43 insertions(+), 25 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 0516e26f..4a01ca50 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -159,18 +159,18 @@ ReturnValue_t CoreController::initSdCardNonBlocking() { SdCardManager::Operations operation; SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); if(status == SdCardManager::OpStatus::SUCCESS) { - state = SdStates::SET_STATE; + state = SdStates::SET_STATE_SELF; commandExecuted = false; sdcInitCycleCount = 0; } - else if(sdcInitCycleCount > 2) { + else if(sdcInitCycleCount > 4) { sif::warning << "CoreController::initSdCardNonBlocking: " "Updating SDC file takes too long" << std::endl; } } } - if(state == SdStates::SET_STATE) { + if(state == SdStates::SET_STATE_SELF) { if(not commandExecuted) { determinePreferredSdCard(); statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); @@ -250,6 +250,7 @@ ReturnValue_t CoreController::initSdCardNonBlocking() { } } + sdcInitCycleCount++; return HasReturnvaluesIF::RETURN_OK; #endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ } @@ -290,7 +291,7 @@ ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPai return sdcMan->switchOnSdCard(sdCard, true, &statusPair); } else { - if(state == SdStates::SET_STATE) { + if(state == SdStates::SET_STATE_SELF) { sif::info << "Switching on SD card" << std::endl; return sdcMan->switchOnSdCard(sdCard, false, &statusPair); } @@ -303,7 +304,7 @@ ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPai return sdcMan->mountSdCard(sdCard); } else { - if(state == SdStates::SET_STATE) { + if(state == SdStates::SET_STATE_SELF) { return SdCardManager::ALREADY_ON; } if(state == SdStates::MOUNT) { @@ -379,25 +380,32 @@ ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, otherString = "0"; } - result = sdCardSetup(statusPair, preferredSdCard, preferredString); - if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Setting up preferred card " << otherString << - " in cold redundant mode failed" << std::endl; - // Try other SD card and mark set up operation as failed - sdCardSetup(statusPair, preferredSdCard, preferredString); - result = HasReturnvaluesIF::RETURN_FAILED; - } - - if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdState::OFF) { - sif::info << "Switching off secondary SD card " << otherString << std::endl; - // Switch off other SD card in cold redundant mode if setting up preferred one walked - // without issues - result = sdcMan->switchOffSdCard(otherSdc, otherStatus, &statusPair); - if(result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_OFF) { - sif::warning << "Switching off secondary SD card " << otherString << + if(step != SdStates::SET_STATE_OTHER) { + result = sdCardSetup(statusPair, preferredSdCard, preferredString); + if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Setting up preferred card " << otherString << " in cold redundant mode failed" << std::endl; + // Try other SD card and mark set up operation as failed + sdCardSetup(statusPair, preferredSdCard, preferredString); + result = HasReturnvaluesIF::RETURN_FAILED; } } + + if(BLOCKING_SD_INIT or (not BLOCKING_SD_INIT and state == SdStates::SET_STATE_OTHER)) { + // Don't disable other card if enabling the first one already failed + // Otherwise, try to turn off the other SD card + if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdState::OFF) { + sif::info << "Switching off secondary SD card " << otherString << std::endl; + // Switch off other SD card in cold redundant mode if setting up preferred one worked + // without issues + ReturnValue_t result2 = sdcMan->switchOffSdCard(otherSdc, otherStatus, &statusPair); + if(result2 != HasReturnvaluesIF::RETURN_OK and result2 != SdCardManager::ALREADY_OFF) { + sif::warning << "Switching off secondary SD card " << otherString << + " in cold redundant mode failed" << std::endl; + } + } + } + return result; } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index a424a615..a4f2868e 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -64,12 +64,13 @@ private: NONE, START, GET_INFO, - SET_STATE, + SET_STATE_SELF, + SET_STATE_OTHER, MOUNT, UPDATE_INFO, DONE }; - static constexpr bool BLOCKING_SD_INIT = true; + static constexpr bool BLOCKING_SD_INIT = false; SdCardManager* sdcMan = nullptr; uint16_t sdcInitCycleCount = 0; diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index 89cdf85f..d9442a8c 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -386,16 +386,21 @@ SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) { currentOp = this->currentOp; bool bytesRead = false; +#if OBSW_ENABLE_TIMERS == 1 Timer timer; - timer.setTimer(200); + timer.setTimer(100); uint32_t remainingTimeMs = 0; +#endif while(true) { ReturnValue_t result = cmdExecutor.check(bytesRead); + // This timer can prevent deadlocks due to missconfigurations +#if OBSW_ENABLE_TIMERS == 1 timer.getTimer(&remainingTimeMs); if(remainingTimeMs == 0) { sif::error << "SdCardManager::checkCurrentOp: Timeout!" << std::endl; return OpStatus::FAIL; } +#endif switch(result) { case(CommandExecutor::BYTES_READ): { continue; diff --git a/fsfw b/fsfw index 6073abb1..3704d2b8 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 6073abb12db23decbc9d69f4b6342f4f6f1247bd +Subproject commit 3704d2b8295152652a4c7836b595223d8fa3767d diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 778a1611..0246ff82 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -22,6 +22,10 @@ debugging. */ #define OBSW_VERBOSE_LEVEL 1 +//! Timers can mess up the code when debugging +//! TODO: Enable for mission code, disable for debug code +#define OBSW_ENABLE_TIMERS 0 + #define OBSW_PRINT_MISSED_DEADLINES 1 #define OBSW_ADD_TEST_CODE 1 #define OBSW_ADD_TEST_PST 1 -- 2.43.0 From 2fb54f7de9e2c85377aaf35161da5398d95ccee4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 6 Aug 2021 01:25:36 +0200 Subject: [PATCH 095/116] first successfull tests --- bsp_q7s/core/CoreController.cpp | 391 ++++++++++++++++----------- bsp_q7s/core/CoreController.h | 39 ++- bsp_q7s/memory/FileSystemHandler.cpp | 11 +- bsp_q7s/memory/FileSystemHandler.h | 3 + bsp_q7s/memory/SdCardManager.cpp | 47 +++- bsp_q7s/memory/SdCardManager.h | 14 +- 6 files changed, 308 insertions(+), 197 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 4a01ca50..cf99a8e9 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -39,7 +39,8 @@ CoreController::CoreController(object_id_t objectId): sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; } if(not BLOCKING_SD_INIT) { - initSdCardNonBlocking(); + sdInitStateMachine(); + sdcMan->setBlocking(false); } result = initBootCopy(); @@ -58,8 +59,8 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - if(not BLOCKING_SD_INIT and not sdInitFinished) { - initSdCardNonBlocking(); + if(not BLOCKING_SD_INIT and not sdInfo.initFinished) { + sdInitStateMachine(); } performWatchdogControlOperation(); } @@ -83,7 +84,7 @@ ReturnValue_t CoreController::initialize() { } if(not BLOCKING_SD_INIT) { - initSdCardNonBlocking(); + sdInitStateMachine(); } return ExtendedControllerBase::initialize(); @@ -106,17 +107,17 @@ ReturnValue_t CoreController::initSdCardBlocking() { << std::endl; } - auto statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); - result = sdcMan->getSdCardActiveStatus(statusPair); + result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT determinePreferredSdCard(); + updateSdInfoOther(); sif::info << "Cold redundant SD card configuration, preferred SD card: " << - static_cast(preferredSdCard) << std::endl; - result = sdCardColdRedundantInit(sdcMan, statusPair); + static_cast(sdInfo.pref) << std::endl; + result = sdColdRedundantBlockingInit(); // Update status file sdcMan->updateSdCardStateFile(); return result; @@ -133,131 +134,193 @@ ReturnValue_t CoreController::initSdCardBlocking() { } -ReturnValue_t CoreController::initSdCardNonBlocking() { +ReturnValue_t CoreController::sdInitStateMachine() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE sif::info << "No SD card initialization will be performed" << std::endl; return HasReturnvaluesIF::RETURN_OK; #else ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - if(state == SdStates::START) { - sdcInitCycleCount = 0; - commandExecuted = false; - state = SdStates::GET_INFO; + SdCardManager::Operations operation; + + auto nonBlockingOpChecking = [&](SdStates newStateOnSuccess, + uint16_t maxCycleCount, std::string opPrintout) { + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + sif::debug << "op success" << std::endl; + sdInfo.state = newStateOnSuccess; + sdInfo.commandExecuted = false; + sdInfo.cycleCount = 0; + } + else if(sdInfo.cycleCount > 4) { + sif::warning << "CoreController::sdInitStateMachine: " << opPrintout << + " takes too long" << std::endl; + } + }; + + if(sdInfo.state == SdStates::START) { + sdInfo.cycleCount = 0; + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::GET_INFO; } - if(state == SdStates::GET_INFO) { - if(not commandExecuted) { + if(sdInfo.state == SdStates::GET_INFO) { + + if(not sdInfo.commandExecuted) { + sif::debug << "Getting info.." << std::endl; // Create update status file result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl; } - commandExecuted = true; + sdInfo.commandExecuted = true; } else { - SdCardManager::Operations operation; - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - state = SdStates::SET_STATE_SELF; - commandExecuted = false; - sdcInitCycleCount = 0; - } - else if(sdcInitCycleCount > 4) { - sif::warning << "CoreController::initSdCardNonBlocking: " - "Updating SDC file takes too long" << std::endl; - } + nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file"); } } - if(state == SdStates::SET_STATE_SELF) { - if(not commandExecuted) { + if(sdInfo.state == SdStates::SET_STATE_SELF) { + if(not sdInfo.commandExecuted) { + sif::debug << "Set self state" << std::endl; + result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); determinePreferredSdCard(); - statusPair = SdCardManager::SdStatusPair(sd::SdState::OFF, sd::SdState::OFF); - result = sdcMan->getSdCardActiveStatus(statusPair); + updateSdInfoOther(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } sif::info << "Cold redundant SD card configuration, preferred SD card: " << - static_cast(preferredSdCard) << std::endl; - result = sdCardColdRedundantInit(sdcMan, statusPair); - if(result == SdCardManager::ALREADY_ON) { - state = SdStates::MOUNT; + static_cast(sdInfo.pref) << std::endl; + if(sdInfo.prefState == sd::SdState::MOUNTED) { + sdInfo.state = SdStates::DETERMINE_OTHER; } - if(result == SdCardManager::ALREADY_MOUNTED) { - state = SdStates::UPDATE_INFO; + else if(sdInfo.prefState == sd::SdState::OFF) { + sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + sdInfo.commandExecuted = true; } - else { - commandExecuted = true; + else if(sdInfo.prefState == sd::SdState::ON) { + sdInfo.state = SdStates::MOUNT_SELF; } } else { - SdCardManager::Operations operation; - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - state = SdStates::MOUNT; - commandExecuted = false; - sdcInitCycleCount = 0; - } - else if(sdcInitCycleCount > 10) { - sif::warning << "CoreController::initSdCardNonBlocking: " - "Setting SDC state takes too long" << std::endl; - } + nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state"); } } - if(state == SdStates::MOUNT) { - if(not commandExecuted) { - result = sdCardColdRedundantInit(sdcMan, statusPair); - commandExecuted = false; + if(sdInfo.state == SdStates::MOUNT_SELF) { + if(not sdInfo.commandExecuted) { + sif::debug << "Mount self" << std::endl; + result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + sdInfo.commandExecuted = true; } else { - SdCardManager::Operations operation; - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - state = SdStates::UPDATE_INFO; - commandExecuted = false; - sdcInitCycleCount = 0; - } - else if(sdcInitCycleCount > 5) { - sif::warning << "CoreController::initSdCardNonBlocking: " - "Mounting SD card takes too long" << std::endl; - } + nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card"); } } - if(state == SdStates::UPDATE_INFO) { - if(not commandExecuted) { + if(sdInfo.state == SdStates::DETERMINE_OTHER) { + // Determine whether any additional operations have to be done for the other SD card + // 1. Cold redundant case: Other SD card needs to be unmounted and switched off + // 2. Hot redundant case: Other SD card needs to be mounted and switched on +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT + if(sdInfo.otherState == sd::SdState::ON) { + sdInfo.state = SdStates::SET_STATE_OTHER; + } + else if(sdInfo.otherState == sd::SdState::MOUNTED) { + sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; + } + else { + // Is already off, update info + sdInfo.state = SdStates::UPDATE_INFO; + } +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + if(sdInfo.otherState == sd::SdState::OFF) { + sdInfo.state = SdStates::SET_STATE_OTHER; + } + else if(sdInfo.otherState == sd::SdState::ON) { + sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; + } + else { + // Is already on and mounted, update info + sdInfo.state = SdStates::UPDATE_INFO; + } +#endif + } + + if(sdInfo.state == SdStates::SET_STATE_OTHER) { + // Set state of other SD card to ON or OFF, depending on redundancy mode +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT + if(not sdInfo.commandExecuted) { + sif::debug << "Set state other off" << std::endl; + result = sdCardSetup(sdInfo.pref, sd::SdState::OFF, sdInfo.prefChar); + sdInfo.commandExecuted = true; + } +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + if(not sdInfo.commandExecuted) { + sif::debug << "Set state other on" << std::endl; + result = sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + sdInfo.commandExecuted = true; + } +#endif + else { + nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, "Switching off other SD card"); + } + } + + if(sdInfo.state == SdStates::MOUNT_UNMOUNT_OTHER) { + // Mount or unmount other SD card, depending on redundancy mode +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT + if(not sdInfo.commandExecuted) { + sif::debug << "Unmount other" << std::endl; + result = sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + sdInfo.commandExecuted = true; + } +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + if(not sdInfo.commandExecuted) { + result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + sdInfo.commandExecuted = true; + } +#endif + else { +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT + std::string opPrint = "Switching off other SD card"; +#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT + std::string opPrint = "Mounting other SD card"; +#endif + nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, opPrint); + } + } + + if(sdInfo.state == SdStates::UPDATE_INFO) { + if(not sdInfo.commandExecuted) { + sif::debug << "update info" << std::endl; + // It is assumed that all tasks are running by the point this section is reached. + // Therefore, perform this operation in blocking mode because it does not take long + // and the ready state of the SD card is available sooner + sdcMan->setBlocking(true); // Update status file result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl; } - commandExecuted = true; - } - else { - SdCardManager::Operations operation; - SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); - if(status == SdCardManager::OpStatus::SUCCESS) { - sdInitFinished = true; - state = SdStates::DONE; - } - else if(sdcInitCycleCount > 2) { - sif::warning << "CoreController::initSdCardNonBlocking: " - "Updating SDC file takes too long" << std::endl; - } + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::DONE; + sdInfo.initFinished = true; + sdInfo.cycleCount = 0; + sdcMan->setBlocking(false); + sif::debug << "Sd init done" << std::endl; } } - sdcInitCycleCount++; + sdInfo.cycleCount++; return HasReturnvaluesIF::RETURN_OK; #endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ } -ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPair, - sd::SdCard sdCard, std::string sdString) { +ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, + std::string sdChar) { std::string mountString; if(sdCard == sd::SdCard::SLOT_0) { mountString = SdCardManager::SD_0_MOUNT_POINT; @@ -266,51 +329,54 @@ ReturnValue_t CoreController::sdCardSetup(SdCardManager::SdStatusPair& statusPai mountString = SdCardManager::SD_1_MOUNT_POINT; } - sd::SdState status = sd::SdState::OFF; + sd::SdState state = sd::SdState::OFF; if(sdCard == sd::SdCard::SLOT_0) { - status = statusPair.first; + state = sdInfo.currentState.first; } else { - status = statusPair.second; + state = sdInfo.currentState.second; } - if(status == sd::SdState::MOUNTED) { - if(std::filesystem::exists(mountString)) { - sif::info << "SD card " << sdString << " already on and mounted at " << - mountString << std::endl; - return SdCardManager::ALREADY_MOUNTED; + if(state == sd::SdState::MOUNTED) { + if(targetState == sd::SdState::OFF) { + sif::info << "Switching off SD card" << sdChar << std::endl; + return sdcMan->switchOffSdCard(sdCard, true, &sdInfo.currentState); } - sif::error << "SD card mounted but expected mount point " << - mountString << " not found!" << std::endl; - return SdCardManager::MOUNT_ERROR; - } - - if(status == sd::SdState::OFF) { - if(BLOCKING_SD_INIT) { - sif::info << "Switching on and mounting SD card " << sdString << " at " << - mountString << std::endl; - return sdcMan->switchOnSdCard(sdCard, true, &statusPair); + else if(targetState == sd::SdState::ON) { + sif::info << "Unmounting SD card " << sdChar << std::endl; + return sdcMan->unmountSdCard(sdCard); } else { - if(state == SdStates::SET_STATE_SELF) { - sif::info << "Switching on SD card" << std::endl; - return sdcMan->switchOnSdCard(sdCard, false, &statusPair); + if(std::filesystem::exists(mountString)) { + sif::info << "SD card " << sdChar << " already on and mounted at " << + mountString << std::endl; + return SdCardManager::ALREADY_MOUNTED; } + sif::error << "SD card mounted but expected mount point " << + mountString << " not found!" << std::endl; + return SdCardManager::MOUNT_ERROR; } } - else if(status == sd::SdState::ON) { - if(BLOCKING_SD_INIT) { - sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; + if(state == sd::SdState::OFF) { + if(targetState == sd::SdState::MOUNTED) { + sif::info << "Switching on and mounting SD card " << sdChar << " at " << + mountString << std::endl; + return sdcMan->switchOnSdCard(sdCard, true, &sdInfo.currentState); + } + else if(targetState == sd::SdState::ON) { + sif::info << "Switching on SD card" << sdChar << std::endl; + return sdcMan->switchOnSdCard(sdCard, false, &sdInfo.currentState); + } + } + + else if(state == sd::SdState::ON) { + if(targetState == sd::SdState::MOUNTED) { + sif::info << "Mounting SD card " << sdChar << " at " << mountString << std::endl; return sdcMan->mountSdCard(sdCard); } - else { - if(state == SdStates::SET_STATE_SELF) { - return SdCardManager::ALREADY_ON; - } - if(state == SdStates::MOUNT) { - sif::info << "Mounting SD card " << sdString << " at " << mountString << std::endl; - return sdcMan->mountSdCard(sdCard); - } + else if(targetState == sd::SdState::OFF) { + sif::info << "Switching off SD card" << sdChar << std::endl; + return sdcMan->switchOffSdCard(sdCard, false, &sdInfo.currentState); } } else { @@ -337,18 +403,16 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ ReturnValue_t CoreController::initializeAfterTaskCreation() { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - // TODO: Do this here because this can take a longer time. Later, use non-blocking mode - // to start doing stuff in ctor and initialize function. - // This operation can take 1-2 seconds on reboot, and around 50-100ms if the SD - // card is already on. if(BLOCKING_SD_INIT) { ReturnValue_t result = initSdCardBlocking(); - if(result != HasReturnvaluesIF::RETURN_OK) { + if(result != HasReturnvaluesIF::RETURN_OK and result != SdCardManager::ALREADY_MOUNTED) { sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; } } else { - initSdCardNonBlocking(); + if(not sdInfo.initFinished) { + sdInitStateMachine(); + } } result = initVersionFile(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -358,54 +422,29 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { return result; } -ReturnValue_t CoreController::sdCardColdRedundantInit(SdCardManager* sdcMan, - SdCardManager::SdStatusPair& statusPair, SdStates step) { +ReturnValue_t CoreController::sdColdRedundantBlockingInit() { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - std::string preferredString; - sd::SdState otherStatus = sd::SdState::OFF; - std::string otherString; - sd::SdCard otherSdc = sd::SdCard::SLOT_0; - - if(preferredSdCard == sd::SdCard::SLOT_0) { - preferredString = "0"; - otherSdc = sd::SdCard::SLOT_1; - otherStatus = statusPair.second; - otherString = "1"; - } - else { - preferredString = "1"; - otherStatus = statusPair.first; - otherSdc = sd::SdCard::SLOT_0; - otherString = "0"; + result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Setting up preferred card " << sdInfo.otherChar << + " in cold redundant mode failed" << std::endl; + // Try other SD card and mark set up operation as failed + sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + result = HasReturnvaluesIF::RETURN_FAILED; } - if(step != SdStates::SET_STATE_OTHER) { - result = sdCardSetup(statusPair, preferredSdCard, preferredString); - if(result != SdCardManager::ALREADY_MOUNTED and result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "Setting up preferred card " << otherString << + if(result != HasReturnvaluesIF::RETURN_FAILED and sdInfo.otherState != sd::SdState::OFF) { + sif::info << "Switching off secondary SD card " << sdInfo.otherChar << std::endl; + // Switch off other SD card in cold redundant mode if setting up preferred one worked + // without issues + ReturnValue_t result2 = sdcMan->switchOffSdCard(sdInfo.other, + sdInfo.otherState, &sdInfo.currentState); + if(result2 != HasReturnvaluesIF::RETURN_OK and result2 != SdCardManager::ALREADY_OFF) { + sif::warning << "Switching off secondary SD card " << sdInfo.otherChar << " in cold redundant mode failed" << std::endl; - // Try other SD card and mark set up operation as failed - sdCardSetup(statusPair, preferredSdCard, preferredString); - result = HasReturnvaluesIF::RETURN_FAILED; } } - - if(BLOCKING_SD_INIT or (not BLOCKING_SD_INIT and state == SdStates::SET_STATE_OTHER)) { - // Don't disable other card if enabling the first one already failed - // Otherwise, try to turn off the other SD card - if(result != HasReturnvaluesIF::RETURN_FAILED and otherStatus != sd::SdState::OFF) { - sif::info << "Switching off secondary SD card " << otherString << std::endl; - // Switch off other SD card in cold redundant mode if setting up preferred one worked - // without issues - ReturnValue_t result2 = sdcMan->switchOffSdCard(otherSdc, otherStatus, &statusPair); - if(result2 != HasReturnvaluesIF::RETURN_OK and result2 != SdCardManager::ALREADY_OFF) { - sif::warning << "Switching off secondary SD card " << otherString << - " in cold redundant mode failed" << std::endl; - } - } - } - return result; } @@ -665,13 +704,13 @@ CoreController::~CoreController() { } void CoreController::determinePreferredSdCard() { - if(preferredSdCard == sd::SdCard::NONE) { - ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); + if(sdInfo.pref == sd::SdCard::NONE) { + ReturnValue_t result = sdcMan->getPreferredSdCard(sdInfo.pref); if(result != HasReturnvaluesIF::RETURN_OK) { if(result == scratch::KEY_NOT_FOUND) { sif::warning << "CoreController::sdCardInit: " "Preferred SD card not set. Setting to 0" << std::endl; - sdcMan->setPreferredSdCard(preferredSdCard); + sdcMan->setPreferredSdCard(sdInfo.pref); } else { sif::warning << "CoreController::sdCardInit: Could not get preferred SD card" @@ -681,6 +720,28 @@ void CoreController::determinePreferredSdCard() { } } +void CoreController::updateSdInfoOther() { + if(sdInfo.pref == sd::SdCard::SLOT_0) { + sdInfo.prefChar = "0"; + sdInfo.otherChar = "1"; + sdInfo.otherState = sdInfo.currentState.second; + sdInfo.prefState = sdInfo.currentState.first; + sdInfo.other = sd::SdCard::SLOT_1; + + } + else { + sdInfo.prefChar = "1"; + sdInfo.otherChar = "0"; + sdInfo.otherState = sdInfo.currentState.first; + sdInfo.prefState = sdInfo.currentState.second; + sdInfo.other = sd::SdCard::SLOT_0; + } +} + +bool CoreController::sdInitFinished() const { + return sdInfo.initFinished; +} + void CoreController::performWatchdogControlOperation() { // Only perform each fifth iteration if(watchdogFifoFd != 0 and opDivider.checkAndIncrement()) { diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index a4f2868e..1dec1f36 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -48,6 +48,7 @@ public: static ReturnValue_t incrementAllocationFailureCount(); static void getCurrentBootCopy(Chip& chip, Copy& copy); + bool sdInitFinished() const; private: static Chip currentChip; @@ -65,26 +66,40 @@ private: START, GET_INFO, SET_STATE_SELF, + MOUNT_SELF, + DETERMINE_OTHER, SET_STATE_OTHER, - MOUNT, + // Mount or unmount other + MOUNT_UNMOUNT_OTHER, UPDATE_INFO, DONE }; static constexpr bool BLOCKING_SD_INIT = false; SdCardManager* sdcMan = nullptr; - uint16_t sdcInitCycleCount = 0; + ReturnValue_t initSdCardBlocking(); - ReturnValue_t initSdCardNonBlocking(); - sd::SdCard preferredSdCard = sd::SdCard::NONE; - SdStates state = SdStates::START; - SdCardManager::SdStatusPair statusPair; - bool commandExecuted = true; - bool sdInitFinished = false; - ReturnValue_t sdCardSetup(SdCardManager::SdStatusPair& statusPair, - sd::SdCard sdCard, std::string sdString); - ReturnValue_t sdCardColdRedundantInit(SdCardManager* sdcMan, - SdCardManager::SdStatusPair& statusPair, SdStates step = SdStates::NONE); + ReturnValue_t sdInitStateMachine(); + + struct SdInfo { + sd::SdCard pref = sd::SdCard::NONE; + sd::SdState prefState = sd::SdState::OFF; + sd::SdCard other = sd::SdCard::NONE; + sd::SdState otherState = sd::SdState::OFF; + std::string prefChar = "0"; + std::string otherChar = "1"; + SdStates state = SdStates::START; + bool commandExecuted = true; + bool initFinished = false; + SdCardManager::SdStatePair currentState; + uint16_t cycleCount = 0; + }; + + SdInfo sdInfo; + + void updateSdInfoOther(); + ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar); + ReturnValue_t sdColdRedundantBlockingInit(); void determinePreferredSdCard(); ReturnValue_t initVersionFile(); diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 82891979..ad8ec137 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -41,7 +41,9 @@ void FileSystemHandler::fileSystemHandlerLoop() { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; while(true) { if(opCounter % 5 == 0) { - fileSystemCheckup(); + if(coreCtrl->sdInitFinished()) { + fileSystemCheckup(); + } } result = mq->receiveMessage(&filemsg); if(result == MessageQueueIF::EMPTY) { @@ -72,7 +74,7 @@ void FileSystemHandler::fileSystemHandlerLoop() { } void FileSystemHandler::fileSystemCheckup() { - SdCardManager::SdStatusPair statusPair; + SdCardManager::SdStatePair statusPair; sdcMan->getSdCardActiveStatus(statusPair); sd::SdCard preferredSdCard; sdcMan->getPreferredSdCard(preferredSdCard); @@ -111,6 +113,11 @@ MessageQueueId_t FileSystemHandler::getCommandQueue() const { } ReturnValue_t FileSystemHandler::initialize() { + coreCtrl = ObjectManager::instance()->get(objects::CORE_CONTROLLER); + if(coreCtrl == nullptr) { + sif::error << "FileSystemHandler::initialize: Could not retrieve core controller handle" << + std::endl; + } sdcMan = SdCardManager::instance(); sd::SdCard preferredSdCard; ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard); diff --git a/bsp_q7s/memory/FileSystemHandler.h b/bsp_q7s/memory/FileSystemHandler.h index 22a7e7ae..1ff5d7c9 100644 --- a/bsp_q7s/memory/FileSystemHandler.h +++ b/bsp_q7s/memory/FileSystemHandler.h @@ -11,6 +11,8 @@ #include +class CoreController; + class FileSystemHandler: public SystemObject, public ExecutableObjectIF, public HasFileSystemIF { @@ -47,6 +49,7 @@ public: void* args = nullptr) override; private: + CoreController* coreCtrl = nullptr; MessageQueueIF* mq = nullptr; std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE; diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index d9442a8c..f203cb29 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -34,11 +34,18 @@ SdCardManager* SdCardManager::instance() { } ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard, - SdStatusPair* statusPair) { + SdStatePair* statusPair) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - std::unique_ptr sdStatusPtr; + if(doMountSdCard) { + if(not blocking) { + sif::warning << "SdCardManager::switchOnSdCard: Two-step command but manager is" + " not configured for blocking operation. Forcing blocking mode.." << std::endl; + blocking = true; + } + } + std::unique_ptr sdStatusPtr; if(statusPair == nullptr) { - sdStatusPtr = std::make_unique(); + sdStatusPtr = std::make_unique(); statusPair = sdStatusPtr.get(); result = getSdCardActiveStatus(*statusPair); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -91,12 +98,19 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar } ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard, - SdStatusPair* statusPair) { + SdStatePair* statusPair) { std::pair active; ReturnValue_t result = getSdCardActiveStatus(active); if(result != HasReturnvaluesIF::RETURN_OK) { return result; } + if(doUnmountSdCard) { + if(not blocking) { + sif::warning << "SdCardManager::switchOffSdCard: Two-step command but manager is" + " not configured for blocking operation. Forcing blocking mode.." << std::endl; + blocking = true; + } + } // Not allowed, this function turns off one SD card if(sdCard == sd::SdCard::BOTH) { sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH" @@ -155,7 +169,7 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { return result; } -ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatusPair& active) { +ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatePair& active) { using namespace std; if(not filesystem::exists(SD_STATE_FILE)) { return STATUS_FILE_NEXISTS; @@ -253,23 +267,34 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { return result; } -ReturnValue_t SdCardManager::sanitizeState(SdStatusPair* statusPair, sd::SdCard prefSdCard) { - std::unique_ptr sdStatusPtr; +ReturnValue_t SdCardManager::sanitizeState(SdStatePair* statusPair, sd::SdCard prefSdCard) { + std::unique_ptr sdStatusPtr; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; + // Enforce blocking operation for now. Be careful to reset it when returning prematurely! + bool resetNonBlockingState = false; + if(not this->blocking) { + blocking = true; + resetNonBlockingState = true; + } if(prefSdCard == sd::SdCard::NONE) { - ReturnValue_t result = getPreferredSdCard(prefSdCard); + result = getPreferredSdCard(prefSdCard); if(result != HasReturnvaluesIF::RETURN_OK) {} } if(statusPair == nullptr) { - sdStatusPtr = std::make_unique(); + sdStatusPtr = std::make_unique(); statusPair = sdStatusPtr.get(); getSdCardActiveStatus(*statusPair); } if(statusPair->first == sd::SdState::ON) { - return mountSdCard(prefSdCard); + result = mountSdCard(prefSdCard); } - return switchOnSdCard(prefSdCard, true, statusPair); + result = switchOnSdCard(prefSdCard, true, statusPair); + if(resetNonBlockingState) { + blocking = false; + } + return result; } void SdCardManager::resetState() { diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 31dc740d..96192575 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -42,7 +42,7 @@ public: FAIL }; - using SdStatusPair = std::pair; + using SdStatePair = std::pair; static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER; @@ -114,7 +114,7 @@ public: * SYSTEM_CALL_ERROR on system error */ ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true, - SdStatusPair* statusPair = nullptr); + SdStatePair* statusPair = nullptr); /** * Switch off the specified SD card. @@ -126,7 +126,7 @@ public: * SYSTEM_CALL_ERROR on system error */ ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true, - SdStatusPair* statusPair = nullptr); + SdStatePair* statusPair = nullptr); /** * Update the state file or creates one if it does not exist. You need to call this @@ -149,7 +149,7 @@ public: * should call #updateSdCardStateFile again in that case * - STATUS_FILE_NEXISTS if the status file does not exist */ - ReturnValue_t getSdCardActiveStatus(SdStatusPair& active); + ReturnValue_t getSdCardActiveStatus(SdStatePair& active); /** * Mount the specified SD card. This is necessary to use it. @@ -169,13 +169,13 @@ public: * In case that there is a discrepancy between the preferred SD card and the currently * mounted one, this function will sanitize the state by attempting to mount the * currently preferred SD card. If the caller already has state information, it can be - * passed into the function. + * passed into the function. For now, this operation will be enforced in blocking mode. * @param statusPair Current SD card status capture with #getSdCardActiveStatus * @param prefSdCard Preferred SD card captured with #getPreferredSdCard * @throws std::bad_alloc if one of the two arguments was a nullptr and an allocation failed * @return */ - ReturnValue_t sanitizeState(SdStatusPair* statusPair = nullptr, + ReturnValue_t sanitizeState(SdStatePair* statusPair = nullptr, sd::SdCard prefSdCard = sd::SdCard::NONE); /** @@ -203,7 +203,7 @@ private: ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on); - void processSdStatusLine(SdStatusPair& active, std::string& line, uint8_t& idx, + void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx, sd::SdCard& currentSd); std::string currentPrefix; -- 2.43.0 From e186bff4e48b3d18492a8d2aa0be5ccc86c8b2b0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 7 Aug 2021 18:52:36 +0200 Subject: [PATCH 096/116] important bugfixes for core controller --- bsp_q7s/core/CoreController.cpp | 37 ++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index cf99a8e9..00179b24 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -224,9 +224,11 @@ ReturnValue_t CoreController::sdInitStateMachine() { // 2. Hot redundant case: Other SD card needs to be mounted and switched on #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(sdInfo.otherState == sd::SdState::ON) { + sif::debug << "Determine: Setting other state off" << std::endl; sdInfo.state = SdStates::SET_STATE_OTHER; } else if(sdInfo.otherState == sd::SdState::MOUNTED) { + sif::debug << "Determine: Unmounting other" << std::endl; sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { @@ -235,9 +237,11 @@ ReturnValue_t CoreController::sdInitStateMachine() { } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(sdInfo.otherState == sd::SdState::OFF) { + sif::debug << "Determine: Setting other state on" << std::endl; sdInfo.state = SdStates::SET_STATE_OTHER; } else if(sdInfo.otherState == sd::SdState::ON) { + sif::debug << "Determine: Mounting other" << std::endl; sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { @@ -252,19 +256,24 @@ ReturnValue_t CoreController::sdInitStateMachine() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(not sdInfo.commandExecuted) { sif::debug << "Set state other off" << std::endl; - result = sdCardSetup(sdInfo.pref, sd::SdState::OFF, sdInfo.prefChar); + result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar); sdInfo.commandExecuted = true; } + else { + nonBlockingOpChecking(SdStates::UPDATE_INFO, 10, "Switching off other SD card"); + } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { sif::debug << "Set state other on" << std::endl; - result = sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); sdInfo.commandExecuted = true; } -#endif else { - nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, "Switching off other SD card"); + nonBlockingOpChecking(SdStates::SdStates::MOUNT_UNMOUNT_OTHER, 10, + "Switching on other SD card"); } +#endif + } if(sdInfo.state == SdStates::MOUNT_UNMOUNT_OTHER) { @@ -272,23 +281,21 @@ ReturnValue_t CoreController::sdInitStateMachine() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(not sdInfo.commandExecuted) { sif::debug << "Unmount other" << std::endl; - result = sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); sdInfo.commandExecuted = true; } + else { + nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card"); + } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { - result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); + result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar); sdInfo.commandExecuted = true; } -#endif else { -#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT - std::string opPrint = "Switching off other SD card"; -#elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT - std::string opPrint = "Mounting other SD card"; -#endif - nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, opPrint); + nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card"); } +#endif } if(sdInfo.state == SdStates::UPDATE_INFO) { @@ -338,7 +345,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS } if(state == sd::SdState::MOUNTED) { if(targetState == sd::SdState::OFF) { - sif::info << "Switching off SD card" << sdChar << std::endl; + sif::info << "Switching off SD card " << sdChar << std::endl; return sdcMan->switchOffSdCard(sdCard, true, &sdInfo.currentState); } else if(targetState == sd::SdState::ON) { @@ -375,7 +382,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS return sdcMan->mountSdCard(sdCard); } else if(targetState == sd::SdState::OFF) { - sif::info << "Switching off SD card" << sdChar << std::endl; + sif::info << "Switching off SD card " << sdChar << std::endl; return sdcMan->switchOffSdCard(sdCard, false, &sdInfo.currentState); } } -- 2.43.0 From 5a4d287f676b140a5928fc27db59e3a801e9dda6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 00:11:21 +0200 Subject: [PATCH 097/116] more testing and bugfixes --- bsp_q7s/core/CoreController.cpp | 57 ++++++++++++++++++++------------ bsp_q7s/core/CoreController.h | 5 +-- bsp_q7s/memory/SdCardManager.cpp | 16 ++++++--- bsp_q7s/memory/SdCardManager.h | 2 ++ 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 00179b24..cb705930 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -39,7 +39,7 @@ CoreController::CoreController(object_id_t objectId): sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; } if(not BLOCKING_SD_INIT) { - sdInitStateMachine(); + sdStateMachine(); sdcMan->setBlocking(false); } @@ -60,7 +60,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { void CoreController::performControlOperation() { if(not BLOCKING_SD_INIT and not sdInfo.initFinished) { - sdInitStateMachine(); + sdStateMachine(); } performWatchdogControlOperation(); } @@ -84,7 +84,7 @@ ReturnValue_t CoreController::initialize() { } if(not BLOCKING_SD_INIT) { - sdInitStateMachine(); + sdStateMachine(); } return ExtendedControllerBase::initialize(); @@ -134,7 +134,7 @@ ReturnValue_t CoreController::initSdCardBlocking() { } -ReturnValue_t CoreController::sdInitStateMachine() { +ReturnValue_t CoreController::sdStateMachine() { #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE sif::info << "No SD card initialization will be performed" << std::endl; return HasReturnvaluesIF::RETURN_OK; @@ -146,7 +146,6 @@ ReturnValue_t CoreController::sdInitStateMachine() { uint16_t maxCycleCount, std::string opPrintout) { SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); if(status == SdCardManager::OpStatus::SUCCESS) { - sif::debug << "op success" << std::endl; sdInfo.state = newStateOnSuccess; sdInfo.commandExecuted = false; sdInfo.cycleCount = 0; @@ -157,6 +156,15 @@ ReturnValue_t CoreController::sdInitStateMachine() { } }; + auto currentStateSetter = [&](sd::SdCard sdCard, sd::SdState newState) { + if(sdCard == sd::SdCard::SLOT_0) { + sdInfo.currentState.first = newState; + } + else { + sdInfo.currentState.second = newState; + } + }; + if(sdInfo.state == SdStates::START) { sdInfo.cycleCount = 0; sdInfo.commandExecuted = false; @@ -164,9 +172,7 @@ ReturnValue_t CoreController::sdInitStateMachine() { } if(sdInfo.state == SdStates::GET_INFO) { - if(not sdInfo.commandExecuted) { - sif::debug << "Getting info.." << std::endl; // Create update status file result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -182,20 +188,21 @@ ReturnValue_t CoreController::sdInitStateMachine() { if(sdInfo.state == SdStates::SET_STATE_SELF) { if(not sdInfo.commandExecuted) { - sif::debug << "Set self state" << std::endl; result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); determinePreferredSdCard(); updateSdInfoOther(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "Getting SD card activity status failed" << std::endl; } +#if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT sif::info << "Cold redundant SD card configuration, preferred SD card: " << static_cast(sdInfo.pref) << std::endl; +#endif if(sdInfo.prefState == sd::SdState::MOUNTED) { sdInfo.state = SdStates::DETERMINE_OTHER; } else if(sdInfo.prefState == sd::SdState::OFF) { - sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar); + sdCardSetup(sdInfo.pref, sd::SdState::ON, sdInfo.prefChar, false); sdInfo.commandExecuted = true; } else if(sdInfo.prefState == sd::SdState::ON) { @@ -204,17 +211,20 @@ ReturnValue_t CoreController::sdInitStateMachine() { } else { nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state"); + sdInfo.prefState = sd::SdState::ON; + currentStateSetter(sdInfo.pref, sd::SdState::ON); } } if(sdInfo.state == SdStates::MOUNT_SELF) { if(not sdInfo.commandExecuted) { - sif::debug << "Mount self" << std::endl; result = sdCardSetup(sdInfo.pref, sd::SdState::MOUNTED, sdInfo.prefChar); sdInfo.commandExecuted = true; } else { nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card"); + sdInfo.prefState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.pref, sd::SdState::MOUNTED); } } @@ -224,11 +234,9 @@ ReturnValue_t CoreController::sdInitStateMachine() { // 2. Hot redundant case: Other SD card needs to be mounted and switched on #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(sdInfo.otherState == sd::SdState::ON) { - sif::debug << "Determine: Setting other state off" << std::endl; sdInfo.state = SdStates::SET_STATE_OTHER; } else if(sdInfo.otherState == sd::SdState::MOUNTED) { - sif::debug << "Determine: Unmounting other" << std::endl; sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { @@ -255,22 +263,24 @@ ReturnValue_t CoreController::sdInitStateMachine() { // Set state of other SD card to ON or OFF, depending on redundancy mode #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(not sdInfo.commandExecuted) { - sif::debug << "Set state other off" << std::endl; - result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar); + result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar, false); sdInfo.commandExecuted = true; } else { nonBlockingOpChecking(SdStates::UPDATE_INFO, 10, "Switching off other SD card"); + sdInfo.otherState = sd::SdState::OFF; + currentStateSetter(sdInfo.other, sd::SdState::OFF); } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { - sif::debug << "Set state other on" << std::endl; result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); sdInfo.commandExecuted = true; } else { nonBlockingOpChecking(SdStates::SdStates::MOUNT_UNMOUNT_OTHER, 10, "Switching on other SD card"); + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); } #endif @@ -280,12 +290,13 @@ ReturnValue_t CoreController::sdInitStateMachine() { // Mount or unmount other SD card, depending on redundancy mode #if Q7S_SD_CARD_CONFIG == Q7S_SD_COLD_REDUNDANT if(not sdInfo.commandExecuted) { - sif::debug << "Unmount other" << std::endl; result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); sdInfo.commandExecuted = true; } else { nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card"); + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { @@ -294,13 +305,14 @@ ReturnValue_t CoreController::sdInitStateMachine() { } else { nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card"); + sdInfo.otherState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.other, sd::SdState::MOUNTED); } #endif } if(sdInfo.state == SdStates::UPDATE_INFO) { if(not sdInfo.commandExecuted) { - sif::debug << "update info" << std::endl; // It is assumed that all tasks are running by the point this section is reached. // Therefore, perform this operation in blocking mode because it does not take long // and the ready state of the SD card is available sooner @@ -316,7 +328,9 @@ ReturnValue_t CoreController::sdInitStateMachine() { sdInfo.initFinished = true; sdInfo.cycleCount = 0; sdcMan->setBlocking(false); - sif::debug << "Sd init done" << std::endl; + sdcMan->getSdCardActiveStatus(sdInfo.currentState); + updateSdInfoOther(); + sif::info << "SD card initialization finished" << std::endl; } } @@ -327,8 +341,9 @@ ReturnValue_t CoreController::sdInitStateMachine() { ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, - std::string sdChar) { + std::string sdChar, bool printOutput) { std::string mountString; + sdcMan->setPrintCommandOutput(printOutput); if(sdCard == sd::SdCard::SLOT_0) { mountString = SdCardManager::SD_0_MOUNT_POINT; } @@ -371,7 +386,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS return sdcMan->switchOnSdCard(sdCard, true, &sdInfo.currentState); } else if(targetState == sd::SdState::ON) { - sif::info << "Switching on SD card" << sdChar << std::endl; + sif::info << "Switching on SD card " << sdChar << std::endl; return sdcMan->switchOnSdCard(sdCard, false, &sdInfo.currentState); } } @@ -418,7 +433,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { } else { if(not sdInfo.initFinished) { - sdInitStateMachine(); + sdStateMachine(); } } result = initVersionFile(); diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 1dec1f36..f2d9a565 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -79,7 +79,7 @@ private: SdCardManager* sdcMan = nullptr; ReturnValue_t initSdCardBlocking(); - ReturnValue_t sdInitStateMachine(); + ReturnValue_t sdStateMachine(); struct SdInfo { sd::SdCard pref = sd::SdCard::NONE; @@ -98,7 +98,8 @@ private: SdInfo sdInfo; void updateSdInfoOther(); - ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar); + ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar, + bool printOutput = true); ReturnValue_t sdColdRedundantBlockingInit(); void determinePreferredSdCard(); diff --git a/bsp_q7s/memory/SdCardManager.cpp b/bsp_q7s/memory/SdCardManager.cpp index f203cb29..873bb6a4 100644 --- a/bsp_q7s/memory/SdCardManager.cpp +++ b/bsp_q7s/memory/SdCardManager.cpp @@ -39,7 +39,8 @@ ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCar if(doMountSdCard) { if(not blocking) { sif::warning << "SdCardManager::switchOnSdCard: Two-step command but manager is" - " not configured for blocking operation. Forcing blocking mode.." << std::endl; + " not configured for blocking operation. " + "Forcing blocking mode.." << std::endl; blocking = true; } } @@ -161,7 +162,7 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { } ostringstream command; command << "q7hw sd set " << sdstring << " " << statestring; - cmdExecutor.load(command.str(), blocking, true); + cmdExecutor.load(command.str(), blocking, printCmdOutput); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::setSdCardState"); @@ -220,7 +221,7 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { currentOp = Operations::MOUNTING; } string sdMountCommand = "mount " + mountDev + " " + mountPoint; - cmdExecutor.load(sdMountCommand, blocking, true); + cmdExecutor.load(sdMountCommand, blocking, printCmdOutput); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); @@ -259,7 +260,7 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { if(not blocking) { currentOp = Operations::UNMOUNTING; } - cmdExecutor.load(sdUnmountCommand, blocking, true); + cmdExecutor.load(sdUnmountCommand, blocking, printCmdOutput); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::unmountSdCard"); @@ -380,7 +381,7 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() { } // Use q7hw utility and pipe the command output into the state file std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); - cmdExecutor.load(updateCmd, blocking, true); + cmdExecutor.load(updateCmd, blocking, printCmdOutput); ReturnValue_t result = cmdExecutor.execute(); if(blocking and result != HasReturnvaluesIF::RETURN_OK) { utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard"); @@ -450,3 +451,8 @@ void SdCardManager::setBlocking(bool blocking) { this->blocking = blocking; } +void SdCardManager::setPrintCommandOutput(bool print) { + this->printCmdOutput = print; + +} + diff --git a/bsp_q7s/memory/SdCardManager.h b/bsp_q7s/memory/SdCardManager.h index 96192575..19024914 100644 --- a/bsp_q7s/memory/SdCardManager.h +++ b/bsp_q7s/memory/SdCardManager.h @@ -194,10 +194,12 @@ public: void resetState(); void setBlocking(bool blocking); + void setPrintCommandOutput(bool print); private: CommandExecutor cmdExecutor; Operations currentOp = Operations::IDLE; bool blocking = false; + bool printCmdOutput = true; SdCardManager(); -- 2.43.0 From 1c0ea5cbb10040b0675d0a54ac8621639dd83b01 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 00:37:07 +0200 Subject: [PATCH 098/116] tested hot redundant config as well --- bsp_q7s/core/CoreController.cpp | 58 +++++++++++++++++---------------- bsp_q7s/core/CoreController.h | 16 +++++++-- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index cb705930..6bc0abbb 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -123,8 +123,8 @@ ReturnValue_t CoreController::initSdCardBlocking() { return result; #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT sif::info << "Hot redundant SD card configuration" << std::endl; - sdCardSetup(statusPair, sd::SdCard::SLOT_0, "0"); - sdCardSetup(statusPair, sd::SdCard::SLOT_1, "1"); + sdCardSetup(sd::SdCard::SLOT_0, sd::SdState::MOUNTED, "0", false); + sdCardSetup(sd::SdCard::SLOT_1, sd::SdState::MOUNTED, "1", false); // Update status file sdcMan->updateSdCardStateFile(); return HasReturnvaluesIF::RETURN_OK; @@ -240,21 +240,19 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { - // Is already off, update info - sdInfo.state = SdStates::UPDATE_INFO; + // Is already off, update info, but with a small delay + sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(sdInfo.otherState == sd::SdState::OFF) { - sif::debug << "Determine: Setting other state on" << std::endl; sdInfo.state = SdStates::SET_STATE_OTHER; } else if(sdInfo.otherState == sd::SdState::ON) { - sif::debug << "Determine: Mounting other" << std::endl; sdInfo.state = SdStates::MOUNT_UNMOUNT_OTHER; } else { // Is already on and mounted, update info - sdInfo.state = SdStates::UPDATE_INFO; + sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; } #endif } @@ -267,17 +265,18 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::UPDATE_INFO, 10, "Switching off other SD card"); + nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10, + "Switching off other SD card"); sdInfo.otherState = sd::SdState::OFF; currentStateSetter(sdInfo.other, sd::SdState::OFF); } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { - result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar); + result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar, false); sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::SdStates::MOUNT_UNMOUNT_OTHER, 10, + nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, "Switching on other SD card"); sdInfo.otherState = sd::SdState::ON; currentStateSetter(sdInfo.other, sd::SdState::ON); @@ -311,25 +310,28 @@ ReturnValue_t CoreController::sdStateMachine() { #endif } - if(sdInfo.state == SdStates::UPDATE_INFO) { - if(not sdInfo.commandExecuted) { - // It is assumed that all tasks are running by the point this section is reached. - // Therefore, perform this operation in blocking mode because it does not take long - // and the ready state of the SD card is available sooner - sdcMan->setBlocking(true); - // Update status file - result = sdcMan->updateSdCardStateFile(); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "CoreController::initialize: Updating SD card state file failed" - << std::endl; - } - sdInfo.commandExecuted = false; - sdInfo.state = SdStates::DONE; - sdInfo.initFinished = true; - sdInfo.cycleCount = 0; - sdcMan->setBlocking(false); - sdcMan->getSdCardActiveStatus(sdInfo.currentState); + if(sdInfo.state == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) { + sdInfo.state = SdStates::UPDATE_INFO; + } + else if(sdInfo.state == SdStates::UPDATE_INFO) { + // It is assumed that all tasks are running by the point this section is reached. + // Therefore, perform this operation in blocking mode because it does not take long + // and the ready state of the SD card is available sooner + sdcMan->setBlocking(true); + // Update status file + result = sdcMan->updateSdCardStateFile(); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "CoreController::initialize: Updating SD card state file failed" + << std::endl; + } + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::DONE; + sdInfo.cycleCount = 0; + sdcMan->setBlocking(false); + sdcMan->getSdCardActiveStatus(sdInfo.currentState); + if(not sdInfo.initFinished) { updateSdInfoOther(); + sdInfo.initFinished = true; sif::info << "SD card initialization finished" << std::endl; } } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index f2d9a565..da587807 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -60,19 +60,29 @@ private: ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode); - // States for non-blocking setup + // States for SD state machine, which is used in non-blocking mode enum class SdStates { NONE, START, GET_INFO, SET_STATE_SELF, MOUNT_SELF, + // Determine operations for other SD card, depending on redundancy configuration DETERMINE_OTHER, SET_STATE_OTHER, // Mount or unmount other MOUNT_UNMOUNT_OTHER, + // Skip period because the shell command used to generate the info file sometimes is + // missing the last performed operation if executed too early + SKIP_CYCLE_BEFORE_INFO_UPDATE, UPDATE_INFO, - DONE + // SD initialization done + DONE, + // Used if SD switches or mount commands are issued via telecommand + SET_STATE_FROM_COMMAND, + MOUNT_FROM_COMMAND, + UNMOUNT_FROM_COMMAND, + }; static constexpr bool BLOCKING_SD_INIT = false; @@ -93,6 +103,8 @@ private: bool initFinished = false; SdCardManager::SdStatePair currentState; uint16_t cycleCount = 0; + sd::SdCard commandedCard = sd::SdCard::NONE; + sd::SdState commandedState = sd::SdState::OFF; }; SdInfo sdInfo; -- 2.43.0 From f50b9de4a5acf392ab50a300fb6b5fc2d6de7502 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 01:24:18 +0200 Subject: [PATCH 099/116] extneded state machine for commanding support --- bsp_q7s/core/CoreController.cpp | 163 +++++++++++++++++++++++++------- bsp_q7s/core/CoreController.h | 13 ++- 2 files changed, 138 insertions(+), 38 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 6bc0abbb..b484c4cb 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -135,13 +135,27 @@ ReturnValue_t CoreController::initSdCardBlocking() { } ReturnValue_t CoreController::sdStateMachine() { -#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE - sif::info << "No SD card initialization will be performed" << std::endl; - return HasReturnvaluesIF::RETURN_OK; -#else ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; SdCardManager::Operations operation; + if(sdInfo.state == SdStates::IDLE) { + // Nothing to do + return result; + } + + if(sdInfo.state == SdStates::START) { +#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE + sif::info << "No SD card initialization will be performed" << std::endl; + sdInfo.state == SdStates::IDLE; + sdInfo.initFinished = true; +#else + sdInfo.cycleCount = 0; + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::GET_INFO; + } + + // This lambda checks the non-blocking operation and assigns the new state on success. + // It returns true for an operation success and false otherwise auto nonBlockingOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount, std::string opPrintout) { SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); @@ -149,28 +163,16 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.state = newStateOnSuccess; sdInfo.commandExecuted = false; sdInfo.cycleCount = 0; + return true; } else if(sdInfo.cycleCount > 4) { sif::warning << "CoreController::sdInitStateMachine: " << opPrintout << " takes too long" << std::endl; + return false; } + return false; }; - auto currentStateSetter = [&](sd::SdCard sdCard, sd::SdState newState) { - if(sdCard == sd::SdCard::SLOT_0) { - sdInfo.currentState.first = newState; - } - else { - sdInfo.currentState.second = newState; - } - }; - - if(sdInfo.state == SdStates::START) { - sdInfo.cycleCount = 0; - sdInfo.commandExecuted = false; - sdInfo.state = SdStates::GET_INFO; - } - if(sdInfo.state == SdStates::GET_INFO) { if(not sdInfo.commandExecuted) { // Create update status file @@ -222,9 +224,10 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card"); - sdInfo.prefState = sd::SdState::MOUNTED; - currentStateSetter(sdInfo.pref, sd::SdState::MOUNTED); + if(nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) { + sdInfo.prefState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.pref, sd::SdState::MOUNTED); + } } } @@ -265,10 +268,11 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10, - "Switching off other SD card"); - sdInfo.otherState = sd::SdState::OFF; - currentStateSetter(sdInfo.other, sd::SdState::OFF); + if(nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10, + "Switching off other SD card")) { + sdInfo.otherState = sd::SdState::OFF; + currentStateSetter(sdInfo.other, sd::SdState::OFF); + } } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { @@ -282,7 +286,6 @@ ReturnValue_t CoreController::sdStateMachine() { currentStateSetter(sdInfo.other, sd::SdState::ON); } #endif - } if(sdInfo.state == SdStates::MOUNT_UNMOUNT_OTHER) { @@ -293,9 +296,10 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card"); - sdInfo.otherState = sd::SdState::ON; - currentStateSetter(sdInfo.other, sd::SdState::ON); + if(nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) { + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); + } } #elif Q7S_SD_CARD_CONFIG == Q7S_SD_HOT_REDUNDANT if(not sdInfo.commandExecuted) { @@ -303,9 +307,10 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card"); - sdInfo.otherState = sd::SdState::MOUNTED; - currentStateSetter(sdInfo.other, sd::SdState::MOUNTED); + if(nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card")) { + sdInfo.otherState = sd::SdState::MOUNTED; + currentStateSetter(sdInfo.other, sd::SdState::MOUNTED); + } } #endif } @@ -325,7 +330,7 @@ ReturnValue_t CoreController::sdStateMachine() { << std::endl; } sdInfo.commandExecuted = false; - sdInfo.state = SdStates::DONE; + sdInfo.state = SdStates::IDLE; sdInfo.cycleCount = 0; sdcMan->setBlocking(false); sdcMan->getSdCardActiveStatus(sdInfo.currentState); @@ -336,11 +341,100 @@ ReturnValue_t CoreController::sdStateMachine() { } } + if(sdInfo.state == SdStates::SET_STATE_FROM_COMMAND) { + if(not sdInfo.commandExecuted) { + executeNextExternalSdCommand(); + } + else { + checkExternalSdCommandStatus(); + } + } + sdInfo.cycleCount++; return HasReturnvaluesIF::RETURN_OK; #endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ } +void CoreController::executeNextExternalSdCommand() { + std::string sdChar; + sd::SdState currentStateOfCard = sd::SdState::OFF; + if(sdInfo.commandedCard == sd::SdCard::SLOT_0) { + sdChar = "0"; + currentStateOfCard = sdInfo.currentState.first; + } + else { + sdChar = "1"; + currentStateOfCard = sdInfo.currentState.second; + } + if(currentStateOfCard == sd::SdState::OFF) { + if(sdInfo.commandedState == sd::SdState::ON) { + sdInfo.currentlyCommandedState = sdInfo.commandedState; + } + else if(sdInfo.commandedState == sd::SdState::MOUNTED) { + sdInfo.currentlyCommandedState = sd::SdState::ON; + } + else { + // SD card is already on target state + sdInfo.commandFinished = true; + sdInfo.state = SdStates::IDLE; + } + } + else if(currentStateOfCard == sd::SdState::ON) { + if(sdInfo.commandedState == sd::SdState::OFF or + sdInfo.commandedState == sd::SdState::MOUNTED) { + sdInfo.currentlyCommandedState = sdInfo.commandedState; + } + else { + // Already on target state + sdInfo.commandFinished = true; + sdInfo.state = SdStates::IDLE; + } + } + else if(currentStateOfCard == sd::SdState::MOUNTED) { + if(sdInfo.commandedState == sd::SdState::ON) { + sdInfo.currentlyCommandedState = sdInfo.commandedState; + } + else if(sdInfo.commandedState == sd::SdState::OFF) { + // This causes an unmount in sdCardSetup + sdInfo.currentlyCommandedState = sd::SdState::ON; + } + else { + sdInfo.commandFinished = true; + } + } + sdCardSetup(sdInfo.commandedCard, sdInfo.commandedState, sdChar); + sdInfo.commandExecuted = true; +} + +void CoreController::checkExternalSdCommandStatus() { + SdCardManager::Operations operation; + SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation); + if(status == SdCardManager::OpStatus::SUCCESS) { + if(sdInfo.currentlyCommandedState == sdInfo.commandedState) { + sdInfo.state = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE; + sdInfo.commandFinished = true; + } + else { + // stay on same state machine state because the target state was not reached yet. + sdInfo.cycleCount = 0; + } + currentStateSetter(sdInfo.commandedCard, sdInfo.currentlyCommandedState); + sdInfo.commandExecuted = false; + } + else if(sdInfo.cycleCount > 4) { + sif::warning << "CoreController::sdStateMachine: Commanding SD state " + "takes too long" << std::endl; + } +} + +void CoreController::currentStateSetter(sd::SdCard sdCard, sd::SdState newState) { + if(sdCard == sd::SdCard::SLOT_0) { + sdInfo.currentState.first = newState; + } + else { + sdInfo.currentState.second = newState; + } +} ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar, bool printOutput) { @@ -610,6 +704,7 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId, if(RFlag) { oss << "R"; } + oss << " " << repoName << " > " << targetFileName; int result = std::system(oss.str().c_str()); if(result != 0) { diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index da587807..b26c99c5 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -77,12 +77,9 @@ private: SKIP_CYCLE_BEFORE_INFO_UPDATE, UPDATE_INFO, // SD initialization done - DONE, + IDLE, // Used if SD switches or mount commands are issued via telecommand SET_STATE_FROM_COMMAND, - MOUNT_FROM_COMMAND, - UNMOUNT_FROM_COMMAND, - }; static constexpr bool BLOCKING_SD_INIT = false; @@ -99,10 +96,15 @@ private: std::string prefChar = "0"; std::string otherChar = "1"; SdStates state = SdStates::START; + // Used to track whether a command was executed bool commandExecuted = true; bool initFinished = false; SdCardManager::SdStatePair currentState; uint16_t cycleCount = 0; + // These two flags are related to external commanding + bool commandIssued = false; + bool commandFinished = false; + sd::SdState currentlyCommandedState = sd::SdState::OFF; sd::SdCard commandedCard = sd::SdCard::NONE; sd::SdState commandedState = sd::SdState::OFF; }; @@ -113,7 +115,10 @@ private: ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar, bool printOutput = true); ReturnValue_t sdColdRedundantBlockingInit(); + void currentStateSetter(sd::SdCard sdCard, sd::SdState newState); void determinePreferredSdCard(); + void executeNextExternalSdCommand(); + void checkExternalSdCommandStatus(); ReturnValue_t initVersionFile(); ReturnValue_t initBootCopy(); -- 2.43.0 From 51dbc957504a7fd626f914d8a6b242f60be181a6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:39:53 +0200 Subject: [PATCH 100/116] fixes for NO_INIT code --- bsp_q7s/core/CoreController.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index b484c4cb..5f6c1ecc 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -146,8 +146,9 @@ ReturnValue_t CoreController::sdStateMachine() { if(sdInfo.state == SdStates::START) { #if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE sif::info << "No SD card initialization will be performed" << std::endl; - sdInfo.state == SdStates::IDLE; + sdInfo.state = SdStates::IDLE; sdInfo.initFinished = true; + return result; #else sdInfo.cycleCount = 0; sdInfo.commandExecuted = false; -- 2.43.0 From 365fa0adc415970e56203603fa6259a139da0321 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:43:02 +0200 Subject: [PATCH 101/116] tweaks and fixes for state machine --- bsp_q7s/core/CoreController.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 5f6c1ecc..f92e6d60 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -38,10 +38,11 @@ CoreController::CoreController(object_id_t objectId): if(sdcMan == nullptr) { sif::error << "CoreController::CoreController: SD card manager invalid!" << std::endl; } + if(not BLOCKING_SD_INIT) { - sdStateMachine(); sdcMan->setBlocking(false); } + sdStateMachine(); result = initBootCopy(); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -59,7 +60,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - if(not BLOCKING_SD_INIT and not sdInfo.initFinished) { + if(not BLOCKING_SD_INIT) { sdStateMachine(); } performWatchdogControlOperation(); @@ -83,9 +84,8 @@ ReturnValue_t CoreController::initialize() { "count failed" << std::endl; } - if(not BLOCKING_SD_INIT) { - sdStateMachine(); - } + sdStateMachine(); + return ExtendedControllerBase::initialize(); } @@ -150,6 +150,13 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.initFinished = true; return result; #else + // Init will be performed by separate function + if(not BLOCKING_SD_INIT) { + sdInfo.state = SdStates::IDLE; + sdInfo.initFinished = true; + return result; + } +#endif sdInfo.cycleCount = 0; sdInfo.commandExecuted = false; sdInfo.state = SdStates::GET_INFO; -- 2.43.0 From ea56a5d536f94657ffffc7db4280502c9e6f4ec8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:43:54 +0200 Subject: [PATCH 102/116] includes reordered --- bsp_q7s/core/CoreController.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index f92e6d60..f1144e4b 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -6,14 +6,13 @@ #include "fsfw/FSFWVersion.h" #include "fsfw/timemanager/Stopwatch.h" #include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw/osal/linux/Timer.h" #if OBSW_USE_TMTC_TCP_BRIDGE == 0 #include "fsfw/osal/common/UdpTmTcBridge.h" #else #include "fsfw/osal/common/TcpTmTcBridge.h" #endif -#include "fsfw/osal/linux/Timer.h" - #include "bsp_q7s/memory/scratchApi.h" #include "bsp_q7s/memory/SdCardManager.h" -- 2.43.0 From e05c52be859c14aee9a2e15ae2108b626638b205 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:45:26 +0200 Subject: [PATCH 103/116] always performing state machine now --- bsp_q7s/core/CoreController.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index f1144e4b..d56c07ed 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -59,9 +59,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - if(not BLOCKING_SD_INIT) { - sdStateMachine(); - } + sdStateMachine(); performWatchdogControlOperation(); } -- 2.43.0 From 0fecfab2f030dce892e2dbf139dc50a2ab71d76f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:46:24 +0200 Subject: [PATCH 104/116] minor formatting changes --- bsp_q7s/core/CoreController.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index d56c07ed..1fa1949e 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -82,8 +82,6 @@ ReturnValue_t CoreController::initialize() { } sdStateMachine(); - - return ExtendedControllerBase::initialize(); } -- 2.43.0 From 22d7af4b7834e7bab860eea1cda605afe2e0d7c3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:49:04 +0200 Subject: [PATCH 105/116] always perform state machine in initAfterTaskCreation --- bsp_q7s/core/CoreController.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 1fa1949e..51c49485 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -530,11 +530,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { sif::warning << "CoreController::CoreController: SD card init failed" << std::endl; } } - else { - if(not sdInfo.initFinished) { - sdStateMachine(); - } - } + sdStateMachine(); result = initVersionFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; -- 2.43.0 From 8cdb877df6538c76ae7bb6c7f34e67067300b597 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:50:45 +0200 Subject: [PATCH 106/116] removed endif block --- bsp_q7s/core/CoreController.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 51c49485..77ccbcbd 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -355,7 +355,6 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.cycleCount++; return HasReturnvaluesIF::RETURN_OK; -#endif /* Q7S_SD_CARD_CONFIG != Q7S_SD_NONE */ } void CoreController::executeNextExternalSdCommand() { -- 2.43.0 From 02a837c964dc74c5850bee268916e8ac5f11d03c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 12:59:21 +0200 Subject: [PATCH 107/116] tweaks for no-init variant --- bsp_q7s/core/CoreController.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 77ccbcbd..e1891de7 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -25,7 +25,8 @@ CoreController::Chip CoreController::currentChip = Chip::NO_CHIP; CoreController::Copy CoreController::currentCopy = Copy::NO_COPY; CoreController::CoreController(object_id_t objectId): - ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) { + ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), + opDivider(5) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; try { result = initWatchdogFifo(); @@ -91,16 +92,16 @@ ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, } ReturnValue_t CoreController::initSdCardBlocking() { -#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE - sif::info << "No SD card initialization will be performed" << std::endl; - return HasReturnvaluesIF::RETURN_OK; -#else // Create update status file ReturnValue_t result = sdcMan->updateSdCardStateFile(); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl; } +#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE + sif::info << "No SD card initialization will be performed" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +#else result = sdcMan->getSdCardActiveStatus(sdInfo.currentState); if(result != HasReturnvaluesIF::RETURN_OK) { @@ -139,22 +140,22 @@ ReturnValue_t CoreController::sdStateMachine() { } if(sdInfo.state == SdStates::START) { -#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE - sif::info << "No SD card initialization will be performed" << std::endl; - sdInfo.state = SdStates::IDLE; - sdInfo.initFinished = true; - return result; -#else // Init will be performed by separate function - if(not BLOCKING_SD_INIT) { + if(BLOCKING_SD_INIT) { sdInfo.state = SdStates::IDLE; sdInfo.initFinished = true; return result; } + else { + // Still update SD state file +#if Q7S_SD_CARD_CONFIG == Q7S_SD_NONE + sdInfo.state = SdStates::UPDATE_INFO; +#else + sdInfo.cycleCount = 0; + sdInfo.commandExecuted = false; + sdInfo.state = SdStates::GET_INFO; #endif - sdInfo.cycleCount = 0; - sdInfo.commandExecuted = false; - sdInfo.state = SdStates::GET_INFO; + } } // This lambda checks the non-blocking operation and assigns the new state on success. @@ -502,7 +503,7 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS else { sif::warning << "CoreController::sdCardSetup: Invalid state for this call" << std::endl; } -return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } -- 2.43.0 From 891ba6881ba842c8d4a13c5a2dd8f80a4788627c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 8 Aug 2021 13:00:11 +0200 Subject: [PATCH 108/116] reordered control operation --- bsp_q7s/core/CoreController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index e1891de7..33f2acd1 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -60,8 +60,8 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - sdStateMachine(); performWatchdogControlOperation(); + sdStateMachine(); } ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, -- 2.43.0 From dc3dfa12924b5459c5f1cc9584fae00421c50de5 Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sun, 8 Aug 2021 15:02:59 +0200 Subject: [PATCH 109/116] ploc updater --- bsp_q7s/core/InitMission.cpp | 8 + bsp_q7s/core/ObjectFactory.cpp | 2 + common/config/commonConfig.h.in | 2 +- common/config/commonObjects.h | 2 +- generators/bsp_q7s_events.csv | 198 ++-- generators/bsp_q7s_objects.csv | 1 + generators/bsp_q7s_returnvalues.csv | 908 +++++++++--------- generators/events/translateEvents.cpp | 22 +- generators/objects/translateObjects.cpp | 7 +- linux/fsfwconfig/events/translateEvents.cpp | 22 +- linux/fsfwconfig/objects/systemObjectList.h | 2 +- linux/fsfwconfig/objects/translateObjects.cpp | 7 +- mission/devices/PlocSupervisorHandler.cpp | 135 ++- mission/devices/PlocSupervisorHandler.h | 49 +- mission/devices/PlocUpdater.cpp | 225 +++-- mission/devices/PlocUpdater.h | 65 +- .../PlocSupervisorDefinitions.h | 31 +- tmtc | 2 +- 18 files changed, 982 insertions(+), 706 deletions(-) diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index a619da5a..f082d3d9 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -95,6 +95,13 @@ void initmission::initTasks() { initmission::printAddObjectError("UDP_POLLING", objects::TMTC_POLLING_TASK); } + PeriodicTaskIF* plocUpdaterTask = factory->createPeriodicTask( + "PLOC_UPDATER_TASK", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc); + result = plocUpdaterTask->addComponent(objects::PLOC_UPDATER); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("PLOC_UPDATER_TASK", objects::PLOC_UPDATER); + } + // FS task, task interval does not matter because it runs in permanent loop, priority low // because it is a non-essential background task @@ -137,6 +144,7 @@ void initmission::initTasks() { tmtcBridgeTask->startTask(); tmtcPollingTask->startTask(); coreController->startTask(); + plocUpdaterTask->startTask(); taskStarter(pstTasks, "PST task vector"); taskStarter(pusTasks, "PUS task vector"); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index a5e045cb..73e93dc4 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -37,6 +37,7 @@ #include "mission/devices/RadiationSensorHandler.h" #include "mission/devices/RwHandler.h" #include "mission/devices/StarTrackerHandler.h" +#include "mission/devices/PlocUpdater.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" #include "mission/devices/devicedefinitions/PlocMPSoCDefinitions.h" @@ -178,6 +179,7 @@ void ObjectFactory::produce(void* args){ #endif + new PlocUpdater(objects::PLOC_UPDATER); } void ObjectFactory::createTmpComponents() { diff --git a/common/config/commonConfig.h.in b/common/config/commonConfig.h.in index 52b5dd45..2b0590c8 100644 --- a/common/config/commonConfig.h.in +++ b/common/config/commonConfig.h.in @@ -5,6 +5,6 @@ // Use TCP instead of UDP for the TMTC bridge. This allows using the TMTC client locally // because UDP packets are not allowed in the VPN -#define OBSW_USE_TMTC_TCP_BRIDGE 1 +#define OBSW_USE_TMTC_TCP_BRIDGE 0 #endif /* COMMON_CONFIG_COMMONCONFIG_H_ */ diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index 2a2a25b9..ef61d4b8 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -82,7 +82,7 @@ enum commonObjects: uint32_t { START_TRACKER = 0x44130001, - PLOC_UPDATER = 0x44300000 + PLOC_UPDATER = 0x44330000 }; } diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 4635788b..0174a9ee 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -1,96 +1,102 @@ -2200;STORE_SEND_WRITE_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2201;STORE_WRITE_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2202;STORE_SEND_READ_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2203;STORE_READ_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2204;UNEXPECTED_MSG;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2205;STORING_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2206;TM_DUMP_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2207;STORE_INIT_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2208;STORE_INIT_EMPTY;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2209;STORE_CONTENT_CORRUPTED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2210;STORE_INITIALIZE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2211;INIT_DONE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2212;DUMP_FINISHED;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2213;DELETION_FINISHED;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2214;DELETION_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -2600;GET_DATA_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h -2601;STORE_DATA_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h -2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2803;DEVICE_READING_REPLY_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2805;DEVICE_MISSED_REPLY;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2806;DEVICE_UNKNOWN_REPLY;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2807;DEVICE_UNREQUESTED_REPLY;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2809;MONITORING_LIMIT_EXCEEDED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -2810;MONITORING_AMBIGUOUS;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -4201;FUSE_CURRENT_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4202;FUSE_WENT_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4204;POWER_ABOVE_HIGH_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4205;POWER_BELOW_LOW_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h -4300;SWITCH_WENT_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h -5000;HEATER_ON;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5001;HEATER_OFF;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5002;HEATER_TIMEOUT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5003;HEATER_STAYED_ON;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5004;HEATER_STAYED_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h -5200;TEMP_SENSOR_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5201;TEMP_SENSOR_LOW;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5202;TEMP_SENSOR_GRADIENT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h -5901;COMPONENT_TEMP_LOW;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5902;COMPONENT_TEMP_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5903;COMPONENT_TEMP_OOL_LOW;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5904;COMPONENT_TEMP_OOL_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -5905;TEMP_NOT_IN_OP_RANGE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h -7101;FDIR_CHANGED_STATE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7102;FDIR_STARTS_RECOVERY;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h -7201;MONITOR_CHANGED_STATE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7202;VALUE_BELOW_LOW_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7204;VALUE_OUT_OF_RANGE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h -7301;SWITCHING_TM_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/HkSwitchHelper.h -7400;CHANGING_MODE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7401;MODE_INFO;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7402;FALLBACK_FAILED;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7403;MODE_TRANSITION_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7404;CANT_KEEP_MODE;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7405;OBJECT_IN_INVALID_MODE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7406;FORCING_MODE;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7407;MODE_CMD_REJECTED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h -7506;HEALTH_INFO;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7507;CHILD_CHANGED_HEALTH;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7508;CHILD_PROBLEMS;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7509;OVERWRITING_HEALTH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7510;TRYING_RECOVERY;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7511;RECOVERY_STEP;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7512;RECOVERY_DONE;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h -7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h -8900;CLOCK_SET;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h -8901;CLOCK_SET_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h -9700;TEST;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service17Test.h -10600;CHANGE_OF_SETUP_PARAMETER;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/MGMHandlerLIS3MDL.h -11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h -11102;ACK_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h -11103;EXE_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h -11104;CRC_FAILURE_EVENT;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h -11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h -11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h -11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h -11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h -11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h -11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h -11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h -11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h -11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h -11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervrisor crc failure in telemetry packet;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h -11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h -11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h -11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h +2200;STORE_SEND_WRITE_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2201;STORE_WRITE_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2202;STORE_SEND_READ_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2203;STORE_READ_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2204;UNEXPECTED_MSG;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2205;STORING_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2206;TM_DUMP_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2207;STORE_INIT_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2208;STORE_INIT_EMPTY;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2209;STORE_CONTENT_CORRUPTED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2210;STORE_INITIALIZE;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2211;INIT_DONE;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2212;DUMP_FINISHED;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2213;DELETION_FINISHED;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2214;DELETION_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +2600;GET_DATA_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2601;STORE_DATA_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h +2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2803;DEVICE_READING_REPLY_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2805;DEVICE_MISSED_REPLY;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2806;DEVICE_UNKNOWN_REPLY;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2807;DEVICE_UNREQUESTED_REPLY;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2809;MONITORING_LIMIT_EXCEEDED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +2810;MONITORING_AMBIGUOUS;HIGH;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h +4201;FUSE_CURRENT_HIGH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4202;FUSE_WENT_OFF;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4204;POWER_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4205;POWER_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/Fuse.h +4300;SWITCH_WENT_OFF;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h +5000;HEATER_ON;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5001;HEATER_OFF;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5002;HEATER_TIMEOUT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5003;HEATER_STAYED_ON;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5004;HEATER_STAYED_OFF;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h +5200;TEMP_SENSOR_HIGH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5201;TEMP_SENSOR_LOW;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5202;TEMP_SENSOR_GRADIENT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h +5901;COMPONENT_TEMP_LOW;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5902;COMPONENT_TEMP_HIGH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5903;COMPONENT_TEMP_OOL_LOW;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5904;COMPONENT_TEMP_OOL_HIGH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +5905;TEMP_NOT_IN_OP_RANGE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h +7101;FDIR_CHANGED_STATE;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7102;FDIR_STARTS_RECOVERY;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h +7201;MONITOR_CHANGED_STATE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7202;VALUE_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7204;VALUE_OUT_OF_RANGE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h +7301;SWITCHING_TM_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/HkSwitchHelper.h +7400;CHANGING_MODE;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7401;MODE_INFO;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7402;FALLBACK_FAILED;HIGH;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7403;MODE_TRANSITION_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7404;CANT_KEEP_MODE;HIGH;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7405;OBJECT_IN_INVALID_MODE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7406;FORCING_MODE;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7407;MODE_CMD_REJECTED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h +7506;HEALTH_INFO;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7507;CHILD_CHANGED_HEALTH;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7508;CHILD_PROBLEMS;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7509;OVERWRITING_HEALTH;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7510;TRYING_RECOVERY;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7511;RECOVERY_STEP;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7512;RECOVERY_DONE;MEDIUM;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h +7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h +8900;CLOCK_SET;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +8901;CLOCK_SET_FAILURE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h +9700;TEST;INFO;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/pus/Service17Test.h +10600;CHANGE_OF_SETUP_PARAMETER;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/MGMHandlerLIS3MDL.h +11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11102;ACK_FAILURE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11103;EXE_FAILURE;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11104;CRC_FAILURE_EVENT;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h +11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h +11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h +11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h +11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h +11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h +11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h +11700;UPDATE_FILE_NOT_EXISTS;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h +11701;ACTION_COMMANDING_FAILED;LOW;;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h +11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h +11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h +11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h +11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index d0e9bfb6..84d3db3a 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -37,6 +37,7 @@ 0x44250002;PDU2_HANDLER 0x44250003;ACU_HANDLER 0x443200A5;RAD_SENSOR +0x44330000;PLOC_UPDATER 0x44330015;PLOC_MPSOC_HANDLER 0x44330016;PLOC_SUPERVISOR_HANDLER 0x444100A2;SOLAR_ARRAY_DEPL_HANDLER diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index 99529d17..2b87317d 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -1,451 +1,461 @@ 0x0;OK;System-wide code for ok.;RETURN_OK;HasReturnvaluesIF.h;HasReturnvaluesIF 0x1;Failed;Unspecified system-wide code for failed.;RETURN_FAILED;HasReturnvaluesIF.h;HasReturnvaluesIF -0x5d00;GOMS_PacketTooLong;;0;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x5d01;GOMS_InvalidTableId;;1;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x5d02;GOMS_InvalidAddress;;2;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x5d03;GOMS_InvalidParamSize;;3;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x5d04;GOMS_InvalidPayloadSize;;4;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x5d05;GOMS_UnknownReplyId;;5;/home/rmueller/EIVE/eive-obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER -0x54a0;PLSV_CrcFailure;Space Packet received from PLOC supervisor has invalid CRC;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER -0x54a1;PLSV_ReceivedAckFailure;Received ACK failure reply from PLOC supervisor;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER -0x54a2;PLSV_ReceivedExeFailure;Received execution failure reply from PLOC supervisor;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER -0x54a3;PLSV_InvalidApid;Received space packet with invalid APID from PLOC supervisor;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER -0x54a4;PLSV_GetTimeFailure;Failed to read current system time;0xA4;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER -0x54a5;PLSV_InvalidUartComIf;Invalid communication interface specified;0xA5;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER -0x51b0;RWHA_SpiWriteFailure;;0xB0;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;0xB1;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;0xB2;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51b3;RWHA_InvalidSubstitute;Can be used by the HDLC decoding mechanism to inform about an invalid substitution combination;0xB3;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51b4;RWHA_MissingEndSign;HDLC decoding mechanism never receives the end sign 0x7E;0xB4;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51b5;RWHA_NoReply;Reaction wheel only responds with empty frames.;0xB5;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51a0;RWHA_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000; 1000] or [1000; 65000];0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51a1;RWHA_InvalidRampTime;Action Message with invalid ramp time was received.;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51a2;RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51a3;RWHA_ExecutionFailed;Command execution failed;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x51a4;RWHA_CrcError;Reaction wheel reply has invalid crc;0xA4;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h;RW_HANDLER -0x52b0;STRH_CrcFailure;Received reply with invalid CRC;0xB0;/home/rmueller/EIVE/eive-obsw/mission/devices/StarTrackerHandler.h;STR_HANDLER -0x52a0;STRH_TmReplyError;Result code of tm reply indicates an error;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/StarTrackerHandler.h;STR_HANDLER -0x50a0;IMTQ_InvalidCommandCode;;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x50a1;IMTQ_ParameterMissing;;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x50a2;IMTQ_ParameterInvalid;;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x50a3;IMTQ_CcUnavailable;;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x50a4;IMTQ_InternalProcessingError;;0xA4;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x50a5;IMTQ_RejectedWithoutReason;;0xA5;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x50a6;IMTQ_CmdErrUnknown;;0xA6;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x50a7;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;0xA7;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER -0x4fa0;SYRLINKS_CrcFailure;;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4fa1;SYRLINKS_UartFraminOrParityErrorAck;;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4fa2;SYRLINKS_BadCharacterAck;;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4fa3;SYRLINKS_BadParameterValueAck;;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4fa4;SYRLINKS_BadEndOfFrameAck;;0xA4;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4fa5;SYRLINKS_UnknownCommandIdAck;;0xA5;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4fa6;SYRLINKS_BadCrcAck;;0xA6;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4fa7;SYRLINKS_ReplyWrongSize;;0xA7;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x4fa8;SYRLINKS_MissingStartFrameCharacter;;0xA8;/home/rmueller/EIVE/eive-obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER -0x53a0;PLMP_CrcFailure;;0xA0;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER -0x53a1;PLMP_ReceivedAckFailure;;0xA1;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER -0x53a2;PLMP_ReceivedExeFailure;;0xA2;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER -0x53a3;PLMP_InvalidApid;;0xA3;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER -0x4100;HSPI_HalTimeoutRetval;;0;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/stm32h7/spi/spiDefinitions.h;HAL_SPI -0x4101;HSPI_HalBusyRetval;;1;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/stm32h7/spi/spiDefinitions.h;HAL_SPI -0x4102;HSPI_HalErrorRetval;;2;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/stm32h7/spi/spiDefinitions.h;HAL_SPI -0x4201;HURT_UartReadFailure;;1;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/uart/UartComIF.h;HAL_UART -0x4202;HURT_UartReadSizeMissmatch;;2;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/uart/UartComIF.h;HAL_UART -0x4203;HURT_UartRxBufferTooSmall;;3;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/uart/UartComIF.h;HAL_UART -0x4401;HGIO_UnknownGpioId;;1;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4402;HGIO_DriveGpioFailure;;2;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4403;HGIO_GpioTypeFailure;;3;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x4404;HGIO_GpioInvalidInstance;;4;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw/hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO -0x2b01;CCS_BcIsSetVrCommand;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2b02;CCS_BcIsUnlockCommand;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bb0;CCS_BcIllegalCommand;;0xB0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bb1;CCS_BoardReadingNotFinished;;0xB1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf0;CCS_NsPositiveW;;0xF0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf1;CCS_NsNegativeW;;0xF1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf2;CCS_NsLockout;;0xF2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf3;CCS_FarmInLockout;;0xF3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bf4;CCS_FarmInWait;;0xF4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be0;CCS_WrongSymbol;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be1;CCS_DoubleStart;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be2;CCS_StartSymbolMissed;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be3;CCS_EndWithoutStart;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be4;CCS_TooLarge;;0xE4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be5;CCS_TooShort;;0xE5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be6;CCS_WrongTfVersion;;0xE6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be7;CCS_WrongSpacecraftId;;0xE7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be8;CCS_NoValidFrameType;;0xE8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2be9;CCS_CrcFailed;;0xE9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bea;CCS_VcNotFound;;0xEA;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2beb;CCS_ForwardingFailed;;0xEB;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bec;CCS_ContentTooLarge;;0xEC;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bed;CCS_ResidualData;;0xED;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bee;CCS_DataCorrupted;;0xEE;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bef;CCS_IllegalSegmentationFlag;;0xEF;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bd0;CCS_IllegalFlagCombination;;0xD0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bd1;CCS_ShorterThanHeader;;0xD1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bd2;CCS_TooShortBlockedPacket;;0xD2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2bd3;CCS_TooShortMapExtraction;;0xD3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF -0x2901;IEC_NoConfigurationTable;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2902;IEC_NoCpuTable;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2903;IEC_InvalidWorkspaceAddress;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2904;IEC_TooLittleWorkspace;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2905;IEC_WorkspaceAllocation;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2906;IEC_InterruptStackTooSmall;;0x06;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2907;IEC_ThreadExitted;;0x07;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2908;IEC_InconsistentMpInformation;;0x08;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2909;IEC_InvalidNode;;0x09;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290a;IEC_NoMpci;;0x0a;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290b;IEC_BadPacket;;0x0b;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290c;IEC_OutOfPackets;;0x0c;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290d;IEC_OutOfGlobalObjects;;0x0d;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290e;IEC_OutOfProxies;;0x0e;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x290f;IEC_InvalidGlobalId;;0x0f;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2910;IEC_BadStackHook;;0x10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2911;IEC_BadAttributes;;0x11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2912;IEC_ImplementationKeyCreateInconsistency;;0x12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2913;IEC_ImplementationBlockingOperationCancel;;0x13;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2914;IEC_MutexObtainFromBadState;;0x14;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0x2915;IEC_UnlimitedAndMaximumIs0;;0x15;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES -0xe01;HM_InvalidMode;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF -0xe02;HM_TransNotAllowed;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF -0xe03;HM_InTransition;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF -0xe04;HM_InvalidSubmode;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF -0x2d01;HPA_InvalidIdentifierId;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF -0x2d02;HPA_InvalidDomainId;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF -0x2d03;HPA_InvalidValue;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF -0x2d05;HPA_ReadOnly;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF -0x2c01;PAW_UnknownDatatype;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c02;PAW_DatatypeMissmatch;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c03;PAW_Readonly;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c04;PAW_TooBig;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c05;PAW_SourceNotSet;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c06;PAW_OutOfBounds;;0x06;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c07;PAW_NotSet;;0x07;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x2c08;PAW_ColumnOrRowsZero;;0x08;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER -0x3101;CF_ObjectHasNoFunctions;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/CommandsActionsIF.h;COMMANDS_ACTIONS_IF -0x3102;CF_AlreadyCommanding;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/CommandsActionsIF.h;COMMANDS_ACTIONS_IF -0x3201;HF_IsBusy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF -0x3202;HF_InvalidParameters;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF -0x3203;HF_ExecutionFinished;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF -0x3204;HF_InvalidActionId;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF -0x201;OM_InsertionFailed;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF -0x202;OM_NotFound;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF -0x203;OM_ChildInitFailed;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF -0x204;OM_InternalErrReporterUninit;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF -0x2500;FDI_YourFault;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF -0x2501;FDI_MyFault;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF -0x2502;FDI_ConfirmLater;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF -0x2101;TMF_Busy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2102;TMF_LastPacketFound;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2103;TMF_StopFetch;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2104;TMF_Timeout;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2105;TMF_TmChannelFull;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2106;TMF_NotStored;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2107;TMF_AllDeleted;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2108;TMF_InvalidData;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2109;TMF_NotReady;;9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF -0x2001;TMB_Busy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2002;TMB_Full;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2003;TMB_Empty;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2004;TMB_NullRequested;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2005;TMB_TooLarge;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2006;TMB_NotReady;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2007;TMB_DumpError;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2008;TMB_CrcError;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x2009;TMB_Timeout;;9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200a;TMB_IdlePacketFound;;10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200b;TMB_TelecommandFound;;11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200c;TMB_NoPusATm;;12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200d;TMB_TooSmall;;13;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200e;TMB_BlockNotFound;;14;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x200f;TMB_InvalidRequest;;15;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF -0x1c01;TCD_PacketLost;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION -0x1c02;TCD_DestinationNotFound;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION -0x1c03;TCD_ServiceIdAlreadyExists;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION -0x1b00;TCC_IllegalApid;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b01;TCC_IncompletePacket;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b02;TCC_IncorrectChecksum;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b03;TCC_IllegalPacketType;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b04;TCC_IllegalPacketSubtype;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b05;TCC_IncorrectPrimaryHeader;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x1b06;TCC_IncorrectSecondaryHeader;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK -0x4e1;RMP_CommandNoDescriptorsAvailable;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e2;RMP_CommandBufferFull;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e3;RMP_CommandChannelOutOfRange;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e6;RMP_CommandChannelDeactivated;;0xE6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e7;RMP_CommandPortOutOfRange;;0xE7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e8;RMP_CommandPortInUse;;0xE8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4e9;RMP_CommandNoChannel;;0xE9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4ea;RMP_NoHwCrc;;0xEA;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d0;RMP_ReplyNoReply;;0xD0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d1;RMP_ReplyNotSent;;0xD1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d2;RMP_ReplyNotYetSent;;0xD2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d3;RMP_ReplyMissmatch;;0xD3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4d4;RMP_ReplyTimeout;;0xD4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4c0;RMP_ReplyInterfaceBusy;;0xC0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4c1;RMP_ReplyTransmissionError;;0xC1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4c2;RMP_ReplyInvalidData;;0xC2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4c3;RMP_ReplyNotSupported;;0xC3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f0;RMP_LinkDown;;0xF0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f1;RMP_SpwCredit;;0xF1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f2;RMP_SpwEscape;;0xF2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f3;RMP_SpwDisconnect;;0xF3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f4;RMP_SpwParity;;0xF4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f5;RMP_SpwWriteSync;;0xF5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f6;RMP_SpwInvalidAddress;;0xF6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f7;RMP_SpwEarlyEop;;0xF7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f8;RMP_SpwDma;;0xF8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x4f9;RMP_SpwLinkError;;0xF9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x400;RMP_ReplyOk;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x401;RMP_ReplyGeneralErrorCode;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x402;RMP_ReplyUnusedPacketTypeOrCommandCode;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x403;RMP_ReplyInvalidKey;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x404;RMP_ReplyInvalidDataCrc;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x405;RMP_ReplyEarlyEop;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x406;RMP_ReplyTooMuchData;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x407;RMP_ReplyEep;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x408;RMP_ReplyReserved;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x409;RMP_ReplyVerifyBufferOverrun;;9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x40a;RMP_ReplyCommandNotImplementedOrNotAuthorised;;10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x40b;RMP_ReplyRmwDataLengthError;;11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x40c;RMP_ReplyInvalidTargetLogicalAddress;;12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL -0x2701;SM_DataTooLarge;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2702;SM_DataStorageFull;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2703;SM_IllegalStorageId;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2704;SM_DataDoesNotExist;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2705;SM_IllegalAddress;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x2706;SM_PoolTooLarge;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF -0x36a1;SGP4_InvalidEccentricity;;0xA1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a2;SGP4_InvalidMeanMotion;;0xA2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a3;SGP4_InvalidPerturbationElements;;0xA3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a4;SGP4_InvalidSemiLatusRectum;;0xA4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a5;SGP4_InvalidEpochElements;;0xA5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36a6;SGP4_SatelliteHasDecayed;;0xA6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36b1;SGP4_TleTooOld;;0xB1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x36b2;SGP4_TleNotInitialized;;0xB2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS -0x2301;MT_TooDetailedRequest;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x2302;MT_TooGeneralRequest;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x2303;MT_NoMatch;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x2304;MT_Full;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x2305;MT_NewNodeCreated;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS -0x3d01;DLEE_StreamTooShort;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/DleEncoder.h;DLE_ENCODER -0x3d02;DLEE_DecodingError;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/DleEncoder.h;DLE_ENCODER -0x2e01;ASC_TooLongForTargetType;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER -0x2e02;ASC_InvalidCharacters;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER -0x2e03;ASC_BufferTooSmall;;0x3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER -0xf01;CM_UnknownCommand;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/CommandMessageIF.h;COMMAND_MESSAGE -0x3801;MQI_Empty;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF -0x3802;MQI_Full;No space left for more messages;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF -0x3803;MQI_NoReplyPartner;Returned if a reply method was called without partner;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF -0x3804;MQI_DestinationInvalid;Returned if the target destination is invalid.;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF -0x3701;MUX_NotEnoughResources;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x3702;MUX_InsufficientMemory;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x3703;MUX_NoPrivilege;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x3704;MUX_WrongAttributeSetting;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x3705;MUX_MutexAlreadyLocked;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x3706;MUX_MutexNotFound;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x3707;MUX_MutexMaxLocks;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x3708;MUX_CurrThreadAlreadyOwnsMutex;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x3709;MUX_CurrThreadDoesNotOwnMutex;;9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x370a;MUX_MutexTimeout;;10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x370b;MUX_MutexInvalidId;;11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x370c;MUX_MutexDestroyedWhileWaiting;;12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF -0x3901;SPH_SemaphoreTimeout;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF -0x3902;SPH_SemaphoreNotOwned;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF -0x3903;SPH_SemaphoreInvalid;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF -0x2801;TC_InvalidTargetState;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF -0x28f1;TC_AboveOperationalLimit;;0xF1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF -0x28f2;TC_BelowOperationalLimit;;0xF2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF -0xc02;MS_InvalidEntry;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF -0xc03;MS_TooManyElements;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF -0xc04;MS_CantStoreEmpty;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF -0xd01;SS_SequenceAlreadyExists;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd02;SS_TableAlreadyExists;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd03;SS_TableDoesNotExist;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd04;SS_TableOrSequenceLengthInvalid;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd05;SS_SequenceDoesNotExist;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd06;SS_TableContainsInvalidObjectId;;0x06;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd07;SS_FallbackSequenceDoesNotExist;;0x07;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd08;SS_NoTargetTable;;0x08;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd09;SS_SequenceOrTableTooLong;;0x09;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd0b;SS_IsFallbackSequence;;0x0B;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd0c;SS_AccessDenied;;0x0C;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xd0e;SS_TableInUse;;0x0E;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xda1;SS_TargetTableNotReached;;0xA1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xda2;SS_TableCheckFailed;;0xA2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM -0xb01;SB_ChildNotFound;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0xb02;SB_ChildInfoUpdated;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0xb03;SB_ChildDoesntHaveModes;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0xb04;SB_CouldNotInsertChild;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0xb05;SB_TableContainsInvalidObjectId;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE -0x3c00;HKM_QueueOrDestinationInvalid;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c01;HKM_WrongHkPacketType;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c02;HKM_ReportingStatusUnchanged;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c03;HKM_PeriodicHelperInvalid;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c04;HKM_PoolobjectNotFound;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3c05;HKM_DatasetNotFound;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER -0x3a00;LPIF_PoolEntryNotFound;;0x00;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF -0x3a01;LPIF_PoolEntryTypeConflict;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF -0x3ba0;PVA_InvalidReadWriteMode;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/PoolVariableIF.h;POOL_VARIABLE_IF -0x3ba1;PVA_InvalidPoolEntry;;0xA1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/PoolVariableIF.h;POOL_VARIABLE_IF -0x801;DPS_InvalidParameterDefinition;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x802;DPS_SetWasAlreadyRead;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x803;DPS_CommitingWithoutReading;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x804;DPS_DataSetUninitialised;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x805;DPS_DataSetFull;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x806;DPS_PoolVarNull;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS -0x1000;TIM_UnsupportedTimeFormat;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1001;TIM_NotEnoughInformationForTargetFormat;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1002;TIM_LengthMismatch;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1003;TIM_InvalidTimeFormat;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1004;TIM_InvalidDayOfYear;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x1005;TIM_TimeDoesNotFitFormat;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS -0x3501;TSI_BadTimestamp;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/timemanager/TimeStamperIF.h;TIME_STAMPER_IF -0x1d01;PUS_ActivityStarted;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1d02;PUS_InvalidSubservice;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1d03;PUS_IllegalApplicationData;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1d04;PUS_SendTmFailed;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1d05;PUS_Timeout;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF -0x1f01;CSB_ExecutionComplete;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f02;CSB_NoStepMessage;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f03;CSB_ObjectBusy;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f04;CSB_Busy;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f05;CSB_InvalidTc;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f06;CSB_InvalidObject;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1f07;CSB_InvalidReply;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE -0x1101;AL_Full;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/ArrayList.h;ARRAY_LIST -0x1801;FF_Full;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FIFOBase.h;FIFO_CLASS -0x1802;FF_Empty;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FIFOBase.h;FIFO_CLASS -0x1601;FMM_MapFull;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedOrderedMultimap.h;FIXED_MULTIMAP -0x1602;FMM_KeyDoesNotExist;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedOrderedMultimap.h;FIXED_MULTIMAP -0x1501;FM_KeyAlreadyExists;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedMap.h;FIXED_MAP -0x1502;FM_MapFull;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedMap.h;FIXED_MAP -0x1503;FM_KeyDoesNotExist;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/container/FixedMap.h;FIXED_MAP -0x2401;EV_ListenerNotFound;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/events/EventManagerIF.h;EVENT_MANAGER_IF -0x1701;HHI_ObjectNotHealthy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h;HAS_HEALTH_IF -0x1702;HHI_InvalidHealthState;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h;HAS_HEALTH_IF -0x2f01;POS_InPowerTransition;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitcher.h;POWER_SWITCHER -0x2f02;POS_SwitchStateMismatch;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitcher.h;POWER_SWITCHER -0x501;PS_SwitchOn;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x500;PS_SwitchOff;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x502;PS_SwitchTimeout;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x503;PS_FuseOn;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x504;PS_FuseOff;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF -0x1a01;TRC_NotEnoughSensors;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x1a02;TRC_LowestValueOol;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x1a03;TRC_HighestValueOol;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x1a04;TRC_BothValuesOol;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x1a05;TRC_DuplexOol;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK -0x3001;LIM_Unchecked;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3002;LIM_Invalid;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3003;LIM_Unselected;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3004;LIM_BelowLowLimit;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3005;LIM_AboveHighLimit;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3006;LIM_UnexpectedValue;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x3007;LIM_OutOfRange;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30a0;LIM_FirstSample;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30e0;LIM_InvalidSize;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30e1;LIM_WrongType;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30e2;LIM_WrongPid;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30e3;LIM_WrongLimitId;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x30ee;LIM_MonitorNotFound;;0xEE;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF -0x4000;FILS_GenericFileError;;0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4001;FILS_IsBusy;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4002;FILS_InvalidParameters;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4005;FILS_FileDoesNotExist;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4006;FILS_FileAlreadyExists;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4007;FILS_FileLocked;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x400a;FILS_DirectoryDoesNotExist;;10;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x400b;FILS_DirectoryAlreadyExists;;11;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x400c;FILS_DirectoryNotEmpty;;12;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x400f;FILS_SequencePacketMissingWrite;;15;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x4010;FILS_SequencePacketMissingRead;;16;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM -0x601;PP_DoItMyself;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x602;PP_PointsToVariable;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x603;PP_PointsToMemory;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x604;PP_ActivityCompleted;;4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x605;PP_PointsToVectorUint8;;5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x606;PP_PointsToVectorUint16;;6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x607;PP_PointsToVectorUint32;;7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x608;PP_PointsToVectorFloat;;8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6a0;PP_DumpNotSupported;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e0;PP_InvalidSize;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e1;PP_InvalidAddress;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e2;PP_InvalidContent;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e3;PP_UnalignedAccess;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x6e4;PP_WriteProtected;;0xE4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF -0x13e0;MH_UnknownCmd;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER -0x13e1;MH_InvalidAddress;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER -0x13e2;MH_InvalidSize;;0xE2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER -0x13e3;MH_StateMismatch;;0xE3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER -0x1201;AB_NeedSecondStep;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x1202;AB_NeedToReconfigure;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x1203;AB_ModeFallback;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x1204;AB_ChildNotCommandable;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x1205;AB_NeedToChangeHealth;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x12a1;AB_NotEnoughChildrenInCorrectState;;0xa1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE -0x3a0;DHB_InvalidChannel;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3b0;DHB_AperiodicReply;;0xB0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3b1;DHB_IgnoreReplyData;;0xB1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3b2;DHB_IgnoreFullPacket;;0xB2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3c0;DHB_NothingToSend;;0xC0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3c2;DHB_CommandMapError;;0xC2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3d0;DHB_NoSwitch;;0xD0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3e0;DHB_ChildTimeout;;0xE0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3e1;DHB_SwitchFailed;;0xE1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE -0x3301;DC_NoReplyReceived;;0x01;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3302;DC_ProtocolError;;0x02;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3303;DC_Nullpointer;;0x03;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3304;DC_InvalidCookieType;;0x04;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3305;DC_NotActive;;0x05;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x3306;DC_TooMuchData;;0x06;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF -0x26a0;DHI_NoCommandData;;0xA0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a1;DHI_CommandNotSupported;;0xA1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a2;DHI_CommandAlreadySent;;0xA2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a3;DHI_CommandWasNotSent;;0xA3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a4;DHI_CantSwitchAddress;;0xA4;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a5;DHI_WrongModeForCommand;;0xA5;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a6;DHI_Timeout;;0xA6;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a7;DHI_Busy;;0xA7;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a8;DHI_NoReplyExpected;;0xA8;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26a9;DHI_NonOpTemperature;;0xA9;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26aa;DHI_CommandNotImplemented;;0xAA;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26b0;DHI_ChecksumError;;0xB0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26b1;DHI_LengthMissmatch;;0xB1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26b2;DHI_InvalidData;;0xB2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26b3;DHI_ProtocolError;;0xB3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26c0;DHI_DeviceDidNotExecute;;0xC0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26c1;DHI_DeviceReportedError;;0xC1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26c2;DHI_UnknownDeviceReply;;0xC2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26c3;DHI_DeviceReplyInvalid;;0xC3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26d0;DHI_InvalidCommandParameter;;0xD0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x26d1;DHI_InvalidNumberOrLengthOfParameters;;0xD1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF -0x1401;SE_BufferTooShort;;1;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF -0x1402;SE_StreamTooShort;;2;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF -0x1403;SE_TooManyElements;;3;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF -0x5f00;SDMA_AlreadyOn;;0;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x5f01;SDMA_AlreadyMounted;;1;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x5f02;SDMA_AlreadyOff;;2;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x5f0a;SDMA_StatusFileNexists;;10;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x5f0b;SDMA_StatusFileFormatInvalid;;11;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x5f0c;SDMA_MountError;;12;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x5f0d;SDMA_UnmountError;;13;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x5f0e;SDMA_SystemCallError;;14;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER -0x6000;SCBU_KeyNotFound;;0;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/scratchApi.h;SCRATCH_BUFFER -0x4ea1;HEATER_CommandNotSupported;;0xA1;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER -0x4ea2;HEATER_InitFailed;;0xA2;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER -0x4ea3;HEATER_InvalidSwitchNr;;0xA3;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER -0x4ea4;HEATER_MainSwitchSetTimeout;;0xA4;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER -0x4ea5;HEATER_CommandAlreadyWaiting;;0xA5;/home/rmueller/EIVE/eive-obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER -0x55a0;SUSS_ErrorUnlockMutex;;0xA0;/home/rmueller/EIVE/eive-obsw/linux/devices/SusHandler.h;SUS_HANDLER -0x55a1;SUSS_ErrorLockMutex;;0xA1;/home/rmueller/EIVE/eive-obsw/linux/devices/SusHandler.h;SUS_HANDLER -0x5ea0;SADPL_CommandNotSupported;;0xA0;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x5ea1;SADPL_DeploymentAlreadyExecuting;;0xA1;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x5ea2;SADPL_MainSwitchTimeoutFailure;;0xA2;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x5ea3;SADPL_SwitchingDeplSa1Failed;;0xA3;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x5ea4;SADPL_SwitchingDeplSa2Failed;;0xA4;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER -0x5e01;SADPL_UnknownGpioId;;1;/home/rmueller/EIVE/eive-obsw/linux/archive/gpio/LinuxLibgpioIF.h;SA_DEPL_HANDLER -0x5e02;SADPL_DriveGpioFailure;;2;/home/rmueller/EIVE/eive-obsw/linux/archive/gpio/LinuxLibgpioIF.h;SA_DEPL_HANDLER -0x5e03;SADPL_GpioTypeFailure;;3;/home/rmueller/EIVE/eive-obsw/linux/archive/gpio/LinuxLibgpioIF.h;SA_DEPL_HANDLER -0x5e04;SADPL_GpioInvalidInstance;;4;/home/rmueller/EIVE/eive-obsw/linux/archive/gpio/LinuxLibgpioIF.h;SA_DEPL_HANDLER -0x56a0;IPCI_PapbBusy;;0xA0;/home/rmueller/EIVE/eive-obsw/linux/obc/CCSDSIPCoreBridge.h;CCSDS_IP_CORE_BRIDGE +0x5e00;GOMS_PacketTooLong;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5e01;GOMS_InvalidTableId;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5e02;GOMS_InvalidAddress;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5e03;GOMS_InvalidParamSize;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5e04;GOMS_InvalidPayloadSize;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x5e05;GOMS_UnknownReplyId;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/GomspaceDeviceHandler.h;GOM_SPACE_HANDLER +0x50a0;IMTQ_InvalidCommandCode;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a1;IMTQ_ParameterMissing;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a2;IMTQ_ParameterInvalid;;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a3;IMTQ_CcUnavailable;;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a4;IMTQ_InternalProcessingError;;0xA4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a5;IMTQ_RejectedWithoutReason;;0xA5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a6;IMTQ_CmdErrUnknown;;0xA6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x50a7;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;0xA7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/IMTQHandler.h;IMTQ_HANDLER +0x53a0;PLMP_CrcFailure;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER +0x53a1;PLMP_ReceivedAckFailure;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER +0x53a2;PLMP_ReceivedExeFailure;;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER +0x53a3;PLMP_InvalidApid;;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocMPSoCHandler.h;PLOC_MPSOC_HANDLER +0x54a0;PLSV_CrcFailure;Space Packet received from PLOC supervisor has invalid CRC;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a1;PLSV_ReceivedAckFailure;Received ACK failure reply from PLOC supervisor;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a2;PLSV_ReceivedExeFailure;Received execution failure reply from PLOC supervisor;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a3;PLSV_InvalidApid;Received space packet with invalid APID from PLOC supervisor;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a4;PLSV_GetTimeFailure;Failed to read current system time;0xA4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a5;PLSV_InvalidUartComIf;Invalid communication interface specified;0xA5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a6;PLSV_InvalidWatchdog;Received command with invalid watchdog parameter. Valid watchdogs are 0 for PS, 1 for PL and 2 for INT;0xA6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a7;PLSV_InvalidWatchdogTimeout;Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms.;0xA7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a8;PLSV_InvalidLatchupId;Received latchup config command with invalid latchup ID;0xA8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54a9;PLSV_SweepPeriodTooSmall;Received set adc sweep period command with invalid sweep period. Must be larger than 21.;0xA9;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54aa;PLSV_InvalidTestParam;Receive auto EM test command with invalid test param. Valid params are 1 and 2.;0xAA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54ab;PLSV_MramPacketParsingFailure;Returned when scanning for MRAM dump packets failed.;0xAB;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54ac;PLSV_InvalidMramAddresses;Returned when the start and stop addresses of the MRAM dump or MRAM wipe commands are invalid (e.g. start address bigger than stop address);0xAC;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x54ad;PLSV_NoMramPacket;Expect reception of an MRAM dump packet but received space packet with other apid.;0xAD;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocSupervisorHandler.h;PLOC_SUPERVISOR_HANDLER +0x57a0;PLUD_UpdaterBusy;Updater is already performing an update;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h;PLOC_UPDATER +0x57a1;PLUD_NameTooLong;Received update command with invalid path string (too long).;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h;PLOC_UPDATER +0x57a2;PLUD_SdNotMounted;Received command to initiate update but SD card with update image not mounted.;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h;PLOC_UPDATER +0x57a3;PLUD_FileNotExists;Update file received with update command does not exist.;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/PlocUpdater.h;PLOC_UPDATER +0x51b0;RWHA_SpiWriteFailure;;0xB0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;0xB1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;0xB2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b3;RWHA_InvalidSubstitute;Can be used by the HDLC decoding mechanism to inform about an invalid substitution combination;0xB3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b4;RWHA_MissingEndSign;HDLC decoding mechanism never receives the end sign 0x7E;0xB4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51b5;RWHA_NoReply;Reaction wheel only responds with empty frames.;0xB5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a0;RWHA_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000; 1000] or [1000; 65000];0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a1;RWHA_InvalidRampTime;Action Message with invalid ramp time was received.;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a2;RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a3;RWHA_ExecutionFailed;Command execution failed;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x51a4;RWHA_CrcError;Reaction wheel reply has invalid crc;0xA4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/RwHandler.h;RW_HANDLER +0x52b0;STRH_CrcFailure;Received reply with invalid CRC;0xB0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/StarTrackerHandler.h;STR_HANDLER +0x52a0;STRH_TmReplyError;Result code of tm reply indicates an error;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/StarTrackerHandler.h;STR_HANDLER +0x4fa0;SYRLINKS_CrcFailure;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa1;SYRLINKS_UartFraminOrParityErrorAck;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa2;SYRLINKS_BadCharacterAck;;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa3;SYRLINKS_BadParameterValueAck;;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa4;SYRLINKS_BadEndOfFrameAck;;0xA4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa5;SYRLINKS_UnknownCommandIdAck;;0xA5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa6;SYRLINKS_BadCrcAck;;0xA6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa7;SYRLINKS_ReplyWrongSize;;0xA7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4fa8;SYRLINKS_MissingStartFrameCharacter;;0xA8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/mission/devices/SyrlinksHkHandler.h;SYRLINKS_HANDLER +0x4401;HGIO_UnknownGpioId;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4402;HGIO_DriveGpioFailure;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4403;HGIO_GpioTypeFailure;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4404;HGIO_GpioInvalidInstance;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h;HAL_GPIO +0x4100;HSPI_HalTimeoutRetval;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/stm32h7/spi/spiDefinitions.h;HAL_SPI +0x4101;HSPI_HalBusyRetval;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/stm32h7/spi/spiDefinitions.h;HAL_SPI +0x4102;HSPI_HalErrorRetval;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/stm32h7/spi/spiDefinitions.h;HAL_SPI +0x4201;HURT_UartReadFailure;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/linux/uart/UartComIF.h;HAL_UART +0x4202;HURT_UartReadSizeMissmatch;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/linux/uart/UartComIF.h;HAL_UART +0x4203;HURT_UartRxBufferTooSmall;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/hal/src/fsfw_hal/linux/uart/UartComIF.h;HAL_UART +0x3101;CF_ObjectHasNoFunctions;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/action/CommandsActionsIF.h;COMMANDS_ACTIONS_IF +0x3102;CF_AlreadyCommanding;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/action/CommandsActionsIF.h;COMMANDS_ACTIONS_IF +0x3201;HF_IsBusy;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF +0x3202;HF_InvalidParameters;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF +0x3203;HF_ExecutionFinished;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF +0x3204;HF_InvalidActionId;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/action/HasActionsIF.h;HAS_ACTIONS_IF +0x1101;AL_Full;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/container/ArrayList.h;ARRAY_LIST +0x1801;FF_Full;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/container/FIFOBase.h;FIFO_CLASS +0x1802;FF_Empty;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/container/FIFOBase.h;FIFO_CLASS +0x1501;FM_KeyAlreadyExists;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/container/FixedMap.h;FIXED_MAP +0x1502;FM_MapFull;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/container/FixedMap.h;FIXED_MAP +0x1503;FM_KeyDoesNotExist;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/container/FixedMap.h;FIXED_MAP +0x1601;FMM_MapFull;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/container/FixedOrderedMultimap.h;FIXED_MULTIMAP +0x1602;FMM_KeyDoesNotExist;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/container/FixedOrderedMultimap.h;FIXED_MULTIMAP +0x36a1;SGP4_InvalidEccentricity;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a2;SGP4_InvalidMeanMotion;;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a3;SGP4_InvalidPerturbationElements;;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a4;SGP4_InvalidSemiLatusRectum;;0xA4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a5;SGP4_InvalidEpochElements;;0xA5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36a6;SGP4_SatelliteHasDecayed;;0xA6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36b1;SGP4_TleTooOld;;0xB1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x36b2;SGP4_TleNotInitialized;;0xB2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/coordinates/Sgp4Propagator.h;SGP4PROPAGATOR_CLASS +0x2b01;CCS_BcIsSetVrCommand;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2b02;CCS_BcIsUnlockCommand;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bb0;CCS_BcIllegalCommand;;0xB0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bb1;CCS_BoardReadingNotFinished;;0xB1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf0;CCS_NsPositiveW;;0xF0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf1;CCS_NsNegativeW;;0xF1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf2;CCS_NsLockout;;0xF2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf3;CCS_FarmInLockout;;0xF3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bf4;CCS_FarmInWait;;0xF4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be0;CCS_WrongSymbol;;0xE0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be1;CCS_DoubleStart;;0xE1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be2;CCS_StartSymbolMissed;;0xE2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be3;CCS_EndWithoutStart;;0xE3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be4;CCS_TooLarge;;0xE4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be5;CCS_TooShort;;0xE5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be6;CCS_WrongTfVersion;;0xE6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be7;CCS_WrongSpacecraftId;;0xE7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be8;CCS_NoValidFrameType;;0xE8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2be9;CCS_CrcFailed;;0xE9;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bea;CCS_VcNotFound;;0xEA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2beb;CCS_ForwardingFailed;;0xEB;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bec;CCS_ContentTooLarge;;0xEC;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bed;CCS_ResidualData;;0xED;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bee;CCS_DataCorrupted;;0xEE;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bef;CCS_IllegalSegmentationFlag;;0xEF;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bd0;CCS_IllegalFlagCombination;;0xD0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bd1;CCS_ShorterThanHeader;;0xD1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bd2;CCS_TooShortBlockedPacket;;0xD2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x2bd3;CCS_TooShortMapExtraction;;0xD3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h;CCSDS_HANDLER_IF +0x801;DPS_InvalidParameterDefinition;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x802;DPS_SetWasAlreadyRead;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x803;DPS_CommitingWithoutReading;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x804;DPS_DataSetUninitialised;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x805;DPS_DataSetFull;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x806;DPS_PoolVarNull;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/DataSetIF.h;DATA_SET_CLASS +0x3ba0;PVA_InvalidReadWriteMode;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/PoolVariableIF.h;POOL_VARIABLE_IF +0x3ba1;PVA_InvalidPoolEntry;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapool/PoolVariableIF.h;POOL_VARIABLE_IF +0x3c00;HKM_QueueOrDestinationInvalid;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c01;HKM_WrongHkPacketType;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c02;HKM_ReportingStatusUnchanged;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c03;HKM_PeriodicHelperInvalid;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c04;HKM_PoolobjectNotFound;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3c05;HKM_DatasetNotFound;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h;HOUSEKEEPING_MANAGER +0x3a00;LPIF_PoolEntryNotFound;;0x00;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF +0x3a01;LPIF_PoolEntryTypeConflict;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h;LOCAL_POOL_OWNER_IF +0x1201;AB_NeedSecondStep;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x1202;AB_NeedToReconfigure;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x1203;AB_ModeFallback;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x1204;AB_ChildNotCommandable;;0x04;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x1205;AB_NeedToChangeHealth;;0x05;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x12a1;AB_NotEnoughChildrenInCorrectState;;0xa1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/AssemblyBase.h;ASSEMBLY_BASE +0x3301;DC_NoReplyReceived;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3302;DC_ProtocolError;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3303;DC_Nullpointer;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3304;DC_InvalidCookieType;;0x04;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3305;DC_NotActive;;0x05;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3306;DC_TooMuchData;;0x06;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h;DEVICE_COMMUNICATION_IF +0x3a0;DHB_InvalidChannel;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3b0;DHB_AperiodicReply;;0xB0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3b1;DHB_IgnoreReplyData;;0xB1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3b2;DHB_IgnoreFullPacket;;0xB2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3c0;DHB_NothingToSend;;0xC0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3c2;DHB_CommandMapError;;0xC2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3d0;DHB_NoSwitch;;0xD0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3e0;DHB_ChildTimeout;;0xE0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x3e1;DHB_SwitchFailed;;0xE1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h;DEVICE_HANDLER_BASE +0x26a0;DHI_NoCommandData;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a1;DHI_CommandNotSupported;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a2;DHI_CommandAlreadySent;;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a3;DHI_CommandWasNotSent;;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a4;DHI_CantSwitchAddress;;0xA4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a5;DHI_WrongModeForCommand;;0xA5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a6;DHI_Timeout;;0xA6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a7;DHI_Busy;;0xA7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a8;DHI_NoReplyExpected;;0xA8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26a9;DHI_NonOpTemperature;;0xA9;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26aa;DHI_CommandNotImplemented;;0xAA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26b0;DHI_ChecksumError;;0xB0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26b1;DHI_LengthMissmatch;;0xB1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26b2;DHI_InvalidData;;0xB2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26b3;DHI_ProtocolError;;0xB3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26c0;DHI_DeviceDidNotExecute;;0xC0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26c1;DHI_DeviceReportedError;;0xC1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26c2;DHI_UnknownDeviceReply;;0xC2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26c3;DHI_DeviceReplyInvalid;;0xC3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26d0;DHI_InvalidCommandParameter;;0xD0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x26d1;DHI_InvalidNumberOrLengthOfParameters;;0xD1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h;DEVICE_HANDLER_IF +0x2401;EV_ListenerNotFound;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/events/EventManagerIF.h;EVENT_MANAGER_IF +0x2500;FDI_YourFault;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF +0x2501;FDI_MyFault;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF +0x2502;FDI_ConfirmLater;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h;HANDLES_FAILURES_IF +0x2301;MT_TooDetailedRequest;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x2302;MT_TooGeneralRequest;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x2303;MT_NoMatch;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x2304;MT_Full;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x2305;MT_NewNodeCreated;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/matching/MatchTree.h;MATCH_TREE_CLASS +0x2e01;ASC_TooLongForTargetType;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER +0x2e02;ASC_InvalidCharacters;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER +0x2e03;ASC_BufferTooSmall;;0x3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/AsciiConverter.h;ASCII_CONVERTER +0x3d01;DLEE_StreamTooShort;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/DleEncoder.h;DLE_ENCODER +0x3d02;DLEE_DecodingError;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/globalfunctions/DleEncoder.h;DLE_ENCODER +0x1701;HHI_ObjectNotHealthy;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h;HAS_HEALTH_IF +0x1702;HHI_InvalidHealthState;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h;HAS_HEALTH_IF +0xf01;CM_UnknownCommand;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/CommandMessageIF.h;COMMAND_MESSAGE +0x3801;MQI_Empty;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF +0x3802;MQI_Full;No space left for more messages;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF +0x3803;MQI_NoReplyPartner;Returned if a reply method was called without partner;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF +0x3804;MQI_DestinationInvalid;Returned if the target destination is invalid.;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MessageQueueIF.h;MESSAGE_QUEUE_IF +0x3701;MUX_NotEnoughResources;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3702;MUX_InsufficientMemory;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3703;MUX_NoPrivilege;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3704;MUX_WrongAttributeSetting;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3705;MUX_MutexAlreadyLocked;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3706;MUX_MutexNotFound;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3707;MUX_MutexMaxLocks;;7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3708;MUX_CurrThreadAlreadyOwnsMutex;;8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x3709;MUX_CurrThreadDoesNotOwnMutex;;9;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x370a;MUX_MutexTimeout;;10;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x370b;MUX_MutexInvalidId;;11;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x370c;MUX_MutexDestroyedWhileWaiting;;12;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/ipc/MutexIF.h;MUTEX_IF +0x4000;FILS_GenericFileError;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4001;FILS_IsBusy;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4002;FILS_InvalidParameters;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4005;FILS_FileDoesNotExist;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4006;FILS_FileAlreadyExists;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4007;FILS_FileLocked;;7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x400a;FILS_DirectoryDoesNotExist;;10;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x400b;FILS_DirectoryAlreadyExists;;11;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x400c;FILS_DirectoryNotEmpty;;12;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x400f;FILS_SequencePacketMissingWrite;;15;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x4010;FILS_SequencePacketMissingRead;;16;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasFileSystemIF.h;FILE_SYSTEM +0x601;PP_DoItMyself;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x602;PP_PointsToVariable;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x603;PP_PointsToMemory;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x604;PP_ActivityCompleted;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x605;PP_PointsToVectorUint8;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x606;PP_PointsToVectorUint16;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x607;PP_PointsToVectorUint32;;7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x608;PP_PointsToVectorFloat;;8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6a0;PP_DumpNotSupported;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e0;PP_InvalidSize;;0xE0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e1;PP_InvalidAddress;;0xE1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e2;PP_InvalidContent;;0xE2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e3;PP_UnalignedAccess;;0xE3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x6e4;PP_WriteProtected;;0xE4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/HasMemoryIF.h;HAS_MEMORY_IF +0x13e0;MH_UnknownCmd;;0xE0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER +0x13e1;MH_InvalidAddress;;0xE1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER +0x13e2;MH_InvalidSize;;0xE2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER +0x13e3;MH_StateMismatch;;0xE3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/memory/MemoryHelper.h;MEMORY_HELPER +0xe01;HM_InvalidMode;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF +0xe02;HM_TransNotAllowed;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF +0xe03;HM_InTransition;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF +0xe04;HM_InvalidSubmode;;0x04;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h;HAS_MODES_IF +0x3001;LIM_Unchecked;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3002;LIM_Invalid;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3003;LIM_Unselected;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3004;LIM_BelowLowLimit;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3005;LIM_AboveHighLimit;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3006;LIM_UnexpectedValue;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x3007;LIM_OutOfRange;;7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30a0;LIM_FirstSample;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30e0;LIM_InvalidSize;;0xE0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30e1;LIM_WrongType;;0xE1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30e2;LIM_WrongPid;;0xE2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30e3;LIM_WrongLimitId;;0xE3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x30ee;LIM_MonitorNotFound;;0xEE;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h;LIMITS_IF +0x1a01;TRC_NotEnoughSensors;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x1a02;TRC_LowestValueOol;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x1a03;TRC_HighestValueOol;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x1a04;TRC_BothValuesOol;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x1a05;TRC_DuplexOol;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/monitoring/TriplexMonitor.h;TRIPLE_REDUNDACY_CHECK +0x201;OM_InsertionFailed;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF +0x202;OM_NotFound;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF +0x203;OM_ChildInitFailed;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF +0x204;OM_InternalErrReporterUninit;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/objectmanager/ObjectManagerIF.h;OBJECT_MANAGER_IF +0x2901;IEC_NoConfigurationTable;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2902;IEC_NoCpuTable;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2903;IEC_InvalidWorkspaceAddress;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2904;IEC_TooLittleWorkspace;;0x04;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2905;IEC_WorkspaceAllocation;;0x05;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2906;IEC_InterruptStackTooSmall;;0x06;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2907;IEC_ThreadExitted;;0x07;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2908;IEC_InconsistentMpInformation;;0x08;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2909;IEC_InvalidNode;;0x09;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290a;IEC_NoMpci;;0x0a;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290b;IEC_BadPacket;;0x0b;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290c;IEC_OutOfPackets;;0x0c;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290d;IEC_OutOfGlobalObjects;;0x0d;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290e;IEC_OutOfProxies;;0x0e;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x290f;IEC_InvalidGlobalId;;0x0f;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2910;IEC_BadStackHook;;0x10;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2911;IEC_BadAttributes;;0x11;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2912;IEC_ImplementationKeyCreateInconsistency;;0x12;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2913;IEC_ImplementationBlockingOperationCancel;;0x13;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2914;IEC_MutexObtainFromBadState;;0x14;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2915;IEC_UnlimitedAndMaximumIs0;;0x15;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/osal/InternalErrorCodes.h;INTERNAL_ERROR_CODES +0x2d01;HPA_InvalidIdentifierId;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF +0x2d02;HPA_InvalidDomainId;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF +0x2d03;HPA_InvalidValue;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF +0x2d05;HPA_ReadOnly;;0x05;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/HasParametersIF.h;HAS_PARAMETERS_IF +0x2c01;PAW_UnknownDatatype;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c02;PAW_DatatypeMissmatch;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c03;PAW_Readonly;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c04;PAW_TooBig;;0x04;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c05;PAW_SourceNotSet;;0x05;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c06;PAW_OutOfBounds;;0x06;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c07;PAW_NotSet;;0x07;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2c08;PAW_ColumnOrRowsZero;;0x08;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/parameters/ParameterWrapper.h;PARAMETER_WRAPPER +0x2f01;POS_InPowerTransition;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitcher.h;POWER_SWITCHER +0x2f02;POS_SwitchStateMismatch;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitcher.h;POWER_SWITCHER +0x501;PS_SwitchOn;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x500;PS_SwitchOff;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x502;PS_SwitchTimeout;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x503;PS_FuseOn;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x504;PS_FuseOff;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h;POWER_SWITCH_IF +0x4e1;RMP_CommandNoDescriptorsAvailable;;0xE1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e2;RMP_CommandBufferFull;;0xE2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e3;RMP_CommandChannelOutOfRange;;0xE3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e6;RMP_CommandChannelDeactivated;;0xE6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e7;RMP_CommandPortOutOfRange;;0xE7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e8;RMP_CommandPortInUse;;0xE8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4e9;RMP_CommandNoChannel;;0xE9;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4ea;RMP_NoHwCrc;;0xEA;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d0;RMP_ReplyNoReply;;0xD0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d1;RMP_ReplyNotSent;;0xD1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d2;RMP_ReplyNotYetSent;;0xD2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d3;RMP_ReplyMissmatch;;0xD3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4d4;RMP_ReplyTimeout;;0xD4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4c0;RMP_ReplyInterfaceBusy;;0xC0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4c1;RMP_ReplyTransmissionError;;0xC1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4c2;RMP_ReplyInvalidData;;0xC2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4c3;RMP_ReplyNotSupported;;0xC3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f0;RMP_LinkDown;;0xF0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f1;RMP_SpwCredit;;0xF1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f2;RMP_SpwEscape;;0xF2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f3;RMP_SpwDisconnect;;0xF3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f4;RMP_SpwParity;;0xF4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f5;RMP_SpwWriteSync;;0xF5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f6;RMP_SpwInvalidAddress;;0xF6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f7;RMP_SpwEarlyEop;;0xF7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f8;RMP_SpwDma;;0xF8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x4f9;RMP_SpwLinkError;;0xF9;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x400;RMP_ReplyOk;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x401;RMP_ReplyGeneralErrorCode;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x402;RMP_ReplyUnusedPacketTypeOrCommandCode;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x403;RMP_ReplyInvalidKey;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x404;RMP_ReplyInvalidDataCrc;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x405;RMP_ReplyEarlyEop;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x406;RMP_ReplyTooMuchData;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x407;RMP_ReplyEep;;7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x408;RMP_ReplyReserved;;8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x409;RMP_ReplyVerifyBufferOverrun;;9;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x40a;RMP_ReplyCommandNotImplementedOrNotAuthorised;;10;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x40b;RMP_ReplyRmwDataLengthError;;11;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x40c;RMP_ReplyInvalidTargetLogicalAddress;;12;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/rmap/RMAP.h;RMAP_CHANNEL +0x1401;SE_BufferTooShort;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF +0x1402;SE_StreamTooShort;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF +0x1403;SE_TooManyElements;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/serialize/SerializeIF.h;SERIALIZE_IF +0x2701;SM_DataTooLarge;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2702;SM_DataStorageFull;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2703;SM_IllegalStorageId;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2704;SM_DataDoesNotExist;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2705;SM_IllegalAddress;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0x2706;SM_PoolTooLarge;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h;STORAGE_MANAGER_IF +0xc02;MS_InvalidEntry;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF +0xc03;MS_TooManyElements;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF +0xc04;MS_CantStoreEmpty;;0x04;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h;MODE_STORE_IF +0xd01;SS_SequenceAlreadyExists;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd02;SS_TableAlreadyExists;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd03;SS_TableDoesNotExist;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd04;SS_TableOrSequenceLengthInvalid;;0x04;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd05;SS_SequenceDoesNotExist;;0x05;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd06;SS_TableContainsInvalidObjectId;;0x06;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd07;SS_FallbackSequenceDoesNotExist;;0x07;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd08;SS_NoTargetTable;;0x08;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd09;SS_SequenceOrTableTooLong;;0x09;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd0b;SS_IsFallbackSequence;;0x0B;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd0c;SS_AccessDenied;;0x0C;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xd0e;SS_TableInUse;;0x0E;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xda1;SS_TargetTableNotReached;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xda2;SS_TableCheckFailed;;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/Subsystem.h;SUBSYSTEM +0xb01;SB_ChildNotFound;;0x01;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0xb02;SB_ChildInfoUpdated;;0x02;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0xb03;SB_ChildDoesntHaveModes;;0x03;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0xb04;SB_CouldNotInsertChild;;0x04;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0xb05;SB_TableContainsInvalidObjectId;;0x05;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/subsystem/SubsystemBase.h;SUBSYSTEM_BASE +0x3901;SPH_SemaphoreTimeout;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF +0x3902;SPH_SemaphoreNotOwned;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF +0x3903;SPH_SemaphoreInvalid;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tasks/SemaphoreIF.h;SEMAPHORE_IF +0x1c01;TCD_PacketLost;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION +0x1c02;TCD_DestinationNotFound;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION +0x1c03;TCD_ServiceIdAlreadyExists;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcDistributor.h;PACKET_DISTRIBUTION +0x1b00;TCC_IllegalApid;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b01;TCC_IncompletePacket;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b02;TCC_IncorrectChecksum;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b03;TCC_IllegalPacketType;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b04;TCC_IllegalPacketSubtype;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b05;TCC_IncorrectPrimaryHeader;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x1b06;TCC_IncorrectSecondaryHeader;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tcdistribution/TcPacketCheck.h;TC_PACKET_CHECK +0x2801;TC_InvalidTargetState;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF +0x28f1;TC_AboveOperationalLimit;;0xF1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF +0x28f2;TC_BelowOperationalLimit;;0xF2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h;THERMAL_COMPONENT_IF +0x1000;TIM_UnsupportedTimeFormat;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1001;TIM_NotEnoughInformationForTargetFormat;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1002;TIM_LengthMismatch;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1003;TIM_InvalidTimeFormat;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1004;TIM_InvalidDayOfYear;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x1005;TIM_TimeDoesNotFitFormat;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/timemanager/CCSDSTime.h;CCSDS_TIME_HELPER_CLASS +0x3501;TSI_BadTimestamp;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/timemanager/TimeStamperIF.h;TIME_STAMPER_IF +0x2001;TMB_Busy;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2002;TMB_Full;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2003;TMB_Empty;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2004;TMB_NullRequested;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2005;TMB_TooLarge;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2006;TMB_NotReady;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2007;TMB_DumpError;;7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2008;TMB_CrcError;;8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2009;TMB_Timeout;;9;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200a;TMB_IdlePacketFound;;10;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200b;TMB_TelecommandFound;;11;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200c;TMB_NoPusATm;;12;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200d;TMB_TooSmall;;13;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200e;TMB_BlockNotFound;;14;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x200f;TMB_InvalidRequest;;15;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h;TM_STORE_BACKEND_IF +0x2101;TMF_Busy;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2102;TMF_LastPacketFound;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2103;TMF_StopFetch;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2104;TMF_Timeout;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2105;TMF_TmChannelFull;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2106;TMF_NotStored;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2107;TMF_AllDeleted;;7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2108;TMF_InvalidData;;8;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x2109;TMF_NotReady;;9;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h;TM_STORE_FRONTEND_IF +0x1d01;PUS_ActivityStarted;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1d02;PUS_InvalidSubservice;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1d03;PUS_IllegalApplicationData;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1d04;PUS_SendTmFailed;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1d05;PUS_Timeout;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h;ACCEPTS_TELECOMMANDS_IF +0x1f01;CSB_ExecutionComplete;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f02;CSB_NoStepMessage;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f03;CSB_ObjectBusy;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f04;CSB_Busy;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f05;CSB_InvalidTc;;5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f06;CSB_InvalidObject;;6;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x1f07;CSB_InvalidReply;;7;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h;COMMAND_SERVICE_BASE +0x6100;SCBU_KeyNotFound;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/scratchApi.h;SCRATCH_BUFFER +0x6000;SDMA_AlreadyOn;;0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x6001;SDMA_UnknownGpioId;;1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/archive/gpio/LinuxLibgpioIF.h;SD_CARD_MANAGER +0x6002;SDMA_DriveGpioFailure;;2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/archive/gpio/LinuxLibgpioIF.h;SD_CARD_MANAGER +0x600a;SDMA_StatusFileNexists;;10;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x600b;SDMA_StatusFileFormatInvalid;;11;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x600c;SDMA_MountError;;12;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x600d;SDMA_UnmountError;;13;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x600e;SDMA_SystemCallError;;14;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/bsp_q7s/memory/SdCardManager.h;SD_CARD_MANAGER +0x6003;SDMA_GpioTypeFailure;;3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/archive/gpio/LinuxLibgpioIF.h;SD_CARD_MANAGER +0x6004;SDMA_GpioInvalidInstance;;4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/archive/gpio/LinuxLibgpioIF.h;SD_CARD_MANAGER +0x4ea1;HEATER_CommandNotSupported;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x4ea2;HEATER_InitFailed;;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x4ea3;HEATER_InvalidSwitchNr;;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x4ea4;HEATER_MainSwitchSetTimeout;;0xA4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x4ea5;HEATER_CommandAlreadyWaiting;;0xA5;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/HeaterHandler.h;HEATER_HANDLER +0x5fa0;SADPL_CommandNotSupported;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5fa1;SADPL_DeploymentAlreadyExecuting;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5fa2;SADPL_MainSwitchTimeoutFailure;;0xA2;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5fa3;SADPL_SwitchingDeplSa1Failed;;0xA3;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x5fa4;SADPL_SwitchingDeplSa2Failed;;0xA4;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SolarArrayDeploymentHandler.h;SA_DEPL_HANDLER +0x55a0;SUSS_ErrorUnlockMutex;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SusHandler.h;SUS_HANDLER +0x55a1;SUSS_ErrorLockMutex;;0xA1;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/devices/SusHandler.h;SUS_HANDLER +0x56a0;IPCI_PapbBusy;;0xA0;C:\Users\jakob\Work\EIVE\Q7S\Software\eive_obsw/linux/obc/CCSDSIPCoreBridge.h;CCSDS_IP_CORE_BRIDGE diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 0df84ad2..1df1d949 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 96 translations. + * @brief Auto-generated event translation file. Contains 102 translations. * @details - * Generated on: 2021-08-02 11:41:47 + * Generated on: 2021-08-07 18:11:16 */ #include "translateEvents.h" @@ -101,6 +101,12 @@ const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_ const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE"; const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE"; const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT"; +const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS"; +const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED"; +const char *UPDATE_AVAILABLE_FAILED_STRING = "UPDATE_AVAILABLE_FAILED"; +const char *UPDATE_TRANSFER_FAILED_STRING = "UPDATE_TRANSFER_FAILED"; +const char *UPDATE_VERIFY_FAILED_STRING = "UPDATE_VERIFY_FAILED"; +const char *UPDATE_FINISHED_STRING = "UPDATE_FINISHED"; const char * translateEvents(Event event) { switch( (event & 0xffff) ) { @@ -296,6 +302,18 @@ const char * translateEvents(Event event) { return SUPV_EXE_FAILURE_STRING; case(11504): return SUPV_CRC_FAILURE_EVENT_STRING; + case(11700): + return UPDATE_FILE_NOT_EXISTS_STRING; + case(11701): + return ACTION_COMMANDING_FAILED_STRING; + case(11702): + return UPDATE_AVAILABLE_FAILED_STRING; + case(11703): + return UPDATE_TRANSFER_FAILED_STRING; + case(11704): + return UPDATE_VERIFY_FAILED_STRING; + case(11705): + return UPDATE_FINISHED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 7be16027..e5cc5b67 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 103 translations. - * Generated on: 2021-08-02 13:00:48 + * Contains 104 translations. + * Generated on: 2021-08-07 18:08:35 */ #include "translateObjects.h" @@ -45,6 +45,7 @@ const char *PDU1_HANDLER_STRING = "PDU1_HANDLER"; const char *PDU2_HANDLER_STRING = "PDU2_HANDLER"; const char *ACU_HANDLER_STRING = "ACU_HANDLER"; const char *RAD_SENSOR_STRING = "RAD_SENSOR"; +const char *PLOC_UPDATER_STRING = "PLOC_UPDATER"; const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER"; const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER"; const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER"; @@ -190,6 +191,8 @@ const char* translateObject(object_id_t object) { return ACU_HANDLER_STRING; case 0x443200A5: return RAD_SENSOR_STRING; + case 0x44330000: + return PLOC_UPDATER_STRING; case 0x44330015: return PLOC_MPSOC_HANDLER_STRING; case 0x44330016: diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 0df84ad2..1df1d949 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 96 translations. + * @brief Auto-generated event translation file. Contains 102 translations. * @details - * Generated on: 2021-08-02 11:41:47 + * Generated on: 2021-08-07 18:11:16 */ #include "translateEvents.h" @@ -101,6 +101,12 @@ const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_ const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE"; const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE"; const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT"; +const char *UPDATE_FILE_NOT_EXISTS_STRING = "UPDATE_FILE_NOT_EXISTS"; +const char *ACTION_COMMANDING_FAILED_STRING = "ACTION_COMMANDING_FAILED"; +const char *UPDATE_AVAILABLE_FAILED_STRING = "UPDATE_AVAILABLE_FAILED"; +const char *UPDATE_TRANSFER_FAILED_STRING = "UPDATE_TRANSFER_FAILED"; +const char *UPDATE_VERIFY_FAILED_STRING = "UPDATE_VERIFY_FAILED"; +const char *UPDATE_FINISHED_STRING = "UPDATE_FINISHED"; const char * translateEvents(Event event) { switch( (event & 0xffff) ) { @@ -296,6 +302,18 @@ const char * translateEvents(Event event) { return SUPV_EXE_FAILURE_STRING; case(11504): return SUPV_CRC_FAILURE_EVENT_STRING; + case(11700): + return UPDATE_FILE_NOT_EXISTS_STRING; + case(11701): + return ACTION_COMMANDING_FAILED_STRING; + case(11702): + return UPDATE_AVAILABLE_FAILED_STRING; + case(11703): + return UPDATE_TRANSFER_FAILED_STRING; + case(11704): + return UPDATE_VERIFY_FAILED_STRING; + case(11705): + return UPDATE_FINISHED_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/linux/fsfwconfig/objects/systemObjectList.h b/linux/fsfwconfig/objects/systemObjectList.h index eb5333c2..a8929187 100644 --- a/linux/fsfwconfig/objects/systemObjectList.h +++ b/linux/fsfwconfig/objects/systemObjectList.h @@ -62,7 +62,7 @@ enum sourceObjects: uint32_t { UART_TEST = 0x54000020, DUMMY_INTERFACE = 0x5400CAFE, DUMMY_HANDLER = 0x5400AFFE, - P60DOCK_TEST_TASK = 0x00005060 + P60DOCK_TEST_TASK = 0x00005060, }; } diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 7be16027..e5cc5b67 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 103 translations. - * Generated on: 2021-08-02 13:00:48 + * Contains 104 translations. + * Generated on: 2021-08-07 18:08:35 */ #include "translateObjects.h" @@ -45,6 +45,7 @@ const char *PDU1_HANDLER_STRING = "PDU1_HANDLER"; const char *PDU2_HANDLER_STRING = "PDU2_HANDLER"; const char *ACU_HANDLER_STRING = "ACU_HANDLER"; const char *RAD_SENSOR_STRING = "RAD_SENSOR"; +const char *PLOC_UPDATER_STRING = "PLOC_UPDATER"; const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER"; const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER"; const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER"; @@ -190,6 +191,8 @@ const char* translateObject(object_id_t object) { return ACU_HANDLER_STRING; case 0x443200A5: return RAD_SENSOR_STRING; + case 0x44330000: + return PLOC_UPDATER_STRING; case 0x44330015: return PLOC_MPSOC_HANDLER_STRING; case 0x44330016: diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 409a48c5..778d8925 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -1,3 +1,8 @@ +#include +#include +#include +#include + #include "PlocSupervisorHandler.h" #include "OBSWConfig.h" @@ -28,6 +33,9 @@ ReturnValue_t PlocSupervisorHandler::initialize() { sif::warning << "PlocSupervisorHandler::initialize: Invalid uart com if" << std::endl; return INVALID_UART_COM_IF; } + + sdcMan = SdCardManager::instance(); + return result; } @@ -112,11 +120,6 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( prepareEmptyCmd(PLOC_SPV::APID_GET_BOOT_STATUS_RPT); result = RETURN_OK; break; - } - case(PLOC_SPV::UPDATE_AVAILABLE): { - prepareUpdateAvailableCmd(commandData); - result = RETURN_OK; - break; } case(PLOC_SPV::WATCHDOGS_ENABLE): { prepareWatchdogsEnableCmd(commandData); @@ -207,6 +210,11 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( prepareSetDbgVerbosityCmd(commandData); result = RETURN_OK; break; + } + case(PLOC_SPV::CAN_LOOPBACK_TEST): { + prepareEmptyCmd(PLOC_SPV::APID_CAN_LOOPBACK_TEST); + result = RETURN_OK; + break; } case(PLOC_SPV::SET_GPIO): { prepareSetGpioCmd(commandData); @@ -242,10 +250,14 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( break; } case(PLOC_SPV::UPDATE_AVAILABLE): - case(PLOC_SPV::UPDATE_AVAILABLE): - case(PLOC_SPV::UPDATE_AVAILABLE): + case(PLOC_SPV::UPDATE_IMAGE_DATA): + case(PLOC_SPV::UPDATE_VERIFY): // Simply forward data from PLOC Updater to supervisor - std::memcpy(rawPacket, commandData, commandDataLen); + std::memcpy(commandBuffer, commandData, commandDataLen); + rawPacket = commandBuffer; + rawPacketLen = commandDataLen; + nextReplyId = PLOC_SPV::ACK_REPORT; + result = RETURN_OK; break; default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -277,6 +289,8 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::DISABLE_PERIOIC_HK_TRANSMISSION); this->insertInCommandMap(PLOC_SPV::GET_BOOT_STATUS_REPORT); this->insertInCommandMap(PLOC_SPV::UPDATE_AVAILABLE); + this->insertInCommandMap(PLOC_SPV::UPDATE_VERIFY); + this->insertInCommandMap(PLOC_SPV::UPDATE_IMAGE_DATA); this->insertInCommandMap(PLOC_SPV::WATCHDOGS_ENABLE); this->insertInCommandMap(PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT); this->insertInCommandMap(PLOC_SPV::ENABLE_LATCHUP_ALERT); @@ -302,6 +316,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_ALL); this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR); this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR); + this->insertInCommandMap(PLOC_SPV::CAN_LOOPBACK_TEST); this->insertInCommandAndReplyMap(PLOC_SPV::DUMP_MRAM, 3); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); @@ -512,6 +527,8 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite case PLOC_SPV::RESET_MPSOC: case PLOC_SPV::SET_TIME_REF: case PLOC_SPV::UPDATE_AVAILABLE: + case PLOC_SPV::UPDATE_IMAGE_DATA: + case PLOC_SPV::UPDATE_VERIFY: case PLOC_SPV::WATCHDOGS_ENABLE: case PLOC_SPV::WATCHDOGS_CONFIG_TIMEOUT: case PLOC_SPV::ENABLE_LATCHUP_ALERT: @@ -1010,26 +1027,6 @@ void PlocSupervisorHandler::prepareRestartTriesCmd(const uint8_t * commandData) packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); } -void PlocSupervisorHandler::prepareUpdateAvailableCmd(const uint8_t * commandData) { - uint8_t offset = 0; - uint8_t imageSelect = *(commandData + offset); - offset += 1; - uint8_t imagePartition = *(commandData + offset); - offset += 1; - uint32_t imageSize = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 - | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); - offset += 4; - uint32_t imageCrc = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 - | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); - offset += 4; - uint32_t numberOfPackets = *(commandData + offset) << 24 | *(commandData + offset + 1) << 16 - | *(commandData + offset + 2) << 8 | *(commandData + offset + 3); - - PLOC_SPV::UpdateAvailable packet(imageSelect, imagePartition, imageSize, imageCrc, - numberOfPackets); - packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); -} - void PlocSupervisorHandler::prepareWatchdogsEnableCmd(const uint8_t * commandData) { uint8_t offset = 0; uint8_t watchdogPs = *(commandData + offset); @@ -1321,7 +1318,7 @@ ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t *packet, siz bufferTop += 1; *foundLen += 1; if (bufferTop >= PLOC_SPV::SPACE_PACKET_HEADER_LENGTH) { - packetLen = spacePacketBuffer[4] << 8 | spacePacketBuffer[5]; + packetLen = readSpacePacketLength(spacePacketBuffer); } if (bufferTop == PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1) { @@ -1347,15 +1344,17 @@ ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket() { // Prepare packet for downlink if (packetInBuffer) { - uint16_t packetLen = spacePacketBuffer[4] << 8 | spacePacketBuffer[5]; + uint16_t packetLen = readSpacePacketLength(spacePacketBuffer); result = verifyPacket(spacePacketBuffer, PLOC_SPV::SPACE_PACKET_HEADER_LENGTH + packetLen + 1); if (result != RETURN_OK) { sif::warning << "PlocSupervisorHandler::handleMramDumpPacket: CRC failure" << std::endl; return result; } - //TODO: Write MRAM dump to SD card handler - handleDeviceTM(spacePacketBuffer + PLOC_SPV::SPACE_PACKET_HEADER_LENGTH, packetLen - 1, - PLOC_SPV::DUMP_MRAM); + handleMramDumpFile(); + if (downlinkMramDump == true) { + handleDeviceTM(spacePacketBuffer + PLOC_SPV::SPACE_PACKET_HEADER_LENGTH, packetLen - 1, + PLOC_SPV::DUMP_MRAM); + } packetInBuffer = false; receivedMramDumpPackets++; if (expectedMramDumpPackets == receivedMramDumpPackets) { @@ -1422,3 +1421,73 @@ ReturnValue_t PlocSupervisorHandler::checkMramPacketApid() { } return APERIODIC_REPLY; } + +ReturnValue_t PlocSupervisorHandler::handleMramDumpFile() { + ReturnValue_t result = RETURN_OK; + uint16_t packetLen = readSpacePacketLength(spacePacketBuffer); + uint8_t sequenceFlags = readSequenceFlags(spacePacketBuffer); + if (sequenceFlags == static_cast(PLOC_SPV::SequenceFlags::FIRST_PKT)) { + result = createMramDumpFile(); + if (result != RETURN_OK) { + return result; + } + } + if (not std::filesystem::exists(activeMramFile)) { + sif::warning << "PlocSupervisorHandler::handleMramDumpFile: MRAM file does not exist" + << std::endl; + return MRAM_FILE_NOT_EXISTS; + } + std::ofstream file(activeMramFile, std::ios_base::app | std::ios_base::out); + file.write( + reinterpret_cast(spacePacketBuffer + PLOC_SPV::SPACE_PACKET_HEADER_LENGTH), + packetLen - 1); + file.close(); + return RETURN_OK; +} + +uint16_t PlocSupervisorHandler::readSpacePacketLength(uint8_t* spacePacket) { + return spacePacket[4] << 8 | spacePacket[5]; +} + +uint8_t PlocSupervisorHandler::readSequenceFlags(uint8_t* spacePacket) { + return spacePacketBuffer[2] >> 6; +} + +ReturnValue_t PlocSupervisorHandler::createMramDumpFile() { + ReturnValue_t result = RETURN_OK; + std::string timeStamp; + result = getTimeStampString(timeStamp); + if (result != RETURN_OK) { + return result; + } + + std::string filename = "mram-dump--" + timeStamp + ".bin"; + std::string currentMountPrefix = sdcMan->getCurrentMountPrefix(); + + // Check if path to PLOC directory exists + if (not std::filesystem::exists(std::string(currentMountPrefix + "/" + plocFilePath))) { + sif::warning << "PlocSupervisorHandler::createMramDumpFile: Ploc path does not exist" + << std::endl; + return PATH_DOES_NOT_EXIST; + } + activeMramFile = currentMountPrefix + "/" + plocFilePath + "/" + filename; + // Create new file + std::ofstream file(activeMramFile, std::ios_base::out); + file.close(); + + return RETURN_OK; +} + +ReturnValue_t PlocSupervisorHandler::getTimeStampString(std::string& timeStamp) { + Clock::TimeOfDay_t time; + ReturnValue_t result = Clock::getDateAndTime(&time); + if (result != RETURN_OK) { + sif::warning << "PlocSupervisorHandler::createMramDumpFile: Failed to get current time" + << std::endl; + return GET_TIME_FAILURE; + } + timeStamp = std::to_string(time.year) + "-" + std::to_string(time.month) + "-" + + std::to_string(time.day) + "--" + std::to_string(time.hour) + "-" + + std::to_string(time.minute) + "-" + std::to_string(time.second); + return RETURN_OK; +} diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index c98cb37c..950ac894 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -3,8 +3,8 @@ #include #include -#include #include +#include /** * @brief This is the device handler for the supervisor of the PLOC which is programmed by @@ -79,6 +79,10 @@ private: static const ReturnValue_t INVALID_MRAM_ADDRESSES = MAKE_RETURN_CODE(0xAC); //! [EXPORT] : [COMMENT] Expect reception of an MRAM dump packet but received space packet with other apid. static const ReturnValue_t NO_MRAM_PACKET = MAKE_RETURN_CODE(0xAD); + //! [EXPORT] : [COMMENT] Path to PLOC directory on SD card does not exist + static const ReturnValue_t PATH_DOES_NOT_EXIST = MAKE_RETURN_CODE(0xAE); + //! [EXPORT] : [COMMENT] MRAM dump file does not exists. The file should actually already have been created with the reception of the first dump packet. + static const ReturnValue_t MRAM_FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xAF); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER; @@ -120,6 +124,15 @@ private: /** This buffer is used to concatenate space packets received in two different read steps */ uint8_t spacePacketBuffer[PLOC_SPV::MAX_PACKET_SIZE]; + SdCardManager* sdcMan = nullptr; + + /** Path to PLOC specific files on SD card */ + std::string plocFilePath = "ploc"; + std::string activeMramFile; + + /** Setting this variable to true will enable direct downlink of MRAM packets */ + bool downlinkMramDump = false; + /** * @brief This function checks the crc of the received PLOC reply. * @@ -211,12 +224,6 @@ private: void prepareRestartTriesCmd(const uint8_t * commandData); - /** - * @brief This function fills the command buffer with the packet to notify the supervisor - * about the availability of an update for the MPSoC - */ - void prepareUpdateAvailableCmd(const uint8_t * commandData); - /** * @brief This function fills the command buffer with the packet to enable or disable the * watchdogs on the PLOC. @@ -299,6 +306,34 @@ private: * MRAM dump packet. */ ReturnValue_t checkMramPacketApid(); + + /** + * @brief Writes the data of the MRAM dump to a file. The file will be created when receiving + * the first packet. + */ + ReturnValue_t handleMramDumpFile(); + + /** + * @brief Extracts the length field of a spacePacket referenced by the spacePacket pointer. + * + * @param spacePacket Pointer to the buffer holding the space packet. + * + * @return The value stored in the length field of the data field. + */ + uint16_t readSpacePacketLength(uint8_t* spacePacket); + + /** + * @brief Extracts the sequence flags from a space packet referenced by the spacePacket + * pointer. + * + * @param spacePacket Pointer to the buffer holding the space packet. + * + * @return uint8_t where the two least significant bits hold the sequence flags. + */ + uint8_t readSequenceFlags(uint8_t* spacePacket); + + ReturnValue_t createMramDumpFile(); + ReturnValue_t getTimeStampString(std::string& timeStamp); }; #endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */ diff --git a/mission/devices/PlocUpdater.cpp b/mission/devices/PlocUpdater.cpp index 9639ff87..bb09a1c6 100644 --- a/mission/devices/PlocUpdater.cpp +++ b/mission/devices/PlocUpdater.cpp @@ -1,15 +1,39 @@ +#include "fsfw/ipc/QueueFactory.h" #include -#include +#include +#include +#include -PlocUpdater::PlocUpdater() : commandActionHelper(this) { +PlocUpdater::PlocUpdater(object_id_t objectId) : + SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) { commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE); } PlocUpdater::~PlocUpdater() { } -ReturnValue_t SystemObject::initialize() { +ReturnValue_t PlocUpdater::initialize() { sdcMan = SdCardManager::instance(); + + ReturnValue_t result = SystemObject::initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = commandActionHelper.initialize(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = actionHelper.initialize(commandQueue); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t PlocUpdater::performOperation(uint8_t operationCode) { + readCommandQueue(); + doStateMachine(); return HasReturnvaluesIF::RETURN_OK; } @@ -17,29 +41,29 @@ ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { ReturnValue_t result = RETURN_FAILED; - if (state != IDLE) { + if (state != State::IDLE) { return IS_BUSY; } if (size > MAX_PLOC_UPDATE_PATH) { - return PATH_TOO_LONG; + return NAME_TOO_LONG; } switch (actionId) { case UPDATE_NVM0_A: - updateImage = Image::A; + updatePartition = Partition::A; updateMemory = Memory::NVM0; break; case UPDATE_NVM0_B: - updateImage = Image::B; + updatePartition = Partition::B; updateMemory = Memory::NVM0; break; case UPDATE_NVM1_A: - updateImage = Image::A; + updatePartition = Partition::A; updateMemory = Memory::NVM1; break; case UPDATE_NVM1_B: - updateImage = Image::B; + updatePartition = Partition::B; updateMemory = Memory::NVM1; break; default: @@ -48,34 +72,45 @@ ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, result = getImageLocation(data, size); - return result; + if (result != RETURN_OK) { + return result; + } + + state = State::UPDATE_AVAILABLE; + + return EXECUTION_FINISHED; } MessageQueueId_t PlocUpdater::getCommandQueue() const { - return commandQueue.getId(); + return commandQueue->getId(); +} + +MessageQueueIF* PlocUpdater::getCommandQueuePtr() { + return commandQueue; } void PlocUpdater::readCommandQueue() { CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); - if (result != RETURN_OK) { - return; - } - result = actionHelper.handleActionMessage(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } + ReturnValue_t result; - result = commandActionHelper.handleReply(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; + for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK; + result = commandQueue->receiveMessage(&message)) { + if (result != RETURN_OK) { + continue; + } + result = actionHelper.handleActionMessage(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + + result = commandActionHelper.handleReply(&message); + if (result == HasReturnvaluesIF::RETURN_OK) { + continue; + } + + sif::debug << "PlocUpdater::readCommandQueue: Received message with invalid format" + << std::endl; } - result = parameterHelper.handleParameterMessage(&message); - if (result == HasReturnvaluesIF::RETURN_OK) { - continue; - } - message.setToUnknownCommand(); - commandQueue.reply(&message); } void PlocUpdater::doStateMachine() { @@ -89,6 +124,9 @@ void PlocUpdater::doStateMachine() { commandUpdatePacket(); break; case State::UPDATE_VERIFY: + commandUpdateVerify(); + break; + case State::COMMAND_EXECUTING: break; default: sif::debug << "PlocUpdater::doStateMachine: Invalid state" << std::endl; @@ -110,13 +148,13 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { } // Check if file is stored on SD card and if associated SD card is mounted - if (std::string(data, SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { + if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) { if (!isSdCardMounted(sd::SLOT_0)) { sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 0 not mounted" << std::endl; return SD_NOT_MOUNTED; } } - else if (std::string(data, SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { + else if (std::string(reinterpret_cast(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) { if (!isSdCardMounted(sd::SLOT_0)) { sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 1 not mounted" << std::endl; return SD_NOT_MOUNTED; @@ -126,7 +164,7 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { //update image not stored on SD card } - updateFile = std::string(reinterpret_cast(data), size); + updateFile = std::string(reinterpret_cast(data), size); // Check if file exists if(not std::filesystem::exists(updateFile)) { @@ -136,8 +174,8 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { } bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) { - SdStatusPair active; - ReturnValue_t result = sdcMan->getSdCardActiveStatus(&active); + SdCardManager::SdStatusPair active; + ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); if (result != RETURN_OK) { sif::debug << "PlocUpdater::isSdCardMounted: Failed to get SD card active state"; return false; @@ -172,55 +210,65 @@ void PlocUpdater::stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) { } +void PlocUpdater::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) { + +} + void PlocUpdater::completionSuccessfulReceived(ActionId_t actionId) { - switch (actionId) { - case UPDATE_AVAILABLE: + switch (pendingCommand) { + case (PLOC_SPV::UPDATE_AVAILABLE): state = State::UPDATE_TRANSFER; break; - case UPDATE_IMAGE_DATA: + case (PLOC_SPV::UPDATE_IMAGE_DATA): if (remainingPackets == 0) { packetsSent = 0; // Reset packets sent variable for next update sequence state = State::UPDATE_VERIFY; } + else { + state = State::UPDATE_TRANSFER; + } break; - case UPDATE_VERIFY: + case (PLOC_SPV::UPDATE_VERIFY): triggerEvent(UPDATE_FINISHED); + state = State::IDLE; + pendingCommand = PLOC_SPV::NONE; break; default: - sif::debug << "PlocUpdater::completionSuccessfulReceived: Action message with has unknown " - << "action id" << std::endl; + sif::debug << "PlocUpdater::completionSuccessfulReceived: Invalid pending command" + << std::endl; + state = State::IDLE; break; } } void PlocUpdater::completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) { - state = State::IDLE; - switch(state) { - case(State::UPDATE_AVAILABLE): { + switch(pendingCommand) { + case(PLOC_SPV::UPDATE_AVAILABLE): { triggerEvent(UPDATE_AVAILABLE_FAILED); break; } - case(State::UPDATE_TRANSFER): { - triggerEvent(UPDATE_TRANSFER_FAILED); + case(PLOC_SPV::UPDATE_IMAGE_DATA): { + triggerEvent(UPDATE_TRANSFER_FAILED, packetsSent); break; } - case(State::UPDATE_VERIFY): { + case(PLOC_SPV::UPDATE_VERIFY): { triggerEvent(UPDATE_VERIFY_FAILED); break; } default: - sif::debug << "PlocUpdater::completionFailedReceived: Action message with has unknown " - << "action id" << std::endl; + sif::debug << "PlocUpdater::completionFailedReceived: Invalid pending command " + << std::endl; break; } + state = State::IDLE; } void PlocUpdater::commandUpdateAvailable() { ReturnValue_t result = RETURN_OK; if (not std::filesystem::exists(updateFile)) { - triggerEvent(UPDATE_FILE_NOT_EXISTS, state); + triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast(state)); state = State::IDLE; return; } @@ -231,7 +279,7 @@ void PlocUpdater::commandUpdateAvailable() { file.close(); numOfUpdatePackets = imageSize / MAX_SP_DATA ; - if (! imageSize % MAX_SP_DATA) { + if (imageSize % MAX_SP_DATA) { numOfUpdatePackets++; } @@ -243,22 +291,28 @@ void PlocUpdater::commandUpdateAvailable() { PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast(updateMemory), static_cast(updatePartition), imageSize, imageCrc, numOfUpdatePackets); - result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, UPDATE_AVAILABLE, - packet.getFullSize()); + result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, + PLOC_SPV::UPDATE_AVAILABLE, packet.getWholeData(), packet.getFullSize()); if (result != RETURN_OK) { sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" << " packet to supervisor handler" << std::endl; - triggerEvent(ACTION_COMMANDING_FAILED, result, UPDATE_AVAILABLE); + triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_AVAILABLE); + state = State::IDLE; + pendingCommand = PLOC_SPV::NONE; return; } + + pendingCommand = PLOC_SPV::UPDATE_AVAILABLE; + state = State::COMMAND_EXECUTING; return; } void PlocUpdater::commandUpdatePacket() { + ReturnValue_t result = RETURN_OK; uint16_t payloadLength = 0; if (not std::filesystem::exists(updateFile)) { - triggerEvent(UPDATE_FILE_NOT_EXISTS, state, packetsSent); + triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast(state), packetsSent); state = State::IDLE; return; } @@ -267,49 +321,59 @@ void PlocUpdater::commandUpdatePacket() { file.seekg(packetsSent * MAX_SP_DATA, file.beg); if (remainingPackets == 1) { - payloadLength = static_cast(file.tellg()); + payloadLength = imageSize - static_cast(file.tellg()); } else { payloadLength = MAX_SP_DATA; } PLOC_SPV::UpdatePacket packet(payloadLength); - file.read(static_cast(packet.getDataFieldPointer()), payloadLength); + file.read(reinterpret_cast(packet.getDataFieldPointer()), payloadLength); file.close(); - packet.updateCrc(); + // sequence count of first packet is 1 + packet.setPacketSequenceCount((packetsSent + 1) & PLOC_SPV::SEQUENCE_COUNT_MASK); + if (numOfUpdatePackets > 0) { + adjustSequenceFlags(packet); + } + packet.makeCrc(); + + result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, + PLOC_SPV::UPDATE_IMAGE_DATA, packet.getWholeData(), packet.getFullSize()); + + if (result != RETURN_OK) { + sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update" + << " packet to supervisor handler" << std::endl; + triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_IMAGE_DATA); + state = State::IDLE; + pendingCommand = PLOC_SPV::NONE; + return; + } - commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, UPDATE_IMAGE_DATA, - packet.getDataFieldPointer(), packet.getFullSize()); remainingPackets--; + packetsSent++; + + pendingCommand = PLOC_SPV::UPDATE_IMAGE_DATA; + state = State::COMMAND_EXECUTING; } void PlocUpdater::commandUpdateVerify() { ReturnValue_t result = RETURN_OK; - if (not std::filesystem::exists(updateFile)) { - triggerEvent(UPDATE_FILE_NOT_EXISTS, state); - state = State::IDLE; - return; - } - - remainingPackets = imageSize / MAX_SP_DATA ; - if (! imageSize % MAX_SP_DATA) { - remainingPackets++; - } - - uint32_t imageCrc = makeCrc(); - PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast(updateMemory), static_cast(updatePartition), imageSize, imageCrc, numOfUpdatePackets); - result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, UPDATE_AVAILABLE, - packet.getFullSize()); + result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, + PLOC_SPV::UPDATE_VERIFY, packet.getWholeData(), packet.getFullSize()); if (result != RETURN_OK) { sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available" << " packet to supervisor handler" << std::endl; - triggerEvent(ACTION_COMMANDING_FAILED, result, UPDATE_AVAILABLE); + triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_VERIFY); + state = State::IDLE; + pendingCommand = PLOC_SPV::NONE; return; } + state = State::COMMAND_EXECUTING; + pendingCommand = PLOC_SPV::UPDATE_VERIFY; return; } @@ -317,3 +381,16 @@ ReturnValue_t PlocUpdater::makeCrc() { //TODO: Waiting on input from TAS about the CRC to use return 0; } + +void PlocUpdater::adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet) { + if (packetsSent == 0) { + packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::FIRST_PKT)); + } + else if (remainingPackets == 1) { + packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::LAST_PKT)); + } + else { + packet.setSequenceFlags(static_cast(PLOC_SPV::SequenceFlags::CONTINUED_PKT)); + } +} + diff --git a/mission/devices/PlocUpdater.h b/mission/devices/PlocUpdater.h index 42c855f3..466d0482 100644 --- a/mission/devices/PlocUpdater.h +++ b/mission/devices/PlocUpdater.h @@ -2,15 +2,22 @@ #define MISSION_DEVICES_PLOCUPDATER_H_ #include "fsfw/action/CommandActionHelper.h" +#include "fsfw/action/ActionHelper.h" +#include "fsfw/action/HasActionsIF.h" +#include "fsfw/action/CommandsActionsIF.h" #include "fsfw/returnvalues/HasReturnValuesIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/objectmanager/SystemObject.h" #include "bsp_q7s/memory/SdCardManager.h" #include "linux/fsfwconfig/objects/systemObjectList.h" #include "fsfw/tmtcpacket/SpacePacket.h" +#include "OBSWConfig.h" +#include /** * @brief An object of this class can be used to perform the software updates of the PLOC. The - * software update will be fetched via file system messages from the SD card handler, - * split into multiple space packets and sent to the PlocSupervisorHandler. + * software update will be read from one of the SD cards, split into multiple space + * packets and sent to the PlocSupervisorHandler. * * @details The MPSoC has two boot memories (NVM0 and NVM1) where each stores two images (Partition A * and Partition B) @@ -25,17 +32,19 @@ class PlocUpdater : public SystemObject, public: static const ActionId_t UPDATE_NVM0_A = 0; - static const ActionId_t UPDATE_NVM0_B = 0; - static const ActionId_t UPDATE_NVM1_A = 0; - static const ActionId_t UPDATE_NVM1_B = 0; + static const ActionId_t UPDATE_NVM0_B = 1; + static const ActionId_t UPDATE_NVM1_A = 2; + static const ActionId_t UPDATE_NVM1_B = 3; - PlocUpdater(); + PlocUpdater(object_id_t objectId); virtual ~PlocUpdater(); + ReturnValue_t performOperation(uint8_t operationCode = 0) override; ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size); MessageQueueId_t getCommandQueue() const; ReturnValue_t initialize() override; + MessageQueueIF* getCommandQueuePtr() override; void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override; void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override; @@ -68,36 +77,39 @@ private: //! [EXPORT] : [COMMENT] Supervisor handler replied action message indicating a command execution failure of the update available command static const Event UPDATE_AVAILABLE_FAILED = MAKE_EVENT(2, severity::LOW); //! [EXPORT] : [COMMENT] Supervisor handler failed to transfer an update space packet. - //! P1: Parameter holds the number of update packets already sent. + //! P1: Parameter holds the number of update packets already sent (inclusive the failed packet) static const Event UPDATE_TRANSFER_FAILED = MAKE_EVENT(3, severity::LOW); //! [EXPORT] : [COMMENT] Supervisor failed to execute the update verify command. static const Event UPDATE_VERIFY_FAILED = MAKE_EVENT(4, severity::LOW); //! [EXPORT] : [COMMENT] MPSoC update successful completed - static const Event UPDATE_FINISHED = MAKE_EVENT(5, SEVERITY::INFO); + static const Event UPDATE_FINISHED = MAKE_EVENT(5, severity::INFO); static const uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE; - static const size_t MAX_PLOC_UPDATE_PATH = 20; + static const size_t MAX_PLOC_UPDATE_PATH = 50; static const size_t SD_PREFIX_LENGTH = 8; // Maximum size of update payload data per space packet (max size of space packet is 1024 bytes) static const size_t MAX_SP_DATA = 1016; - static const ActionId_t UPDATE_AVAILABLE = 12; - static const ActionId_t UPDATE_IMAGE_DATA = 39; - static const ActionId_t UPDATE_VERIFY = 42; + MessageQueueIF* commandQueue = nullptr; SdCardManager* sdcMan = nullptr; CommandActionHelper commandActionHelper; + ActionHelper actionHelper; + enum class State: uint8_t { IDLE, UPDATE_AVAILABLE, UPDATE_TRANSFER, - UPDATE_VERIFY + UPDATE_VERIFY, + COMMAND_EXECUTING }; State state = State::IDLE; + ActionId_t pendingCommand = PLOC_SPV::NONE; + enum class Memory: uint8_t { NVM0, NVM1 @@ -112,8 +124,6 @@ private: Partition updatePartition = Partition::A; - State state = State::IDLE; - uint32_t packetsSent = 0; uint32_t remainingPackets = 0; // Number of packets required to transfer the update image @@ -123,14 +133,39 @@ private: uint32_t imageSize = 0; uint32_t imageCrc = 0; + void readCommandQueue(); + void doStateMachine(); + + /** + * @brief Extracts the path and name of the update image from the service 8 command data. + */ + ReturnValue_t getImageLocation(const uint8_t* data, size_t size); + ReturnValue_t checkNameLength(size_t size); + /** + * @brief Prepares and sends update available command to PLOC supervisor handler. + */ + void commandUpdateAvailable(); + + /** + * @brief Prepares and sends and update packet to the PLOC supervisor handler. + */ + void commandUpdatePacket(); + + /** + * @brief Prepares and sends the update verification packet to the PLOC supervisor handler. + */ + void commandUpdateVerify(); + /** * @brief Checks whether the SD card to read from is mounted or not. */ bool isSdCardMounted(sd::SdCard sdCard); ReturnValue_t makeCrc(); + + void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet); }; #endif /* MISSION_DEVICES_PLOCUPDATER_H_ */ diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index 32e682a1..909379df 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include namespace PLOC_SPV { @@ -131,6 +133,7 @@ static const uint16_t APID_REQUEST_LOGGING_DATA = 0xFD; static const uint16_t APID_GET_HK_REPORT = 0xC6; static const uint16_t APID_MASK = 0x3FF; +static const uint16_t SEQUENCE_COUNT_MASK = 0xFFF; /** Offset from first byte in Space packet to first byte of data field */ static const uint8_t DATA_FIELD_OFFSET = 6; @@ -1410,15 +1413,12 @@ private: class SupvTcSpacePacket : public SpacePacket { public: SupvTcSpacePacket(size_t payloadDataLen, uint16_t apid) : - SpacePacket(payloadLen + 1, true, apid, + SpacePacket(payloadDataLen + 1, true, apid, DEFAULT_SEQUENCE_COUNT), payloadDataLen(payloadDataLen) { - initPacket(); - makeCrc(); } -protected: void makeCrc() { - serializedSize = 0; + size_t serializedSize = 0; uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader) + payloadDataLen); uint8_t* crcPos = this->localData.fields.buffer + payloadDataLen; @@ -1432,15 +1432,10 @@ private: // The size of the payload data (data field without crc size) size_t payloadDataLen = 0; - - void virtual initPacket() { - // Perform stuff to fill packet data field - } }; /** - * @brief This class packages the update available space packet. This is the first packet sent - * to the supervisor in an update procedure. + * @brief This class can be used to package the update available or update verify command. */ class UpdateInfo: public SupvTcSpacePacket { public: @@ -1460,6 +1455,7 @@ public: SupvTcSpacePacket(PAYLOAD_LENGTH, apid), memory(memory), partition(partition), imageSize( imageSize), numPackets(numPackets) { initPacket(); + makeCrc(); } private: @@ -1475,19 +1471,19 @@ private: void initPacket() { size_t serializedSize = 0; uint8_t* data_field_ptr = this->localData.fields.buffer; - SerializeAdapter::serialize(memory, &data_field_ptr, &serializedSize, + SerializeAdapter::serialize(&memory, &data_field_ptr, &serializedSize, sizeof(memory), SerializeIF::Endianness::BIG); serializedSize = 0; SerializeAdapter::serialize(&partition, &data_field_ptr, &serializedSize, sizeof(partition), SerializeIF::Endianness::BIG); serializedSize = 0; - SerializeAdapter::serialize(&imageSize, &data_field_ptr, &serializedSize, + SerializeAdapter::serialize(&imageSize, &data_field_ptr, &serializedSize, sizeof(imageSize), SerializeIF::Endianness::BIG); serializedSize = 0; - SerializeAdapter::serialize(&imageCrc, &data_field_ptr, &serializedSize, + SerializeAdapter::serialize(&imageCrc, &data_field_ptr, &serializedSize, sizeof(imageCrc), SerializeIF::Endianness::BIG); serializedSize = 0; - SerializeAdapter::serialize(&numPackets, &data_field_ptr, &serializedSize, + SerializeAdapter::serialize(&numPackets, &data_field_ptr, &serializedSize, sizeof(numPackets), SerializeIF::Endianness::BIG); } }; @@ -1505,7 +1501,6 @@ public: */ UpdatePacket(uint16_t payloadLength) : SupvTcSpacePacket(payloadLength, APID_UPDATE_IMAGE_DATA) { - initPacket(); } /** @@ -1514,10 +1509,6 @@ public: uint8_t* getDataFieldPointer() { return this->localData.fields.buffer; } - - void updateCrc() { - this->makeCrc(); - } }; /** diff --git a/tmtc b/tmtc index 4aebf4c0..e7d8199e 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 4aebf4c0d9a4a094e1a18753bca77d6a3b993378 +Subproject commit e7d8199e673eb204dbf0ea32158ca2f01c32aaa8 -- 2.43.0 From 74dc04daeb1e50c3a09ff9dd762d24d60f859e1b Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sun, 8 Aug 2021 16:18:49 +0200 Subject: [PATCH 110/116] updated fsfw and tmtc --- fsfw | 2 +- tmtc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index bb88490c..133820f4 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit bb88490cc6cda5474d1d4913452eeb758da8cc25 +Subproject commit 133820f463645164c203e72f0acd078eb002e159 diff --git a/tmtc b/tmtc index e7d8199e..547b4b21 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit e7d8199e673eb204dbf0ea32158ca2f01c32aaa8 +Subproject commit 547b4b213704a72a884c2871debeea0461c7704f -- 2.43.0 From 66f38daf56b697e594157f267769442a74dcaaae Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Mon, 9 Aug 2021 10:44:14 +0200 Subject: [PATCH 111/116] typo in include of ploc updater --- mission/devices/PlocUpdater.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/devices/PlocUpdater.h b/mission/devices/PlocUpdater.h index 466d0482..eee5453a 100644 --- a/mission/devices/PlocUpdater.h +++ b/mission/devices/PlocUpdater.h @@ -5,7 +5,7 @@ #include "fsfw/action/ActionHelper.h" #include "fsfw/action/HasActionsIF.h" #include "fsfw/action/CommandsActionsIF.h" -#include "fsfw/returnvalues/HasReturnValuesIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" #include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/objectmanager/SystemObject.h" #include "bsp_q7s/memory/SdCardManager.h" -- 2.43.0 From f56c8ba1c0c6bc5c4b7696858ecb947fa4e49755 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 11:00:58 +0200 Subject: [PATCH 112/116] minor fixes and additional printout --- bsp_q7s/core/CoreController.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 33f2acd1..606646bf 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -205,6 +205,17 @@ ReturnValue_t CoreController::sdStateMachine() { static_cast(sdInfo.pref) << std::endl; #endif if(sdInfo.prefState == sd::SdState::MOUNTED) { +#if OBSW_VERBOSE_LEVEL >= 1 + std::string mountString; + if(sdInfo.pref == sd::SdCard::SLOT_0) { + mountString = SdCardManager::SD_0_MOUNT_POINT; + } + else { + mountString = SdCardManager::SD_1_MOUNT_POINT; + } + sif::info << "SD card " << sdInfo.prefChar << " already on and mounted at " << + mountString << std::endl; +#endif sdInfo.state = SdStates::DETERMINE_OTHER; } else if(sdInfo.prefState == sd::SdState::OFF) { @@ -216,9 +227,10 @@ ReturnValue_t CoreController::sdStateMachine() { } } else { - nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state"); - sdInfo.prefState = sd::SdState::ON; - currentStateSetter(sdInfo.pref, sd::SdState::ON); + if(nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) { + sdInfo.prefState = sd::SdState::ON; + currentStateSetter(sdInfo.pref, sd::SdState::ON); + } } } @@ -284,10 +296,11 @@ ReturnValue_t CoreController::sdStateMachine() { sdInfo.commandExecuted = true; } else { - nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, - "Switching on other SD card"); - sdInfo.otherState = sd::SdState::ON; - currentStateSetter(sdInfo.other, sd::SdState::ON); + if(nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10, + "Switching on other SD card")) { + sdInfo.otherState = sd::SdState::ON; + currentStateSetter(sdInfo.other, sd::SdState::ON); + } } #endif } -- 2.43.0 From 4a74a3ac3738b30404a5b614a17673670db554a6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 11:24:59 +0200 Subject: [PATCH 113/116] API change fix --- mission/devices/PlocUpdater.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/devices/PlocUpdater.cpp b/mission/devices/PlocUpdater.cpp index bb09a1c6..f890c239 100644 --- a/mission/devices/PlocUpdater.cpp +++ b/mission/devices/PlocUpdater.cpp @@ -174,7 +174,7 @@ ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) { } bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) { - SdCardManager::SdStatusPair active; + SdCardManager::SdStatePair active; ReturnValue_t result = sdcMan->getSdCardActiveStatus(active); if (result != RETURN_OK) { sif::debug << "PlocUpdater::isSdCardMounted: Failed to get SD card active state"; -- 2.43.0 From f5f8df61ae2990f8a00e56e8066dcbf6deadeef3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 11:27:08 +0200 Subject: [PATCH 114/116] bumped subversion --- bsp_q7s/core/obsw.cpp | 2 +- common/config/OBSWVersion.h | 2 +- fsfw | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bsp_q7s/core/obsw.cpp b/bsp_q7s/core/obsw.cpp index 47b7b9d2..e55d5652 100644 --- a/bsp_q7s/core/obsw.cpp +++ b/bsp_q7s/core/obsw.cpp @@ -19,7 +19,7 @@ int obsw::obsw() { #else std::cout << "-- Compiled for Linux (TE0720) --" << std::endl; #endif - std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << + std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "." << FSFW_REVISION << "--" << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; diff --git a/common/config/OBSWVersion.h b/common/config/OBSWVersion.h index 0274b91f..db7cfeb5 100644 --- a/common/config/OBSWVersion.h +++ b/common/config/OBSWVersion.h @@ -4,7 +4,7 @@ const char* const SW_NAME = "eive"; #define SW_VERSION 1 -#define SW_SUBVERSION 5 +#define SW_SUBVERSION 6 #define SW_REVISION 0 #endif /* COMMON_CONFIG_OBSWVERSION_H_ */ diff --git a/fsfw b/fsfw index 3704d2b8..22e29144 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 3704d2b8295152652a4c7836b595223d8fa3767d +Subproject commit 22e29144b6783a824b310204c76fa413eb94f331 -- 2.43.0 From 74dbfae2256d656b6cd46f07c6b9ada68bbab985 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 14:30:14 +0200 Subject: [PATCH 115/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 3e8626bf..3305e1d4 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 3e8626bfafa561510323bf8fe3963bc2860950ed +Subproject commit 3305e1d489c7d3ce401945712a4f374e068175ff -- 2.43.0 From cd7bc466ae7a825fdfb29ce1385752e0a9695437 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 15:53:48 +0200 Subject: [PATCH 116/116] tmtc update --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 3305e1d4..cc6dbd8e 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 3305e1d489c7d3ce401945712a4f374e068175ff +Subproject commit cc6dbd8ef9d5bd028835f37a24a5617224569862 -- 2.43.0