Merge branch 'refactor-fix-ptme' into cfdp-source-handler
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit

This commit is contained in:
2023-10-13 09:45:21 +02:00
34 changed files with 392 additions and 113 deletions

View File

@ -1 +1,2 @@
target_sources(${OBSW_NAME} PRIVATE CoreController.cpp WatchdogHandler.cpp)
target_sources(${OBSW_NAME} PRIVATE CoreController.cpp WatchdogHandler.cpp
XiphosWdtHandler.cpp)

View File

@ -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(); }

View File

@ -0,0 +1,36 @@
#ifndef BSP_Q7S_CORE_XIPHOSWDTHANDLER_H_
#define BSP_Q7S_CORE_XIPHOSWDTHANDLER_H_
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <libxiphos.h>
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_ */

View File

@ -1,4 +1,5 @@
#include <bsp_q7s/callbacks/q7sGpioCallbacks.h>
#include <bsp_q7s/core/XiphosWdtHandler.h>
#include <bsp_q7s/objectFactory.h>
#include <dummies/ComCookieDummy.h>
#include <dummies/PcduHandlerDummy.h>
@ -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, true);

View File

@ -1,4 +1,5 @@
#include <bsp_q7s/callbacks/q7sGpioCallbacks.h>
#include <bsp_q7s/core/XiphosWdtHandler.h>
#include <bsp_q7s/objectFactory.h>
#include <devices/gpioIds.h>
#include <fsfw/storagemanager/LocalPool.h>
@ -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, true);

View File

@ -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