diff --git a/CHANGELOG.md b/CHANGELOG.md index f00c574e..118b667c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,10 +22,10 @@ will consitute of a breaking change warranting a new major release: - Internal error reporter set is now enabled by defalt and generated every 120 seconds. -# [v4.0.0] to be released +# [v4.0.0] 2023-06-22 -- `eive-tmtc` version v4.0.0 -- `q7s-package` version v3.0.0 +- `eive-tmtc` version v5.0.0 +- `q7s-package` version v3.1.1 ## Fixed @@ -38,11 +38,18 @@ will consitute of a breaking change warranting a new major release: - Removed PTME busy/ready signals. Those were not used anyway because register reads are used now. - APB bus access busy checking is not done anymore as this is performed by the bus itself now. +- Core controller will now announce version and image information event in addition to reboot + event in the `inititalize` function. +- Core controller will now try to request and announce the firmware version in addition to the + OBSW version as well. +- Added core controller action to read reboot mechansm information +- GNSS reset pin will now only be asserted for 5 ms instead of 100 ms. ## Added -- Added PL I2C reset pin. It is not used for now but could be used for FDIR procedures to restore - the PL I2C. +- Added PL I2C reset pin. It is not used/connected for now but could be used for FDIR procedures to + restore the PL I2C. +- Core controller now announces firmware version as well when requesting a version info event # [v3.3.0] 2023-06-21 @@ -182,7 +189,6 @@ Like v3.2.0 but without the custom FM changes related to VC0. # [v2.0.5] 2023-05-11 - - The dual lane assembly transition failed handler started new transitions towards the current mode instead of the target mode. This means that if the dual lane assembly never reached the initial submode (e.g. mode normal and submode dual side), it will transition back to the current mode, diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 0128d961..4e006298 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -171,6 +171,8 @@ ReturnValue_t CoreController::initialize() { sdStateMachine(); triggerEvent(core::REBOOT_SW, CURRENT_CHIP, CURRENT_COPY); + announceCurrentImageInfo(); + announceVersionInfo(); EventManagerIF *eventManager = ObjectManager::instance()->get(objects::EVENT_MANAGER); if (eventManager == nullptr or eventQueue == nullptr) { @@ -220,24 +222,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ using namespace core; switch (actionId) { case (ANNOUNCE_VERSION): { - uint32_t p1 = (common::OBSW_VERSION_MAJOR << 24) | (common::OBSW_VERSION_MINOR << 16) | - (common::OBSW_VERSION_REVISION << 8); - uint32_t p2 = 0; - if (strcmp("", common::OBSW_VERSION_CST_GIT_SHA1) != 0) { - p1 |= 1; - auto shaAsStr = std::string(common::OBSW_VERSION_CST_GIT_SHA1); - size_t posDash = shaAsStr.find("-"); - auto gitHash = shaAsStr.substr(posDash + 2, 4); - // Only copy first 4 letters of git hash - memcpy(&p2, gitHash.c_str(), 4); - } - - triggerEvent(VERSION_INFO, p1, p2); - if (mappedSysRomAddr != nullptr) { - uint32_t p1Firmware = *(reinterpret_cast(mappedSysRomAddr)); - uint32_t p2Firmware = *(reinterpret_cast(mappedSysRomAddr) + 1); - triggerEvent(FIRMWARE_INFO, p1Firmware, p2Firmware); - } + announceVersionInfo(); return HasActionsIF::EXECUTION_FINISHED; } case (ANNOUNCE_BOOT_COUNTS): { @@ -245,7 +230,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ return HasActionsIF::EXECUTION_FINISHED; } case (ANNOUNCE_CURRENT_IMAGE): { - triggerEvent(CURRENT_IMAGE_INFO, CURRENT_CHIP, CURRENT_COPY); + announceCurrentImageInfo(); return HasActionsIF::EXECUTION_FINISHED; } case (LIST_DIRECTORY_INTO_FILE): { @@ -261,6 +246,9 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ return result; } std::ostringstream oss("cp ", std::ostringstream::ate); + if (parser.isForceOptSet()) { + oss << "-f "; + } if (parser.isRecursiveOptSet()) { oss << "-r "; } @@ -334,7 +322,6 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ return HasActionsIF::INVALID_PARAMETERS; } std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_FILE; - // Disable the reboot file mechanism parseRebootFile(path, rebootFile); if (data[0] == 0) { rebootFile.enabled = false; @@ -347,6 +334,16 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ } return HasActionsIF::EXECUTION_FINISHED; } + case (READ_REBOOT_MECHANISM_INFO): { + std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_FILE; + parseRebootFile(path, rebootFile); + RebootMechanismPacket packet(rebootFile); + ReturnValue_t result = actionHelper.reportData(commandedBy, actionId, &packet); + if (result != returnvalue::OK) { + return result; + } + return HasActionsIF::EXECUTION_FINISHED; + } case (RESET_REBOOT_COUNTERS): { if (size == 0) { resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY); @@ -2013,7 +2010,6 @@ bool CoreController::parseRebootFile(std::string path, RebootFile &rf) { void CoreController::resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy) { std::string path = currMntPrefix + REBOOT_FILE; - // Disable the reboot file mechanism parseRebootFile(path, rebootFile); if (tgtChip == xsc::ALL_CHIP and tgtCopy == xsc::ALL_COPY) { rebootFile.img00Cnt = 0; @@ -2420,6 +2416,33 @@ void CoreController::dirListingDumpHandler() { } } +void CoreController::announceVersionInfo() { + using namespace core; + uint32_t p1 = (common::OBSW_VERSION_MAJOR << 24) | (common::OBSW_VERSION_MINOR << 16) | + (common::OBSW_VERSION_REVISION << 8); + uint32_t p2 = 0; + if (strcmp("", common::OBSW_VERSION_CST_GIT_SHA1) != 0) { + p1 |= 1; + auto shaAsStr = std::string(common::OBSW_VERSION_CST_GIT_SHA1); + size_t posDash = shaAsStr.find("-"); + auto gitHash = shaAsStr.substr(posDash + 2, 4); + // Only copy first 4 letters of git hash + memcpy(&p2, gitHash.c_str(), 4); + } + + triggerEvent(VERSION_INFO, p1, p2); + if (mappedSysRomAddr != nullptr) { + uint32_t p1Firmware = *(reinterpret_cast(mappedSysRomAddr)); + uint32_t p2Firmware = *(reinterpret_cast(mappedSysRomAddr) + 1); + triggerEvent(FIRMWARE_INFO, p1Firmware, p2Firmware); + } +} + +void CoreController::announceCurrentImageInfo() { + using namespace core; + triggerEvent(CURRENT_IMAGE_INFO, CURRENT_CHIP, CURRENT_COPY); +} + bool CoreController::isNumber(const std::string &s) { return !s.empty() && std::find_if(s.begin(), s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end(); diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 6703e398..7ab80aa7 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -45,6 +45,61 @@ struct RebootFile { xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY; }; +class RebootMechanismPacket : public SerialLinkedListAdapter { + public: + RebootMechanismPacket(RebootFile& rf) { + enabled = rf.enabled; + maxCount = rf.maxCount; + img00Count = rf.img00Cnt; + img01Count = rf.img01Cnt; + img10Count = rf.img10Cnt; + img11Count = rf.img11Cnt; + img00Lock = rf.img00Lock; + img01Lock = rf.img01Lock; + img10Lock = rf.img10Lock; + img11Lock = rf.img11Lock; + lastChip = static_cast(rf.lastChip); + lastCopy = static_cast(rf.lastCopy); + nextChip = static_cast(rf.mechanismNextChip); + nextCopy = static_cast(rf.mechanismNextCopy); + setLinks(); + } + + private: + void setLinks() { + setStart(&enabled); + enabled.setNext(&maxCount); + maxCount.setNext(&img00Count); + img00Count.setNext(&img01Count); + img01Count.setNext(&img10Count); + img10Count.setNext(&img11Count); + img11Count.setNext(&img00Lock); + img00Lock.setNext(&img01Lock); + img01Lock.setNext(&img10Lock); + img10Lock.setNext(&img11Lock); + img11Lock.setNext(&lastChip); + lastChip.setNext(&lastCopy); + lastCopy.setNext(&nextChip); + nextChip.setNext(&nextCopy); + setLast(&nextCopy); + } + + SerializeElement enabled = false; + SerializeElement maxCount = 0; + SerializeElement img00Count = 0; + SerializeElement img01Count = 0; + SerializeElement img10Count = 0; + SerializeElement img11Count = 0; + SerializeElement img00Lock = false; + SerializeElement img01Lock = false; + SerializeElement img10Lock = false; + SerializeElement img11Lock = false; + SerializeElement lastChip = 0; + SerializeElement lastCopy = 0; + SerializeElement nextChip = 0; + SerializeElement nextCopy = 0; +}; + class CoreController : public ExtendedControllerBase, public ReceivesParameterMessagesIF { public: enum ParamId : uint8_t { PREF_SD = 0, NUM_IDS }; @@ -289,6 +344,8 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe bool parseRebootFile(std::string path, RebootFile& file); void rewriteRebootFile(RebootFile file); void announceBootCounts(); + void announceVersionInfo(); + void announceCurrentImageInfo(); void readHkData(); void dirListingDumpHandler(); bool isNumber(const std::string& s); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 54084089..35d30c1a 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -506,7 +506,7 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* debugGps = true; #endif RESET_ARGS_GNSS.gpioComIF = gpioComIF; - RESET_ARGS_GNSS.waitPeriodMs = 100; + RESET_ARGS_GNSS.waitPeriodMs = 5; auto gpsCtrl = new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, enableHkSets, debugGps); gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS); diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index d068bed0..2e171e02 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -84,21 +84,6 @@ void ObjectFactory::produce(void* args) { new CoreController(objects::CORE_CONTROLLER, enableHkSets); - // Regular FM code, does not work for EM if the hardware is not connected - // createPcduComponents(gpioComIF, &pwrSwitcher); - // createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher); - // createSyrlinksComponents(pwrSwitcher); - // createSunSensorComponents(gpioComIF, spiMainComIF, pwrSwitcher, q7s::SPI_DEFAULT_DEV); - // createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher, spiMainComIF); - // createTmpComponents(); - // createSolarArrayDeploymentComponents(); - // createPayloadComponents(gpioComIF); - // createHeaterComponents(gpioComIF, pwrSwitcher, healthTable); - - // TODO: Careful! Switching this on somehow messes with the communication with the ProASIC - // and will cause xsc_boot_copy commands to always boot to 0 0 - // createRadSensorComponent(gpioComIF); - #if OBSW_ADD_ACS_BOARD == 1 // Still initialize chip select to avoid SPI bus issues. createRadSensorChipSelect(gpioComIF); diff --git a/dummies/ImtqDummy.cpp b/dummies/ImtqDummy.cpp index 0c8f9076..8570a9be 100644 --- a/dummies/ImtqDummy.cpp +++ b/dummies/ImtqDummy.cpp @@ -5,14 +5,19 @@ ImtqDummy::ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, power::Switch_t pwrSwitcher, bool enableHkSets) : DeviceHandlerBase(objectId, comif, comCookie), - setNoTorque(this), - setWithTorque(this), enableHkSets(enableHkSets), + statusSet(this), + dipoleSet(*this), + rawMtmNoTorque(this), + hkDatasetNoTorque(this), + rawMtmWithTorque(this), + hkDatasetWithTorque(this), + calMtmMeasurementSet(this), switcher(pwrSwitcher) {} ImtqDummy::~ImtqDummy() = default; -void ImtqDummy::doStartUp() { setMode(MODE_NORMAL); } +void ImtqDummy::doStartUp() { setMode(MODE_ON); } void ImtqDummy::doShutDown() { setMode(_MODE_POWER_DOWN); } @@ -79,17 +84,37 @@ ReturnValue_t ImtqDummy::initializeLocalDataPool(localpool::DataPool &localDataP localDataPoolMap.emplace(imtq::MCU_TEMPERATURE_WT, new PoolEntry({0})); poolManager.subscribeForDiagPeriodicPacket( - subdp::DiagnosticsHkPeriodicParams(setNoTorque.getSid(), enableHkSets, 30.0)); + subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 30.0)); poolManager.subscribeForDiagPeriodicPacket( - subdp::DiagnosticsHkPeriodicParams(setWithTorque.getSid(), enableHkSets, 30.0)); + subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 30.0)); + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(rawMtmNoTorque.getSid(), false, 10.0)); + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(rawMtmWithTorque.getSid(), false, 10.0)); + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(calMtmMeasurementSet.getSid(), false, 10.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(statusSet.getSid(), false, 10.0)); + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(dipoleSet.getSid(), false, 10.0)); return DeviceHandlerBase::initializeLocalDataPool(localDataPoolMap, poolManager); } LocalPoolDataSetBase *ImtqDummy::getDataSetHandle(sid_t sid) { - if (sid == setNoTorque.getSid()) { - return &setNoTorque; - } else if (sid == setWithTorque.getSid()) { - return &setWithTorque; + if (sid == hkDatasetNoTorque.getSid()) { + return &hkDatasetNoTorque; + } else if (sid == dipoleSet.getSid()) { + return &dipoleSet; + } else if (sid == statusSet.getSid()) { + return &statusSet; + } else if (sid == hkDatasetWithTorque.getSid()) { + return &hkDatasetWithTorque; + } else if (sid == rawMtmWithTorque.getSid()) { + return &rawMtmWithTorque; + } else if (sid == calMtmMeasurementSet.getSid()) { + return &calMtmMeasurementSet; + } else if (sid == rawMtmNoTorque.getSid()) { + return &rawMtmNoTorque; } return nullptr; } diff --git a/dummies/ImtqDummy.h b/dummies/ImtqDummy.h index 990df6e0..8c76affc 100644 --- a/dummies/ImtqDummy.h +++ b/dummies/ImtqDummy.h @@ -18,11 +18,18 @@ class ImtqDummy : public DeviceHandlerBase { ~ImtqDummy() override; protected: - ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override; - imtq::HkDatasetNoTorque setNoTorque; - imtq::HkDatasetWithTorque setWithTorque; bool enableHkSets; + imtq::StatusDataset statusSet; + imtq::DipoleActuationSet dipoleSet; + imtq::RawMtmMeasurementNoTorque rawMtmNoTorque; + imtq::HkDatasetNoTorque hkDatasetNoTorque; + + imtq::RawMtmMeasurementWithTorque rawMtmWithTorque; + imtq::HkDatasetWithTorque hkDatasetWithTorque; + + imtq::CalibratedMtmMeasurementSet calMtmMeasurementSet; + PoolEntry statusMode = PoolEntry({0}); PoolEntry statusError = PoolEntry({0}); PoolEntry statusConfig = PoolEntry({0}); @@ -42,6 +49,8 @@ class ImtqDummy : public DeviceHandlerBase { power::Switch_t switcher = power::NO_SWITCH; + ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override; + void doStartUp() override; void doShutDown() override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; diff --git a/dummies/RwDummy.cpp b/dummies/RwDummy.cpp index 60652ef7..0bf4db42 100644 --- a/dummies/RwDummy.cpp +++ b/dummies/RwDummy.cpp @@ -3,13 +3,24 @@ #include RwDummy::RwDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie) - : DeviceHandlerBase(objectId, comif, comCookie) {} + : DeviceHandlerBase(objectId, comif, comCookie), + + statusSet(this), + lastResetStatusSet(this), + tmDataset(this), + rwSpeedActuationSet(*this) {} RwDummy::~RwDummy() {} -void RwDummy::doStartUp() { setMode(MODE_ON); } +void RwDummy::doStartUp() { + statusSet.setReportingEnabled(true); + setMode(MODE_ON); +} -void RwDummy::doShutDown() { setMode(MODE_OFF); } +void RwDummy::doShutDown() { + statusSet.setReportingEnabled(false); + setMode(MODE_OFF); +} ReturnValue_t RwDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) { return NOTHING_TO_SEND; } @@ -74,5 +85,11 @@ ReturnValue_t RwDummy::initializeLocalDataPool(localpool::DataPool &localDataPoo localDataPoolMap.emplace(rws::SPI_BYTES_READ, new PoolEntry({0})); localDataPoolMap.emplace(rws::SPI_REG_OVERRUN_ERRORS, new PoolEntry({0})); localDataPoolMap.emplace(rws::SPI_TOTAL_ERRORS, new PoolEntry({0})); + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(statusSet.getSid(), false, 12.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(tmDataset.getSid(), false, 30.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(lastResetStatusSet.getSid(), false, 30.0)); return returnvalue::OK; } diff --git a/dummies/RwDummy.h b/dummies/RwDummy.h index 5673717a..03629937 100644 --- a/dummies/RwDummy.h +++ b/dummies/RwDummy.h @@ -2,6 +2,7 @@ #define DUMMIES_RWDUMMY_H_ #include +#include class RwDummy : public DeviceHandlerBase { public: @@ -15,6 +16,11 @@ class RwDummy : public DeviceHandlerBase { virtual ~RwDummy(); protected: + rws::StatusSet statusSet; + rws::LastResetSatus lastResetStatusSet; + rws::TmDataset tmDataset; + rws::RwSpeedActuationSet rwSpeedActuationSet; + PoolEntry rwSpeed = PoolEntry({0}); PoolEntry rampTime = PoolEntry({10}); diff --git a/mission/sysDefs.h b/mission/sysDefs.h index 41c7d43d..32ce9642 100644 --- a/mission/sysDefs.h +++ b/mission/sysDefs.h @@ -53,6 +53,7 @@ static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5; static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6; static constexpr ActionId_t SWITCH_IMG_LOCK = 7; static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8; +static constexpr ActionId_t READ_REBOOT_MECHANISM_INFO = 9; static constexpr ActionId_t OBSW_UPDATE_FROM_SD_0 = 10; static constexpr ActionId_t OBSW_UPDATE_FROM_SD_1 = 11; @@ -248,19 +249,22 @@ class CpHelperParser { CpHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {} ReturnValue_t parse() { - if (maxLen < 1) { + if (maxLen < 2) { return SerializeIF::STREAM_TOO_SHORT; } recursiveOpt = data[0]; - return parseDestTargetString(data + 1, maxLen - 1, destTgt); + forceOpt = data[1]; + return parseDestTargetString(data + 2, maxLen - 2, destTgt); } const SourceTargetPair& destTgtPair() const { return destTgt; } bool isRecursiveOptSet() const { return recursiveOpt; } + bool isForceOptSet() const { return forceOpt; } private: const uint8_t* data; size_t maxLen; bool recursiveOpt = false; + bool forceOpt = false; SourceTargetPair destTgt; }; diff --git a/release_checklist.md b/release-checklist.md similarity index 100% rename from release_checklist.md rename to release-checklist.md diff --git a/tmtc b/tmtc index e0457831..c9f4a807 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit e0457831d72e0de8611c5f56221a30f19aea7e2f +Subproject commit c9f4a8070d20bc659809d5b822ac5a17548f57a4