From 9a283b0f98e6092b55e960944c2dd7e74275ea9f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 10 Oct 2023 19:15:52 +0200 Subject: [PATCH] add action cmds --- bsp_q7s/core/XiphosWdtHandler.cpp | 124 +++++++++++++++++++++++------- bsp_q7s/core/XiphosWdtHandler.h | 12 ++- tmtc | 2 +- 3 files changed, 108 insertions(+), 30 deletions(-) diff --git a/bsp_q7s/core/XiphosWdtHandler.cpp b/bsp_q7s/core/XiphosWdtHandler.cpp index 5d4da7b6..be087648 100644 --- a/bsp_q7s/core/XiphosWdtHandler.cpp +++ b/bsp_q7s/core/XiphosWdtHandler.cpp @@ -1,48 +1,116 @@ #include "XiphosWdtHandler.h" -XiphosWdtHandler::XiphosWdtHandler(object_id_t objectId) : SystemObject(objectId) {} +#include "fsfw/ipc/QueueFactory.h" + +XiphosWdtHandler::XiphosWdtHandler(object_id_t objectId) + : SystemObject(objectId), + requestQueue(QueueFactory::instance()->createMessageQueue()), + actionHelper(this, requestQueue) {} 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; + 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; } - result = xsc_watchdog_set_timeout(wdtHandle, timeoutSeconds); - if (result != 0) { + 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(result) << std::endl; + << " seconds failed with code " << result << ": " << strerror(retval) << std::endl; } - int nowayout = 0; - int status = 0; - result = xsc_watchdog_get_status(&nowayout, &status); - if (result == 0) { - if (status == 0) { - 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; - } - } - } else { - sif::warning << "XiphosWdtHandler: Getting WDT status failed" << std::endl; - } - return returnvalue::OK; + return enableWdt(); } 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; + 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; + } + 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) { + int retval = xsc_watchdog_enable(wdtHandle); + if (retval != 0) { + sif::error << "XiphosWdtHandler: Enabling WDT failed with code " << retval << ": " + << strerror(retval) << std::endl; + return returnvalue::FAILED; + } + } + 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) { + int retval = xsc_watchdog_disable(wdtHandle); + if (retval != 0) { + sif::error << "XiphosWdtHandler: Disabling WDT failed with code " << retval << ": " + << strerror(retval) << std::endl; + return returnvalue::FAILED; + } + } + return returnvalue::OK; +} diff --git a/bsp_q7s/core/XiphosWdtHandler.h b/bsp_q7s/core/XiphosWdtHandler.h index 1f6f8c0d..28e48429 100644 --- a/bsp_q7s/core/XiphosWdtHandler.h +++ b/bsp_q7s/core/XiphosWdtHandler.h @@ -6,17 +6,27 @@ #include #include -class XiphosWdtHandler : public SystemObject, public ExecutableObjectIF { +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; + 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. int timeoutSeconds = 60; struct watchdog_s* wdtHandle = nullptr; + MessageQueueIF* requestQueue = nullptr; + ActionHelper actionHelper; }; #endif /* BSP_Q7S_CORE_XIPHOSWDTHANDLER_H_ */ diff --git a/tmtc b/tmtc index 783bdd29..d82cecbe 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 783bdd297a931a96c8b077ec2c2456a203b23ffc +Subproject commit d82cecbe6e51e76a5b3b974b1c0d32ea22693853