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..38d206db --- /dev/null +++ b/bsp_q7s/core/XiphosWdtHandler.cpp @@ -0,0 +1,39 @@ +#include "XiphosWdtHandler.h" + +XiphosWdtHandler::XiphosWdtHandler(object_id_t objectId) : SystemObject(objectId) {} + +ReturnValue_t XiphosWdtHandler::initialize() { + int result = xsc_watchdog_init(&wdtHandle); + if (result != 0) { + sif::error << "XiphosWdtHandler: Initiating watchdog failed with code " << result << ": " + << strerror(result) << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + if (wdtHandle == nullptr) { + sif::error << "XiphosWdtHandler: WDT handle is nullptr!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + result = xsc_watchdog_set_timeout(wdtHandle, timeoutSeconds); + if (result != 0) { + sif::error << "XiphosWdtHandler: Setting WDT timeout of " << timeoutSeconds + << " seconds failed with code " << result << ": " << strerror(result) << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + result = xsc_watchdog_enable(wdtHandle); + if (result != 0) { + sif::error << "XiphosWdtHandler: Enabling WDT failed with code " << result << ": " + << strerror(result) << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + return returnvalue::OK; +} + +ReturnValue_t XiphosWdtHandler::performOperation(uint8_t opCode) { + int result = xsc_watchdog_keepalive(wdtHandle); + if (result != 0) { + sif::warning << "XiphosWdtHandler: Feeding WDT failed with code " << result << ": " + << strerror(result) << std::endl; + return returnvalue::FAILED; + } + return returnvalue::OK; +} diff --git a/bsp_q7s/core/XiphosWdtHandler.h b/bsp_q7s/core/XiphosWdtHandler.h new file mode 100644 index 00000000..346c13ef --- /dev/null +++ b/bsp_q7s/core/XiphosWdtHandler.h @@ -0,0 +1,22 @@ +#ifndef BSP_Q7S_CORE_XIPHOSWDTHANDLER_H_ +#define BSP_Q7S_CORE_XIPHOSWDTHANDLER_H_ + +#include +#include +#include +#include + +class XiphosWdtHandler : public SystemObject, public ExecutableObjectIF { + public: + XiphosWdtHandler(object_id_t objectId); + ReturnValue_t performOperation(uint8_t opCode) override; + ReturnValue_t initialize() override; + + private: + // 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. + uint32_t timeoutSeconds = 60; + struct watchdog_s* wdtHandle = nullptr; +}; + +#endif /* BSP_Q7S_CORE_XIPHOSWDTHANDLER_H_ */ diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 976602d4..06867a1c 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 a3ab6bba..83e3d90b 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 d7c179ad..7a94c118 100644 --- a/bsp_q7s/scheduling.cpp +++ b/bsp_q7s/scheduling.cpp @@ -82,6 +82,14 @@ void scheduling::initTasks() { } #endif + PeriodicTaskIF* xiphosWdtTask = + factory->createPeriodicTask("XIPHOS_WDT", 90, 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); @@ -410,6 +418,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 0cc4b9d9..2118aa6d 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -26,6 +26,7 @@ enum commonObjects : uint32_t { THERMAL_CONTROLLER = 0x43400001, ACS_CONTROLLER = 0x43000002, CORE_CONTROLLER = 0x43000003, + XIPHOS_WDT = 0x43000004, GLOBAL_JSON_CFG = 0x43000006, /* 0x44 ('D') for device handlers */ diff --git a/tmtc b/tmtc index 22a42108..783bdd29 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 22a42108b431bafa707de2b3a24cad9de95b70d0 +Subproject commit 783bdd297a931a96c8b077ec2c2456a203b23ffc