diff --git a/CHANGELOG.md b/CHANGELOG.md index e722c80a..f5ae19d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +# [v1.42.0] 2023-04-01 + +- eive-tmtc: v2.20.1 +- q7s-package: v2.3.0 + ## Changed - SCEX filename updates. Also use T as the file ID / date separator between date and time. @@ -26,12 +31,17 @@ will consitute of a breaking change warranting a new major release: - Added `PTME_LOCKED` boolean lock which is used to lock the PTME so it is not used by the VC tasks anymore. This lock will be controlled by the CCSDS IP core handler and is locked when the PTME needs to be reset. Examples for this are datarate changes. +- Simulate real PCDU in PCDU dummy by remembering commandes switch change and triggering appropriate + events. Switch feedback is still immediate. +- GomSpace devices are polled with a doubled frequency. This speeds up power switch commanding. ## Fixed - Bugfix for side lane transitions of the dual lane assemblies, which only worked when the - assembly was directly commanded + assembly was directly commanded. - Syrlinks Handler: Bugfix so transition command is only sent once. +- SCEX file name bug: Create file name time stamp with `strftime` similarly to how it's done + for the persistent TM store. ## Added @@ -41,8 +51,8 @@ will consitute of a breaking change warranting a new major release: # [v1.41.0] 2023-03-28 -eive-tmtc: v2.20.0 -q7s-package: v2.2.0 +- eive-tmtc: v2.20.0 +- q7s-package: v2.2.0 ## Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a2842a5..29da10da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 1) -set(OBSW_VERSION_MINOR 41) +set(OBSW_VERSION_MINOR 42) set(OBSW_VERSION_REVISION 0) # set(CMAKE_VERBOSE TRUE) diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index 8bce9e73..3e1dd369 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 284 translations. * @details - * Generated on: 2023-03-31 19:17:49 + * Generated on: 2023-04-01 16:00:01 */ #include "translateEvents.h" diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 173c476b..4ceb3a4f 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 171 translations. - * Generated on: 2023-03-31 19:17:49 + * Generated on: 2023-04-01 16:00:01 */ #include "translateObjects.h" diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index 50a70911..8c460f53 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -15,6 +15,9 @@ static constexpr char OBSW_VERSION_FILE_NAME[] = "obsw_version.txt"; static constexpr char OBSW_PATH[] = "/usr/bin/eive-obsw"; static constexpr char OBSW_VERSION_FILE_PATH[] = "/usr/share/eive-obsw/obsw_version.txt"; +// ISO8601 timestamp. +static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ"; + static constexpr uint16_t EIVE_PUS_APID = 0x65; static constexpr uint16_t EIVE_CFDP_APID = 0x66; static constexpr uint16_t EIVE_LOCAL_CFDP_ENTITY_ID = EIVE_CFDP_APID; diff --git a/dummies/PcduHandlerDummy.cpp b/dummies/PcduHandlerDummy.cpp index e3331c8d..0b1dec69 100644 --- a/dummies/PcduHandlerDummy.cpp +++ b/dummies/PcduHandlerDummy.cpp @@ -2,8 +2,12 @@ #include +#include "mission/power/defs.h" + PcduHandlerDummy::PcduHandlerDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie) - : DeviceHandlerBase(objectId, comif, comCookie), dummySwitcher(objectId, 18, 18, false) {} + : DeviceHandlerBase(objectId, comif, comCookie), dummySwitcher(objectId, 18, 18, false) { + switcherLock = MutexFactory::instance()->createMutex(); +} PcduHandlerDummy::~PcduHandlerDummy() {} @@ -44,6 +48,17 @@ ReturnValue_t PcduHandlerDummy::initializeLocalDataPool(localpool::DataPool &loc } ReturnValue_t PcduHandlerDummy::sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) { + if (onOff == SWITCH_ON) { + triggerEvent(power::SWITCH_CMD_SENT, true, switchNr); + } else { + triggerEvent(power::SWITCH_CMD_SENT, false, switchNr); + } + { + MutexGuard mg(switcherLock); + // To simulate a real PCDU, remember the switch change to trigger a SWITCH_HAS_CHANGED event + // at a later stage. + switchChangeArray[switchNr] = true; + } return dummySwitcher.sendSwitchCommand(switchNr, onOff); } @@ -60,3 +75,22 @@ ReturnValue_t PcduHandlerDummy::getFuseState(uint8_t fuseNr) const { } uint32_t PcduHandlerDummy::getSwitchDelayMs(void) const { return dummySwitcher.getSwitchDelayMs(); } + +void PcduHandlerDummy::performOperationHook() { + SwitcherBoolArray switcherChangeCopy{}; + { + MutexGuard mg(switcherLock); + std::memcpy(switcherChangeCopy.data(), switchChangeArray.data(), switchChangeArray.size()); + } + for (uint8_t idx = 0; idx < switcherChangeCopy.size(); idx++) { + if (switcherChangeCopy[idx]) { + if (dummySwitcher.getSwitchState(idx) == PowerSwitchIF::SWITCH_ON) { + triggerEvent(power::SWITCH_HAS_CHANGED, true, idx); + } else { + triggerEvent(power::SWITCH_HAS_CHANGED, false, idx); + } + MutexGuard mg(switcherLock); + switchChangeArray[idx] = false; + } + } +} diff --git a/dummies/PcduHandlerDummy.h b/dummies/PcduHandlerDummy.h index 2f4c167a..7980629b 100644 --- a/dummies/PcduHandlerDummy.h +++ b/dummies/PcduHandlerDummy.h @@ -15,8 +15,12 @@ class PcduHandlerDummy : public DeviceHandlerBase, public PowerSwitchIF { virtual ~PcduHandlerDummy(); protected: + MutexIF *switcherLock; DummyPowerSwitcher dummySwitcher; + using SwitcherBoolArray = std::array; + SwitcherBoolArray switchChangeArray{}; + void performOperationHook() override; void doStartUp() override; void doShutDown() override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; diff --git a/generators/bsp_hosted_returnvalues.csv b/generators/bsp_hosted_returnvalues.csv index dc960aa3..f0618adf 100644 --- a/generators/bsp_hosted_returnvalues.csv +++ b/generators/bsp_hosted_returnvalues.csv @@ -190,8 +190,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x2207;TMF_AllDeleted;No description;7;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h 0x2208;TMF_InvalidData;No description;8;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h 0x2209;TMF_NotReady;No description;9;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2401;MT_TooDetailedRequest;No description;1;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h -0x2402;MT_TooGeneralRequest;No description;2;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h +0x2401;MT_NoPacketFound;No description;1;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/DleParser.h +0x2402;MT_PossiblePacketLoss;No description;2;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/DleParser.h 0x2403;MT_NoMatch;No description;3;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h 0x2404;MT_Full;No description;4;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h 0x2405;MT_NewNodeCreated;No description;5;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h @@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h 0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h 0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h -0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h +0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h +0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h 0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h @@ -402,9 +402,9 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h 0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h 0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h -0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h -0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h -0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h +0x4500;HSPI_HalTimeoutRetval;No description;0;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h +0x4501;HSPI_HalBusyRetval;No description;1;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h +0x4502;HSPI_HalErrorRetval;No description;2;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h 0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h 0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h 0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index 9f6f0379..1c908d4c 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -190,8 +190,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x2207;TMF_AllDeleted;No description;7;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h 0x2208;TMF_InvalidData;No description;8;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h 0x2209;TMF_NotReady;No description;9;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2401;MT_TooDetailedRequest;No description;1;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h -0x2402;MT_TooGeneralRequest;No description;2;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h +0x2401;MT_NoPacketFound;No description;1;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/DleParser.h +0x2402;MT_PossiblePacketLoss;No description;2;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/DleParser.h 0x2403;MT_NoMatch;No description;3;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h 0x2404;MT_Full;No description;4;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h 0x2405;MT_NewNodeCreated;No description;5;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h @@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h 0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h 0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h -0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h +0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h +0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h 0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h @@ -402,9 +402,9 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h 0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h 0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h -0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h -0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h -0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h +0x4500;HSPI_HalTimeoutRetval;No description;0;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h +0x4501;HSPI_HalBusyRetval;No description;1;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h +0x4502;HSPI_HalErrorRetval;No description;2;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h 0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h 0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h 0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h @@ -492,10 +492,9 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x58a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h 0x58a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h 0x58a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h -0x5900;IPCI_NoReplyAvailable;No description;0;CCSDS_IP_CORE_BRIDGE;linux/acs/ImtqPollingTask.h -0x5901;IPCI_NoPacketFound;No description;1;CCSDS_IP_CORE_BRIDGE;linux/com/SyrlinksComHandler.h 0x59a0;IPCI_PapbBusy;No description;160;CCSDS_IP_CORE_BRIDGE;linux/ipcore/PapbVcInterface.h 0x5aa0;PTME_UnknownVcId;No description;160;PTME;linux/ipcore/Ptme.h +0x5c00;STRHLP_NoReplyAvailable;No description;0;STR_HELPER;linux/acs/ImtqPollingTask.h 0x5c01;STRHLP_SdNotMounted;SD card specified in path string not mounted;1;STR_HELPER;linux/acs/StrComHandler.h 0x5c02;STRHLP_FileNotExists;Specified file does not exist on filesystem;2;STR_HELPER;linux/acs/StrComHandler.h 0x5c03;STRHLP_PathNotExists;Specified path does not exist;3;STR_HELPER;linux/acs/StrComHandler.h @@ -541,13 +540,13 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h 0x64a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;160;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h 0x64a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;161;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h -0x6502;PLMPHLP_InvalidCrc;No description;2;PLOC_MPSOC_HELPER;linux/payload/ScexHelper.h 0x65a0;PLMPHLP_FileClosedAccidentally;File accidentally close;160;PLOC_MPSOC_HELPER;linux/payload/PlocMpsocHelper.h 0x66a0;SADPL_CommandNotSupported;No description;160;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x66a1;SADPL_DeploymentAlreadyExecuting;No description;161;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x66a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x66a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x66a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h +0x6702;MPSOCRTVIF_InvalidCrc;No description;2;MPSOC_RETURN_VALUES_IF;linux/payload/ScexHelper.h 0x67a0;MPSOCRTVIF_CrcFailure;Space Packet received from PLOC has invalid CRC;160;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x67a1;MPSOCRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC;161;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x67a2;MPSOCRTVIF_ReceivedExeFailure;Received execution failure reply from PLOC;162;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h @@ -558,6 +557,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x67a7;MPSOCRTVIF_MpsocFilenameTooLong;Filename of MPSoC file is to long (max. 256 bytes);167;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x67a8;MPSOCRTVIF_InvalidParameter;Command has invalid parameter;168;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x67a9;MPSOCRTVIF_NameTooLong;Received command has file string with invalid length;169;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h +0x6801;SPVRTVIF_NoPacketFound;No description;1;SUPV_RETURN_VALUES_IF;linux/com/SyrlinksComHandler.h 0x68a0;SPVRTVIF_CrcFailure;Space Packet received from PLOC supervisor has invalid CRC;160;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h 0x68a1;SPVRTVIF_InvalidServiceId;No description;161;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h 0x68a2;SPVRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC supervisor;162;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 8bce9e73..3e1dd369 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 284 translations. * @details - * Generated on: 2023-03-31 19:17:49 + * Generated on: 2023-04-01 16:00:01 */ #include "translateEvents.h" diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index f08a8f38..9697c7ef 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 175 translations. - * Generated on: 2023-03-31 19:17:49 + * Generated on: 2023-04-01 16:00:01 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 8bce9e73..3e1dd369 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 284 translations. * @details - * Generated on: 2023-03-31 19:17:49 + * Generated on: 2023-04-01 16:00:01 */ #include "translateEvents.h" diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index f08a8f38..9697c7ef 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 175 translations. - * Generated on: 2023-03-31 19:17:49 + * Generated on: 2023-04-01 16:00:01 */ #include "translateObjects.h" diff --git a/mission/acs/str/StarTrackerHandler.cpp b/mission/acs/str/StarTrackerHandler.cpp index def0bea8..5392a600 100644 --- a/mission/acs/str/StarTrackerHandler.cpp +++ b/mission/acs/str/StarTrackerHandler.cpp @@ -213,6 +213,8 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu default: break; } + // In case the JSON has changed, reinitiate the next parameter set to update. + reinitNextSetParam = true; return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); } @@ -273,6 +275,7 @@ void StarTrackerHandler::doShutDown() { startupState = StartupState::IDLE; bootState = FwBootState::NONE; solutionSet.setReportingEnabled(false); + reinitNextSetParam = false; setMode(_MODE_POWER_DOWN); } @@ -313,6 +316,8 @@ ReturnValue_t StarTrackerHandler::buildTransitionDeviceCommand(DeviceCommandId_t if (bootCountdown.isBusy()) { return NOTHING_TO_SEND; } + // Was already done. + reinitNextSetParam = false; bootState = FwBootState::REQ_VERSION; } switch (bootState) { @@ -461,7 +466,8 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi return returnvalue::OK; } case (startracker::SUBSCRIPTION): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.subscription); + result = + prepareParamCommand(commandData, commandDataLen, jcfgs.subscription, reinitNextSetParam); return returnvalue::OK; } case (startracker::REQ_SOLUTION): { @@ -477,55 +483,60 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi return returnvalue::OK; } case (startracker::LIMITS): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.limits); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.limits, reinitNextSetParam); return result; } case (startracker::MOUNTING): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.mounting); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.mounting, reinitNextSetParam); return result; } case (startracker::IMAGE_PROCESSOR): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.imageProcessor); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.imageProcessor, + reinitNextSetParam); return result; } case (startracker::CAMERA): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.camera); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.camera, reinitNextSetParam); return result; } case (startracker::CENTROIDING): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.centroiding); + result = + prepareParamCommand(commandData, commandDataLen, jcfgs.centroiding, reinitNextSetParam); return result; } case (startracker::LISA): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.lisa); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.lisa, reinitNextSetParam); return result; } case (startracker::MATCHING): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.matching); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.matching, reinitNextSetParam); return result; } case (startracker::VALIDATION): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.validation); + result = + prepareParamCommand(commandData, commandDataLen, jcfgs.validation, reinitNextSetParam); return result; } case (startracker::ALGO): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.algo); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.algo, reinitNextSetParam); return result; } case (startracker::TRACKING): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.tracking); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.tracking, reinitNextSetParam); return result; } case (startracker::LOGLEVEL): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.logLevel); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.logLevel, reinitNextSetParam); return result; } case (startracker::LOGSUBSCRIPTION): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.logSubscription); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.logSubscription, + reinitNextSetParam); return result; } case (startracker::DEBUG_CAMERA): { - result = prepareParamCommand(commandData, commandDataLen, jcfgs.debugCamera); + result = + prepareParamCommand(commandData, commandDataLen, jcfgs.debugCamera, reinitNextSetParam); return result; } case (startracker::CHECKSUM): { @@ -1690,12 +1701,19 @@ void StarTrackerHandler::prepareHistogramRequest() { ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData, size_t commandDataLen, - ArcsecJsonParamBase& paramSet) { + ArcsecJsonParamBase& paramSet, + bool reinitSet) { // Stopwatch watch; ReturnValue_t result = returnvalue::OK; if (commandDataLen > MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; } + if (reinitSet) { + result = paramSet.init(paramJsonFile); + if (result != returnvalue::OK) { + return result; + } + } result = paramSet.create(commandBuffer); if (result != returnvalue::OK) { diff --git a/mission/acs/str/StarTrackerHandler.h b/mission/acs/str/StarTrackerHandler.h index c1acc545..69b3e121 100644 --- a/mission/acs/str/StarTrackerHandler.h +++ b/mission/acs/str/StarTrackerHandler.h @@ -287,6 +287,8 @@ class StarTrackerHandler : public DeviceHandlerBase { InternalState internalState = InternalState::IDLE; + bool reinitNextSetParam = false; + bool strHelperHandlingSpecialRequest = false; const power::Switch_t powerSwitch = power::NO_SWITCH; @@ -409,7 +411,7 @@ class StarTrackerHandler : public DeviceHandlerBase { * @return returnvalue::OK if successful, otherwise error return Value */ ReturnValue_t prepareParamCommand(const uint8_t* commandData, size_t commandDataLen, - ArcsecJsonParamBase& paramSet); + ArcsecJsonParamBase& paramSet, bool reinitSet); /** * @brief The following function will fill the command buffer with the command to request diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index 0ae2ead3..ca05a309 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -192,8 +192,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun // HK store and PUS funnel to HK store routing { - PersistentTmStoreArgs storeArgs(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, - 15, *ramToFileStore, sdcMan); + PersistentTmStoreArgs storeArgs(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, 2, + *ramToFileStore, sdcMan); stores.hkStore = new PersistentTmStoreWithTmQueue(storeArgs, "HK STORE", config::HK_STORE_QUEUE_SIZE); (*pusFunnel) diff --git a/mission/payload/ScexDeviceHandler.cpp b/mission/payload/ScexDeviceHandler.cpp index 2b3f69f7..8c3b7386 100644 --- a/mission/payload/ScexDeviceHandler.cpp +++ b/mission/payload/ScexDeviceHandler.cpp @@ -11,6 +11,7 @@ #include #include +#include "eive/definitions.h" #include "fsfw/globalfunctions/CRC.h" using std::ofstream; @@ -27,6 +28,7 @@ void ScexDeviceHandler::doStartUp() { setMode(MODE_ON); } void ScexDeviceHandler::doShutDown() { reader.reset(); commandActive = false; + fileNameSet = false; multiFileFinishOutstanding = false; setMode(_MODE_POWER_DOWN); } @@ -205,50 +207,13 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons using namespace scex; ReturnValue_t status = OK; - auto oneFileHandler = [&](const char* cmdName) { - auto activeSd = sdcMan.getActiveSdCard(); - if (not activeSd) { - return HasFileSystemIF::FILESYSTEM_INACTIVE; - } - fileId = date_time_string(); - std::ostringstream oss; - auto prefix = sdcMan.getCurrentMountPrefix(); - if (prefix == nullptr) { - return returnvalue::FAILED; - } - oss << prefix << "/scex/scex-" << cmdName << "-" << fileId << ".bin"; - fileName = oss.str(); - ofstream out(fileName, ofstream::binary); - if (out.bad()) { - sif::error << "ScexDeviceHandler::interpretDeviceReply: Could not open file " << fileName - << std::endl; - return FAILED; - } - out << helper; - return OK; - }; auto multiFileHandler = [&](const char* cmdName) { if ((helper.getPacketCounter() == 1) or (not fileNameSet)) { - auto activeSd = sdcMan.getActiveSdCard(); - if (not activeSd) { - return HasFileSystemIF::FILESYSTEM_INACTIVE; + status = generateNewScexFile(cmdName); + if (status != returnvalue::OK) { + return status; } - fileId = date_time_string(); - std::ostringstream oss; - auto prefix = sdcMan.getCurrentMountPrefix(); - if (prefix == nullptr) { - return returnvalue::FAILED; - } - oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin"; - fileName = oss.str(); fileNameSet = true; - ofstream out(fileName, ofstream::binary); - if (out.bad()) { - sif::error << "ScexDeviceHandler::handleValidReply: Could not open file " << fileName - << std::endl; - return FAILED; - } - out << helper; } else { ofstream out(fileName, ofstream::binary | ofstream::app); // append @@ -264,19 +229,19 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons id = helper.getCmd(); switch (id) { case (PING): { - status = oneFileHandler(PING_IDLE_BASE_NAME); + status = generateNewScexFile(PING_IDLE_BASE_NAME); break; } case (ION_CMD): { - status = oneFileHandler(ION_BASE_NAME); + status = generateNewScexFile(ION_BASE_NAME); break; } case (TEMP_CMD): { - status = oneFileHandler(TEMPERATURE_BASE_NAME); + status = generateNewScexFile(TEMPERATURE_BASE_NAME); break; } case (EXP_STATUS_CMD): { - status = oneFileHandler(EXP_STATUS_BASE_NAME); + status = generateNewScexFile(EXP_STATUS_BASE_NAME); break; } case (FRAM): { @@ -354,37 +319,41 @@ ReturnValue_t ScexDeviceHandler::initializeLocalDataPool(localpool::DataPool& lo return OK; } -std::string ScexDeviceHandler::date_time_string() { - using namespace std; - string date_time; - Clock::TimeOfDay_t tod; - Clock::getDateAndTime(&tod); - ostringstream oss(std::ostringstream::ate); - - if (tod.hour < 10) { - oss << tod.year << tod.month << tod.day << "T0" << tod.hour; - } else { - oss << tod.year << tod.month << tod.day << "T" << tod.hour; - } - if (tod.minute < 10) { - oss << 0 << tod.minute; - - } else { - oss << tod.minute; - } - if (tod.second < 10) { - oss << 0 << tod.second; - } else { - oss << tod.second; +ReturnValue_t ScexDeviceHandler::generateNewScexFile(const char* cmdName) { + char timeString[64]{}; + auto activeSd = sdcMan.getActiveSdCard(); + if (not activeSd) { + return HasFileSystemIF::FILESYSTEM_INACTIVE; } - date_time = oss.str(); - - return date_time; + std::ostringstream oss; + auto prefix = sdcMan.getCurrentMountPrefix(); + if (prefix == nullptr) { + return returnvalue::FAILED; + } + timeval tv; + Clock::getClock_timeval(&tv); + time_t epoch = tv.tv_sec; + struct tm* time = gmtime(&epoch); + size_t writtenBytes = strftime(reinterpret_cast(timeString), sizeof(timeString), + config::FILE_DATE_FORMAT, time); + if (writtenBytes == 0) { + sif::error << "PersistentTmStore::createMostRecentFile: Could not create file timestamp" + << std::endl; + return returnvalue::FAILED; + } + oss << prefix << "/scex/scex-" << cmdName << "-" << timeString << ".bin"; + fileName = oss.str(); + ofstream out(fileName, ofstream::binary); + if (out.bad()) { + sif::error << "ScexDeviceHandler::interpretDeviceReply: Could not open file " << fileName + << std::endl; + return FAILED; + } + out << helper; + return OK; } -void ScexDeviceHandler::modeChanged() {} - void ScexDeviceHandler::setPowerSwitcher(PowerSwitchIF& powerSwitcher, power::Switch_t switchId) { DeviceHandlerBase::setPowerSwitcher(&powerSwitcher); this->switchId = switchId; diff --git a/mission/payload/ScexDeviceHandler.h b/mission/payload/ScexDeviceHandler.h index f95169b9..e7721ef6 100644 --- a/mission/payload/ScexDeviceHandler.h +++ b/mission/payload/ScexDeviceHandler.h @@ -43,8 +43,6 @@ class ScexDeviceHandler : public DeviceHandlerBase { SdCardMountedIF &sdcMan; Countdown finishCountdown = Countdown(LONG_CD); - std::string date_time_string(); - // DeviceHandlerBase private function implementation void doStartUp() override; void doShutDown() override; @@ -67,7 +65,8 @@ class ScexDeviceHandler : public DeviceHandlerBase { ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) override; ReturnValue_t initializeAfterTaskCreation() override; - void modeChanged() override; + + ReturnValue_t generateNewScexFile(const char *cmdName); }; #endif /* MISSION_PAYLOAD_SCEXDEVICEHANDLER_H_ */ diff --git a/mission/pollingSeqTables.cpp b/mission/pollingSeqTables.cpp index 4225e977..574cc9c1 100644 --- a/mission/pollingSeqTables.cpp +++ b/mission/pollingSeqTables.cpp @@ -104,25 +104,50 @@ ReturnValue_t pst::pstGompaceCan(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::ACU_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PDU1_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::ACU_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PDU1_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::ACU_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::ACU_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::ACU_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::ACU_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::PERFORM_OPERATION); + + thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::SEND_WRITE); + + thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::GET_WRITE); + + thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::ACU_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ); + + thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::ACU_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ); if (thisSequence->checkSequence() != returnvalue::OK) { sif::error << "GomSpace PST initialization failed" << std::endl; return returnvalue::FAILED; diff --git a/mission/system/acs/AcsBoardAssembly.cpp b/mission/system/acs/AcsBoardAssembly.cpp index 6c4023f8..1868185e 100644 --- a/mission/system/acs/AcsBoardAssembly.cpp +++ b/mission/system/acs/AcsBoardAssembly.cpp @@ -112,19 +112,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s using namespace duallane; ReturnValue_t result = returnvalue::OK; bool needsSecondStep = false; - if (sideSwitchState == SideSwitchState::REQUESTED) { - sideSwitchState = SideSwitchState::TO_DUAL; - } - // Switch to dual side first, and later switch back to the otherside - if (sideSwitchState == SideSwitchState::TO_DUAL) { - targetSubmodeForSideSwitch = static_cast(submode); - submode = Submodes::DUAL_MODE; - sideSwitchState = SideSwitchState::DISABLE_OTHER_SIDE; - // TODO: Ugly hack. The base class should support arbitrary number of steps.. - needsSecondStep = true; - } else if (sideSwitchState == SideSwitchState::DISABLE_OTHER_SIDE) { - submode = targetSubmodeForSideSwitch; - } + handleSideSwitchStates(submode, needsSecondStep); auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) { if (mode == devMode) { modeTable[tableIdx].setMode(mode); diff --git a/mission/system/acs/DualLaneAssemblyBase.cpp b/mission/system/acs/DualLaneAssemblyBase.cpp index e1ef29cc..858e6892 100644 --- a/mission/system/acs/DualLaneAssemblyBase.cpp +++ b/mission/system/acs/DualLaneAssemblyBase.cpp @@ -130,7 +130,11 @@ void DualLaneAssemblyBase::handleModeReached() { // For dual to single side transition, devices should be logically off, but the switch // handling still needs to be done. if (dualToSingleSideTransition) { - pwrStateMachine.start(targetMode, targetSubmode); + if (sideSwitchState == SideSwitchState::DISABLE_OTHER_SIDE) { + pwrStateMachine.start(targetMode, targetSubmodeForSideSwitch); + } else { + pwrStateMachine.start(targetMode, targetSubmode); + } pwrStateMachineWrapper(); return; } @@ -238,6 +242,24 @@ bool DualLaneAssemblyBase::sideSwitchTransition(Mode_t mode, Submode_t submode) return false; } +void DualLaneAssemblyBase::handleSideSwitchStates(uint8_t& submode, bool& needsSecondStep) { + if (sideSwitchState == SideSwitchState::REQUESTED) { + sideSwitchState = SideSwitchState::TO_DUAL; + } + // Switch to dual side first, and later switch back to the otherside + if (sideSwitchState == SideSwitchState::TO_DUAL) { + targetSubmodeForSideSwitch = static_cast(submode); + submode = duallane::Submodes::DUAL_MODE; + sideSwitchState = SideSwitchState::DISABLE_OTHER_SIDE; + // TODO: Ugly hack. The base class should support arbitrary number of steps.. + needsSecondStep = true; + } else if (sideSwitchState == SideSwitchState::DISABLE_OTHER_SIDE) { + // Set this flag because the power needs to be switched off. + dualToSingleSideTransition = true; + submode = targetSubmodeForSideSwitch; + } +} + void DualLaneAssemblyBase::finishModeOp() { using namespace duallane; AssemblyBase::handleModeReached(); diff --git a/mission/system/acs/DualLaneAssemblyBase.h b/mission/system/acs/DualLaneAssemblyBase.h index 485f3d9d..d15a2f30 100644 --- a/mission/system/acs/DualLaneAssemblyBase.h +++ b/mission/system/acs/DualLaneAssemblyBase.h @@ -48,6 +48,13 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF { MessageQueueIF* eventQueue = nullptr; + /** + * To be called in mode command packer function of the child class. + * @param submode + * @param needsSecondStep + */ + void handleSideSwitchStates(uint8_t& submode, bool& needsSecondStep); + /** * Check whether it makes sense to send mode commands to the device. * @param object diff --git a/mission/system/acs/SusAssembly.cpp b/mission/system/acs/SusAssembly.cpp index 45123ce4..13946c13 100644 --- a/mission/system/acs/SusAssembly.cpp +++ b/mission/system/acs/SusAssembly.cpp @@ -45,6 +45,7 @@ ReturnValue_t SusAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submod using namespace duallane; ReturnValue_t result = returnvalue::OK; bool needsSecondStep = false; + handleSideSwitchStates(submode, needsSecondStep); auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, uint8_t tableIdx) { if (mode == devMode) { modeTable[tableIdx].setMode(mode); diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index a5f0ec66..bace6025 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -9,6 +9,7 @@ #include #include +#include "eive/definitions.h" #include "fsfw/ipc/CommandMessage.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/tmstorage/TmStoreMessage.h" @@ -289,7 +290,7 @@ ReturnValue_t PersistentTmStore::pathToTime(const std::filesystem::path& path, s auto pathStr = path.string(); size_t splitChar = pathStr.find('_'); auto timeOnlyStr = pathStr.substr(splitChar + 1); - if (nullptr == strptime(timeOnlyStr.c_str(), FILE_DATE_FORMAT, &time)) { + if (nullptr == strptime(timeOnlyStr.c_str(), config::FILE_DATE_FORMAT, &time)) { return returnvalue::FAILED; } return returnvalue::OK; @@ -306,7 +307,7 @@ ReturnValue_t PersistentTmStore::createMostRecentFile(std::optional suf time_t epoch = currentTv.tv_sec; struct tm* time = gmtime(&epoch); size_t writtenBytes = strftime(reinterpret_cast(fileBuf.data() + currentIdx), - fileBuf.size(), FILE_DATE_FORMAT, time); + fileBuf.size(), config::FILE_DATE_FORMAT, time); if (writtenBytes == 0) { sif::error << "PersistentTmStore::createMostRecentFile: Could not create file timestamp" << std::endl; diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index 4839f2fb..17d2c9e7 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -85,8 +85,6 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { private: static constexpr uint8_t MAX_FILES_IN_ONE_SECOND = 10; static constexpr size_t MAX_FILESIZE = 8192; - // ISO8601 timestamp. - static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ"; //! [EXPORT] : [SKIP] static constexpr ReturnValue_t INVALID_FILE_DETECTED_AND_DELETED = returnvalue::makeCode(2, 1); diff --git a/tmtc b/tmtc index 523dd9b7..cef8d623 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 523dd9b759a57c5bff2ae9221eee303dfa080558 +Subproject commit cef8d623c9fa11237fc8e51e5fd4dab750a5602b