diff --git a/CHANGELOG.md b/CHANGELOG.md index b7143400..a6d88025 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +# [v7.1.0] 2023-10-11 + +- Bumped `eive-tmtc` to v5.8.0. +- Activate Xiphos WDT with a timeout period of 80 seconds using the `libxiphos` API. The WDT + calls are done by the new `XiphosWdtHandler` object. + # [v7.0.0] 2023-10-11 - Bumped `eive-tmtc` to v5.7.1. diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b02cfdb..65e85d35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 7) -set(OBSW_VERSION_MINOR 0) +set(OBSW_VERSION_MINOR 1) 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 77df8166..9bb03ff0 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 313 translations. * @details - * Generated on: 2023-10-10 13:50:27 + * Generated on: 2023-10-11 10:54:39 */ #include "translateEvents.h" diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 8d80ca56..7e795093 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 173 translations. - * Generated on: 2023-10-10 13:50:27 + * Contains 174 translations. + * Generated on: 2023-10-11 10:54:39 */ #include "translateObjects.h" @@ -11,6 +11,7 @@ const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER"; const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER"; const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER"; const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG"; +const char *XIPHOS_WDT_STRING = "XIPHOS_WDT"; const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER"; const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER"; const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER"; @@ -192,6 +193,8 @@ const char *translateObject(object_id_t object) { return POWER_CONTROLLER_STRING; case 0x43000006: return GLOBAL_JSON_CFG_STRING; + case 0x43000007: + return XIPHOS_WDT_STRING; case 0x43400001: return THERMAL_CONTROLLER_STRING; case 0x44000001: diff --git a/bsp_q7s/core/CMakeLists.txt b/bsp_q7s/core/CMakeLists.txt index 33550144..530b53e9 100644 --- a/bsp_q7s/core/CMakeLists.txt +++ b/bsp_q7s/core/CMakeLists.txt @@ -1 +1,2 @@ -target_sources(${OBSW_NAME} PRIVATE CoreController.cpp WatchdogHandler.cpp) +target_sources(${OBSW_NAME} PRIVATE CoreController.cpp WatchdogHandler.cpp + XiphosWdtHandler.cpp) diff --git a/bsp_q7s/core/XiphosWdtHandler.cpp b/bsp_q7s/core/XiphosWdtHandler.cpp new file mode 100644 index 00000000..8444b65f --- /dev/null +++ b/bsp_q7s/core/XiphosWdtHandler.cpp @@ -0,0 +1,122 @@ +#include "XiphosWdtHandler.h" + +#include "fsfw/ipc/QueueFactory.h" + +XiphosWdtHandler::XiphosWdtHandler(object_id_t objectId) + : SystemObject(objectId), + requestQueue(QueueFactory::instance()->createMessageQueue()), + actionHelper(this, requestQueue) {} + +ReturnValue_t XiphosWdtHandler::initialize() { + ReturnValue_t result = actionHelper.initialize(); + if (result != returnvalue::OK) { + return result; + } + int retval = xsc_watchdog_init(&wdtHandle); + if (retval != 0) { + sif::error << "XiphosWdtHandler: Initiating watchdog failed with code " << retval << ": " + << strerror(retval) << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + if (wdtHandle == nullptr) { + sif::error << "XiphosWdtHandler: WDT handle is nullptr!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + retval = xsc_watchdog_set_timeout(wdtHandle, timeoutSeconds); + if (retval != 0) { + // This propably means that the default timeout is used. Still continue with task init. + sif::warning << "XiphosWdtHandler: Setting WDT timeout of " << timeoutSeconds + << " seconds failed with code " << result << ": " << strerror(retval) << std::endl; + } + return enableWdt(); +} + +ReturnValue_t XiphosWdtHandler::performOperation(uint8_t opCode) { + CommandMessage command; + ReturnValue_t result; + for (result = requestQueue->receiveMessage(&command); result == returnvalue::OK; + result = requestQueue->receiveMessage(&command)) { + result = actionHelper.handleActionMessage(&command); + if (result == returnvalue::OK) { + continue; + } + sif::warning << "Can not handle message with message type " << command.getMessageType() + << std::endl; + } + if (enabled) { + int retval = xsc_watchdog_keepalive(wdtHandle); + if (retval != 0) { + sif::warning << "XiphosWdtHandler: Feeding WDT failed with code " << retval << ": " + << strerror(retval) << std::endl; + return returnvalue::FAILED; + } + } + return returnvalue::OK; +} + +ReturnValue_t XiphosWdtHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t *data, size_t size) { + switch (actionId) { + case (ActionId::ENABLE): { + ReturnValue_t result = enableWdt(); + if (result != returnvalue::OK) { + return result; + } + return EXECUTION_FINISHED; + } + case (ActionId::DISABLE): { + ReturnValue_t result = disableWdt(); + if (result != returnvalue::OK) { + return result; + } + return EXECUTION_FINISHED; + } + } + return HasActionsIF::INVALID_ACTION_ID; +} + +ReturnValue_t XiphosWdtHandler::enableWdt() { + int nowayout = 0; + int status = 0; + int retval = xsc_watchdog_get_status(&nowayout, &status); + // If this fails for whatever reason, just try enabling in any case. + if (retval != 0) { + sif::warning << "XiphosWdtHandler: Getting WDT status failed" << std::endl; + } + // Of course the enable API will fail if the device is already on, just perfect, love me some + // good C API... :))) + if (retval != 0 or status == 0) { + retval = xsc_watchdog_enable(wdtHandle); + if (retval != 0) { + sif::error << "XiphosWdtHandler: Enabling WDT failed with code " << retval << ": " + << strerror(retval) << std::endl; + return returnvalue::FAILED; + } + } + enabled = true; + return returnvalue::OK; +} + +ReturnValue_t XiphosWdtHandler::disableWdt() { + int nowayout = 0; + int status = 0; + int retval = xsc_watchdog_get_status(&nowayout, &status); + // If this fails for whatever reason, just try disabling in any case. + if (retval != 0) { + sif::warning << "XiphosWdtHandler: Getting WDT status failed" << std::endl; + } + // Of course the disable API will fail if the device is already off, just perfect, love me some + // good C API... :))) + if (retval != 0 or status == 1) { + retval = xsc_watchdog_disable(wdtHandle); + if (retval != 0) { + sif::error << "XiphosWdtHandler: Disabling WDT failed with code " << retval << ": " + << strerror(retval) << std::endl; + return returnvalue::FAILED; + } + } + enabled = false; + return returnvalue::OK; +} + +MessageQueueId_t XiphosWdtHandler::getCommandQueue() const { return requestQueue->getId(); } diff --git a/bsp_q7s/core/XiphosWdtHandler.h b/bsp_q7s/core/XiphosWdtHandler.h new file mode 100644 index 00000000..a8d73f48 --- /dev/null +++ b/bsp_q7s/core/XiphosWdtHandler.h @@ -0,0 +1,36 @@ +#ifndef BSP_Q7S_CORE_XIPHOSWDTHANDLER_H_ +#define BSP_Q7S_CORE_XIPHOSWDTHANDLER_H_ + +#include +#include +#include +#include + +class XiphosWdtHandler : public SystemObject, public ExecutableObjectIF, public HasActionsIF { + public: + enum ActionId { ENABLE = 0, DISABLE = 1 }; + + XiphosWdtHandler(object_id_t objectId); + ReturnValue_t performOperation(uint8_t opCode) override; + ReturnValue_t initialize() override; + + ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t* data, size_t size) override; + [[nodiscard]] virtual MessageQueueId_t getCommandQueue() const override; + + private: + // Wrappers to ensure idempotency of trash C API. + ReturnValue_t enableWdt(); + ReturnValue_t disableWdt(); + // Timeout duration range specified by Xiphos: 0.001 seconds to 171 seconds. The libxiphos API + // expects an int, so I guess this translates to 1 to 171 seconds. + // WARNING: DO NOT SET THIS HIGHER THAN 80 SECONDS! + // Possible bug in Xiphos/Xilinx kernel driver for watchdog, related to overflow. + int timeoutSeconds = 80; + bool enabled = false; + struct watchdog_s* wdtHandle = nullptr; + MessageQueueIF* requestQueue = nullptr; + ActionHelper actionHelper; +}; + +#endif /* BSP_Q7S_CORE_XIPHOSWDTHANDLER_H_ */ diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 370e8d3d..3a16dcec 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -37,6 +38,7 @@ void ObjectFactory::produce(void* args) { PersistentTmStores stores; readFirmwareVersion(); + new XiphosWdtHandler(objects::XIPHOS_WDT); ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, *SdCardManager::instance(), &ipcStore, &tmStore, stores, 200, enableHkSets); diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index c01c4ccb..57e2e0c4 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -34,6 +35,7 @@ void ObjectFactory::produce(void* args) { PersistentTmStores stores; readFirmwareVersion(); + new XiphosWdtHandler(objects::XIPHOS_WDT); ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, *SdCardManager::instance(), &ipcStore, &tmStore, stores, 200, true); diff --git a/bsp_q7s/scheduling.cpp b/bsp_q7s/scheduling.cpp index fa7fbe18..3c30e91a 100644 --- a/bsp_q7s/scheduling.cpp +++ b/bsp_q7s/scheduling.cpp @@ -82,6 +82,16 @@ void scheduling::initTasks() { } #endif + // Medium priority, higher than something like payload, but not the highest priority to also + // detect tasks which choke other tasks. + PeriodicTaskIF* xiphosWdtTask = + factory->createPeriodicTask("XIPHOS_WDT", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, + missedDeadlineFunc, &RR_SCHEDULING); + result = xiphosWdtTask->addComponent(objects::XIPHOS_WDT); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("XIPHOS_WDT", objects::XIPHOS_WDT); + } + PeriodicTaskIF* coreCtrlTask = factory->createPeriodicTask( "CORE_CTRL", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc, &RR_SCHEDULING); result = coreCtrlTask->addComponent(objects::CORE_CONTROLLER); @@ -414,6 +424,7 @@ void scheduling::initTasks() { }; sif::info << "Starting tasks.." << std::endl; + xiphosWdtTask->startTask(); tmTcDistributor->startTask(); #if OBSW_ADD_TCPIP_SERVERS == 1 diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 5d93dffc..d6b15b8d 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -28,6 +28,7 @@ enum commonObjects : uint32_t { CORE_CONTROLLER = 0x43000003, POWER_CONTROLLER = 0x43000004, GLOBAL_JSON_CFG = 0x43000006, + XIPHOS_WDT = 0x43000007, /* 0x44 ('D') for device handlers */ MGM_0_LIS3_HANDLER = 0x44120006, diff --git a/generators/bsp_hosted_objects.csv b/generators/bsp_hosted_objects.csv index 4cb21f46..689a58f2 100644 --- a/generators/bsp_hosted_objects.csv +++ b/generators/bsp_hosted_objects.csv @@ -3,6 +3,7 @@ 0x43000003;CORE_CONTROLLER 0x43000004;POWER_CONTROLLER 0x43000006;GLOBAL_JSON_CFG +0x43000007;XIPHOS_WDT 0x43400001;THERMAL_CONTROLLER 0x44000001;DUMMY_HANDLER 0x44120006;MGM_0_LIS3_HANDLER diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 914b7df6..10cfed26 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -3,6 +3,7 @@ 0x43000003;CORE_CONTROLLER 0x43000004;POWER_CONTROLLER 0x43000006;GLOBAL_JSON_CFG +0x43000007;XIPHOS_WDT 0x43400001;THERMAL_CONTROLLER 0x44120006;MGM_0_LIS3_HANDLER 0x44120010;GYRO_0_ADIS_HANDLER diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 77df8166..9bb03ff0 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 313 translations. * @details - * Generated on: 2023-10-10 13:50:27 + * Generated on: 2023-10-11 10:54:39 */ #include "translateEvents.h" diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index aeb2b405..0599cc18 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 177 translations. - * Generated on: 2023-10-10 13:50:27 + * Contains 178 translations. + * Generated on: 2023-10-11 10:54:39 */ #include "translateObjects.h" @@ -11,6 +11,7 @@ const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER"; const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER"; const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER"; const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG"; +const char *XIPHOS_WDT_STRING = "XIPHOS_WDT"; const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER"; const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER"; const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_HANDLER"; @@ -196,6 +197,8 @@ const char *translateObject(object_id_t object) { return POWER_CONTROLLER_STRING; case 0x43000006: return GLOBAL_JSON_CFG_STRING; + case 0x43000007: + return XIPHOS_WDT_STRING; case 0x43400001: return THERMAL_CONTROLLER_STRING; case 0x44120006: diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 77df8166..9bb03ff0 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** * @brief Auto-generated event translation file. Contains 313 translations. * @details - * Generated on: 2023-10-10 13:50:27 + * Generated on: 2023-10-11 10:54:39 */ #include "translateEvents.h" diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index aeb2b405..0599cc18 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 177 translations. - * Generated on: 2023-10-10 13:50:27 + * Contains 178 translations. + * Generated on: 2023-10-11 10:54:39 */ #include "translateObjects.h" @@ -11,6 +11,7 @@ const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER"; const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER"; const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER"; const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG"; +const char *XIPHOS_WDT_STRING = "XIPHOS_WDT"; const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER"; const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER"; const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_HANDLER"; @@ -196,6 +197,8 @@ const char *translateObject(object_id_t object) { return POWER_CONTROLLER_STRING; case 0x43000006: return GLOBAL_JSON_CFG_STRING; + case 0x43000007: + return XIPHOS_WDT_STRING; case 0x43400001: return THERMAL_CONTROLLER_STRING; case 0x44120006: diff --git a/mission/controller/CMakeLists.txt b/mission/controller/CMakeLists.txt index 901decc0..690ede64 100644 --- a/mission/controller/CMakeLists.txt +++ b/mission/controller/CMakeLists.txt @@ -1,7 +1,7 @@ if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "") - target_sources(${LIB_EIVE_MISSION} PRIVATE ThermalController.cpp - AcsController.cpp - PowerController.cpp) + target_sources( + ${LIB_EIVE_MISSION} PRIVATE ThermalController.cpp AcsController.cpp + PowerController.cpp) endif() add_subdirectory(acs) diff --git a/mission/system/power/CMakeLists.txt b/mission/system/power/CMakeLists.txt index a7e91e05..2c720978 100644 --- a/mission/system/power/CMakeLists.txt +++ b/mission/system/power/CMakeLists.txt @@ -1 +1,2 @@ -target_sources(${LIB_EIVE_MISSION} PRIVATE epsModeTree.cpp EpsSubsystem.cpp GomspacePowerFdir.cpp) +target_sources(${LIB_EIVE_MISSION} PRIVATE epsModeTree.cpp EpsSubsystem.cpp + GomspacePowerFdir.cpp) diff --git a/tmtc b/tmtc index 39e6a048..e249f147 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 39e6a0488922590900b862e5e70524be1d6ec5ba +Subproject commit e249f147bc1738003d31290df8f2b525d91c3482