Merge pull request 'Xiphos WDT' (#797) from add-xiphos-wdt-handling into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good

Reviewed-on: #797
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
This commit is contained in:
Robin Müller 2023-10-11 19:49:59 +02:00
commit 433373e6b7
20 changed files with 209 additions and 16 deletions

View File

@ -16,6 +16,12 @@ will consitute of a breaking change warranting a new major release:
# [unreleased] # [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 # [v7.0.0] 2023-10-11
- Bumped `eive-tmtc` to v5.7.1. - Bumped `eive-tmtc` to v5.7.1.

View File

@ -10,7 +10,7 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 7) set(OBSW_VERSION_MAJOR 7)
set(OBSW_VERSION_MINOR 0) set(OBSW_VERSION_MINOR 1)
set(OBSW_VERSION_REVISION 0) set(OBSW_VERSION_REVISION 0)
# set(CMAKE_VERBOSE TRUE) # set(CMAKE_VERBOSE TRUE)

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 313 translations. * @brief Auto-generated event translation file. Contains 313 translations.
* @details * @details
* Generated on: 2023-10-10 13:50:27 * Generated on: 2023-10-11 10:54:39
*/ */
#include "translateEvents.h" #include "translateEvents.h"

View File

@ -1,8 +1,8 @@
/** /**
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 173 translations. * Contains 174 translations.
* Generated on: 2023-10-10 13:50:27 * Generated on: 2023-10-11 10:54:39
*/ */
#include "translateObjects.h" #include "translateObjects.h"
@ -11,6 +11,7 @@ const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER"; const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER"; const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER";
const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG"; 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 *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER"; const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER";
const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_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; return POWER_CONTROLLER_STRING;
case 0x43000006: case 0x43000006:
return GLOBAL_JSON_CFG_STRING; return GLOBAL_JSON_CFG_STRING;
case 0x43000007:
return XIPHOS_WDT_STRING;
case 0x43400001: case 0x43400001:
return THERMAL_CONTROLLER_STRING; return THERMAL_CONTROLLER_STRING;
case 0x44000001: case 0x44000001:

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/callbacks/q7sGpioCallbacks.h>
#include <bsp_q7s/core/XiphosWdtHandler.h>
#include <bsp_q7s/objectFactory.h> #include <bsp_q7s/objectFactory.h>
#include <dummies/ComCookieDummy.h> #include <dummies/ComCookieDummy.h>
#include <dummies/PcduHandlerDummy.h> #include <dummies/PcduHandlerDummy.h>
@ -37,6 +38,7 @@ void ObjectFactory::produce(void* args) {
PersistentTmStores stores; PersistentTmStores stores;
readFirmwareVersion(); readFirmwareVersion();
new XiphosWdtHandler(objects::XIPHOS_WDT);
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
*SdCardManager::instance(), &ipcStore, &tmStore, stores, 200, *SdCardManager::instance(), &ipcStore, &tmStore, stores, 200,
enableHkSets); enableHkSets);

View File

@ -1,4 +1,5 @@
#include <bsp_q7s/callbacks/q7sGpioCallbacks.h> #include <bsp_q7s/callbacks/q7sGpioCallbacks.h>
#include <bsp_q7s/core/XiphosWdtHandler.h>
#include <bsp_q7s/objectFactory.h> #include <bsp_q7s/objectFactory.h>
#include <devices/gpioIds.h> #include <devices/gpioIds.h>
#include <fsfw/storagemanager/LocalPool.h> #include <fsfw/storagemanager/LocalPool.h>
@ -34,6 +35,7 @@ void ObjectFactory::produce(void* args) {
PersistentTmStores stores; PersistentTmStores stores;
readFirmwareVersion(); readFirmwareVersion();
new XiphosWdtHandler(objects::XIPHOS_WDT);
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
*SdCardManager::instance(), &ipcStore, &tmStore, stores, 200, *SdCardManager::instance(), &ipcStore, &tmStore, stores, 200,
true); true);

View File

@ -82,6 +82,16 @@ void scheduling::initTasks() {
} }
#endif #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( PeriodicTaskIF* coreCtrlTask = factory->createPeriodicTask(
"CORE_CTRL", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc, &RR_SCHEDULING); "CORE_CTRL", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc, &RR_SCHEDULING);
result = coreCtrlTask->addComponent(objects::CORE_CONTROLLER); result = coreCtrlTask->addComponent(objects::CORE_CONTROLLER);
@ -414,6 +424,7 @@ void scheduling::initTasks() {
}; };
sif::info << "Starting tasks.." << std::endl; sif::info << "Starting tasks.." << std::endl;
xiphosWdtTask->startTask();
tmTcDistributor->startTask(); tmTcDistributor->startTask();
#if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TCPIP_SERVERS == 1

View File

