2023-10-02 14:15:50 +02:00
|
|
|
#include "XiphosWdtHandler.h"
|
|
|
|
|
2023-10-10 19:15:52 +02:00
|
|
|
#include "fsfw/ipc/QueueFactory.h"
|
|
|
|
|
|
|
|
XiphosWdtHandler::XiphosWdtHandler(object_id_t objectId)
|
|
|
|
: SystemObject(objectId),
|
|
|
|
requestQueue(QueueFactory::instance()->createMessageQueue()),
|
|
|
|
actionHelper(this, requestQueue) {}
|
2023-10-02 14:15:50 +02:00
|
|
|
|
|
|
|
ReturnValue_t XiphosWdtHandler::initialize() {
|
2023-10-10 19:15:52 +02:00
|
|
|
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;
|
2023-10-02 14:15:50 +02:00
|
|
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
|
|
|
}
|
|
|
|
if (wdtHandle == nullptr) {
|
|
|
|
sif::error << "XiphosWdtHandler: WDT handle is nullptr!" << std::endl;
|
|
|
|
return ObjectManagerIF::CHILD_INIT_FAILED;
|
|
|
|
}
|
2023-10-10 19:15:52 +02:00
|
|
|
retval = xsc_watchdog_set_timeout(wdtHandle, timeoutSeconds);
|
|
|
|
if (retval != 0) {
|
2023-10-02 14:49:29 +02:00
|
|
|
// This propably means that the default timeout is used. Still continue with task init.
|
|
|
|
sif::warning << "XiphosWdtHandler: Setting WDT timeout of " << timeoutSeconds
|
2023-10-10 19:15:52 +02:00
|
|
|
<< " seconds failed with code " << result << ": " << strerror(retval) << std::endl;
|
2023-10-02 14:15:50 +02:00
|
|
|
}
|
2023-10-10 19:15:52 +02:00
|
|
|
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;
|
|
|
|
}
|
2023-10-11 15:00:15 +02:00
|
|
|
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;
|
|
|
|
}
|
2023-10-10 19:15:52 +02:00
|
|
|
}
|
|
|
|
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;
|
2023-10-02 14:47:41 +02:00
|
|
|
}
|
2023-10-10 19:15:52 +02:00
|
|
|
return EXECUTION_FINISHED;
|
2023-10-02 14:47:41 +02:00
|
|
|
}
|
2023-10-10 19:15:52 +02:00
|
|
|
}
|
|
|
|
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) {
|
2023-10-02 14:47:41 +02:00
|
|
|
sif::warning << "XiphosWdtHandler: Getting WDT status failed" << std::endl;
|
2023-10-02 14:15:50 +02:00
|
|
|
}
|
2023-10-10 19:15:52 +02:00
|
|
|
// 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) {
|
2023-10-11 13:56:05 +02:00
|
|
|
retval = xsc_watchdog_enable(wdtHandle);
|
2023-10-10 19:15:52 +02:00
|
|
|
if (retval != 0) {
|
|
|
|
sif::error << "XiphosWdtHandler: Enabling WDT failed with code " << retval << ": "
|
|
|
|
<< strerror(retval) << std::endl;
|
|
|
|
return returnvalue::FAILED;
|
|
|
|
}
|
|
|
|
}
|
2023-10-11 15:00:15 +02:00
|
|
|
enabled = true;
|
2023-10-02 14:15:50 +02:00
|
|
|
return returnvalue::OK;
|
|
|
|
}
|
|
|
|
|
2023-10-10 19:15:52 +02:00
|
|
|
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) {
|
2023-10-11 13:56:05 +02:00
|
|
|
retval = xsc_watchdog_disable(wdtHandle);
|
2023-10-10 19:15:52 +02:00
|
|
|
if (retval != 0) {
|
|
|
|
sif::error << "XiphosWdtHandler: Disabling WDT failed with code " << retval << ": "
|
|
|
|
<< strerror(retval) << std::endl;
|
|
|
|
return returnvalue::FAILED;
|
|
|
|
}
|
2023-10-02 14:15:50 +02:00
|
|
|
}
|
2023-10-11 15:00:15 +02:00
|
|
|
enabled = false;
|
2023-10-02 14:15:50 +02:00
|
|
|
return returnvalue::OK;
|
|
|
|
}
|
2023-10-11 13:56:05 +02:00
|
|
|
|
|
|
|
MessageQueueId_t XiphosWdtHandler::getCommandQueue() const { return requestQueue->getId(); }
|