@ -28,6 +28,7 @@ enum commonObjects : uint32_t {
CORE_CONTROLLER = 0x43000003, CORE_CONTROLLER = 0x43000003,
POWER_CONTROLLER = 0x43000004, POWER_CONTROLLER = 0x43000004,
GLOBAL_JSON_CFG = 0x43000006, GLOBAL_JSON_CFG = 0x43000006,
XIPHOS_WDT = 0x43000007,
/* 0x44 ('D') for device handlers */ /* 0x44 ('D') for device handlers */
MGM_0_LIS3_HANDLER = 0x44120006, MGM_0_LIS3_HANDLER = 0x44120006,

View File

@ -3,6 +3,7 @@
0x43000003;CORE_CONTROLLER 0x43000003;CORE_CONTROLLER
0x43000004;POWER_CONTROLLER 0x43000004;POWER_CONTROLLER
0x43000006;GLOBAL_JSON_CFG 0x43000006;GLOBAL_JSON_CFG
0x43000007;XIPHOS_WDT
0x43400001;THERMAL_CONTROLLER 0x43400001;THERMAL_CONTROLLER
0x44000001;DUMMY_HANDLER 0x44000001;DUMMY_HANDLER
0x44120006;MGM_0_LIS3_HANDLER 0x44120006;MGM_0_LIS3_HANDLER

1 0x42694269 TEST_TASK
3 0x43000003 CORE_CONTROLLER
4 0x43000004 POWER_CONTROLLER
5 0x43000006 GLOBAL_JSON_CFG
6 0x43000007 XIPHOS_WDT
7 0x43400001 THERMAL_CONTROLLER
8 0x44000001 DUMMY_HANDLER
9 0x44120006 MGM_0_LIS3_HANDLER

View File

@ -3,6 +3,7 @@
0x43000003;CORE_CONTROLLER 0x43000003;CORE_CONTROLLER
0x43000004;POWER_CONTROLLER 0x43000004;POWER_CONTROLLER
0x43000006;GLOBAL_JSON_CFG 0x43000006;GLOBAL_JSON_CFG
0x43000007;XIPHOS_WDT
0x43400001;THERMAL_CONTROLLER 0x43400001;THERMAL_CONTROLLER
0x44120006;MGM_0_LIS3_HANDLER 0x44120006;MGM_0_LIS3_HANDLER
0x44120010;GYRO_0_ADIS_HANDLER 0x44120010;GYRO_0_ADIS_HANDLER

1 0x00005060 P60DOCK_TEST_TASK
3 0x43000003 CORE_CONTROLLER
4 0x43000004 POWER_CONTROLLER
5 0x43000006 GLOBAL_JSON_CFG
6 0x43000007 XIPHOS_WDT
7 0x43400001 THERMAL_CONTROLLER
8 0x44120006 MGM_0_LIS3_HANDLER
9 0x44120010 GYRO_0_ADIS_HANDLER

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 313 translations. * @brief Auto-generated event translation file. Contains 313 translations.
* @details * @details
* Generated on: 2023-10-10 13:50:27 * Generated on: 2023-10-11 10:54:39
*/ */
#include "translateEvents.h" #include "translateEvents.h"

View File

@ -1,8 +1,8 @@
/** /**
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 177 translations. * Contains 178 translations.
* Generated on: 2023-10-10 13:50:27 * Generated on: 2023-10-11 10:54:39
*/ */
#include "translateObjects.h" #include "translateObjects.h"
@ -11,6 +11,7 @@ const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER"; const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER"; const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER";
const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG"; 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 *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER"; const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER";
const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_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; return POWER_CONTROLLER_STRING;
case 0x43000006: case 0x43000006:
return GLOBAL_JSON_CFG_STRING; return GLOBAL_JSON_CFG_STRING;
case 0x43000007:
return XIPHOS_WDT_STRING;
case 0x43400001: case 0x43400001:
return THERMAL_CONTROLLER_STRING; return THERMAL_CONTROLLER_STRING;
case 0x44120006: case 0x44120006:

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 313 translations. * @brief Auto-generated event translation file. Contains 313 translations.
* @details * @details
* Generated on: 2023-10-10 13:50:27 * Generated on: 2023-10-11 10:54:39
*/ */
#include "translateEvents.h" #include "translateEvents.h"

View File

@ -1,8 +1,8 @@
/** /**
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 177 translations. * Contains 178 translations.
* Generated on: 2023-10-10 13:50:27 * Generated on: 2023-10-11 10:54:39
*/ */
#include "translateObjects.h" #include "translateObjects.h"
@ -11,6 +11,7 @@ const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER"; const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER"; const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER";
const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG"; 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 *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER"; const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER";
const char *GYRO_0_ADIS_HANDLER_STRING = "GYRO_0_ADIS_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; return POWER_CONTROLLER_STRING;
case 0x43000006: case 0x43000006:
return GLOBAL_JSON_CFG_STRING; return GLOBAL_JSON_CFG_STRING;
case 0x43000007:
return XIPHOS_WDT_STRING;
case 0x43400001: case 0x43400001:
return THERMAL_CONTROLLER_STRING; return THERMAL_CONTROLLER_STRING;
case 0x44120006: case 0x44120006:

View File

@ -1,6 +1,6 @@
if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "") if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "")
target_sources(${LIB_EIVE_MISSION} PRIVATE ThermalController.cpp target_sources(
AcsController.cpp ${LIB_EIVE_MISSION} PRIVATE ThermalController.cpp AcsController.cpp
PowerController.cpp) PowerController.cpp)
endif() endif()

View File

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

2
tmtc

@ -1 +1 @@
Subproject commit 39e6a0488922590900b862e5e70524be1d6ec5ba Subproject commit e249f147bc1738003d31290df8f2b525d91c3482