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
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:
commit
433373e6b7
@ -16,6 +16,12 @@ will consitute of a breaking change warranting a new major release:
|
||||
|
||||
# [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
|
||||
|
||||
- Bumped `eive-tmtc` to v5.7.1.
|
||||
|
@ -10,7 +10,7 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(OBSW_VERSION_MAJOR 7)
|
||||
set(OBSW_VERSION_MINOR 0)
|
||||
set(OBSW_VERSION_MINOR 1)
|
||||
set(OBSW_VERSION_REVISION 0)
|
||||
|
||||
# set(CMAKE_VERBOSE TRUE)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 313 translations.
|
||||
* @details
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
* Generated on: 2023-10-11 10:54:39
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 173 translations.
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
* Contains 174 translations.
|
||||
* Generated on: 2023-10-11 10:54:39
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -11,6 +11,7 @@ const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
|
||||
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
|
||||
const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER";
|
||||
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 *DUMMY_HANDLER_STRING = "DUMMY_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;
|
||||
case 0x43000006:
|
||||
return GLOBAL_JSON_CFG_STRING;
|
||||
case 0x43000007:
|
||||
return XIPHOS_WDT_STRING;
|
||||
case 0x43400001:
|
||||
return THERMAL_CONTROLLER_STRING;
|
||||
case 0x44000001:
|
||||
|
@ -1 +1,2 @@
|
||||
target_sources(${OBSW_NAME} PRIVATE CoreController.cpp WatchdogHandler.cpp)
|
||||
target_sources(${OBSW_NAME} PRIVATE CoreController.cpp WatchdogHandler.cpp
|
||||
XiphosWdtHandler.cpp)
|
||||
|
122
bsp_q7s/core/XiphosWdtHandler.cpp
Normal file
122
bsp_q7s/core/XiphosWdtHandler.cpp
Normal 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(); }
|
36
bsp_q7s/core/XiphosWdtHandler.h
Normal file
36
bsp_q7s/core/XiphosWdtHandler.h
Normal 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_ */
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -28,6 +28,7 @@ enum commonObjects : uint32_t {
|
||||
CORE_CONTROLLER = 0x43000003,
|
||||
POWER_CONTROLLER = 0x43000004,
|
||||
GLOBAL_JSON_CFG = 0x43000006,
|
||||
XIPHOS_WDT = 0x43000007,
|
||||
|
||||
/* 0x44 ('D') for device handlers */
|
||||
MGM_0_LIS3_HANDLER = 0x44120006,
|
||||
|
@ -3,6 +3,7 @@
|
||||
0x43000003;CORE_CONTROLLER
|
||||
0x43000004;POWER_CONTROLLER
|
||||
0x43000006;GLOBAL_JSON_CFG
|
||||
0x43000007;XIPHOS_WDT
|
||||
0x43400001;THERMAL_CONTROLLER
|
||||
0x44000001;DUMMY_HANDLER
|
||||
0x44120006;MGM_0_LIS3_HANDLER
|
||||
|
|
@ -3,6 +3,7 @@
|
||||
0x43000003;CORE_CONTROLLER
|
||||
0x43000004;POWER_CONTROLLER
|
||||
0x43000006;GLOBAL_JSON_CFG
|
||||
0x43000007;XIPHOS_WDT
|
||||
0x43400001;THERMAL_CONTROLLER
|
||||
0x44120006;MGM_0_LIS3_HANDLER
|
||||
0x44120010;GYRO_0_ADIS_HANDLER
|
||||
|
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 313 translations.
|
||||
* @details
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
* Generated on: 2023-10-11 10:54:39
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 177 translations.
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
* Contains 178 translations.
|
||||
* Generated on: 2023-10-11 10:54:39
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -11,6 +11,7 @@ const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
|
||||
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
|
||||
const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER";
|
||||
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 *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_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;
|
||||
case 0x43000006:
|
||||
return GLOBAL_JSON_CFG_STRING;
|
||||
case 0x43000007:
|
||||
return XIPHOS_WDT_STRING;
|
||||
case 0x43400001:
|
||||
return THERMAL_CONTROLLER_STRING;
|
||||
case 0x44120006:
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 313 translations.
|
||||
* @details
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
* Generated on: 2023-10-11 10:54:39
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 177 translations.
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
* Contains 178 translations.
|
||||
* Generated on: 2023-10-11 10:54:39
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -11,6 +11,7 @@ const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
|
||||
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
|
||||
const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER";
|
||||
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 *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_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;
|
||||
case 0x43000006:
|
||||
return GLOBAL_JSON_CFG_STRING;
|
||||
case 0x43000007:
|
||||
return XIPHOS_WDT_STRING;
|
||||
case 0x43400001:
|
||||
return THERMAL_CONTROLLER_STRING;
|
||||
case 0x44120006:
|
||||
|
@ -1,6 +1,6 @@
|
||||
if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "")
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE ThermalController.cpp
|
||||
AcsController.cpp
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION} PRIVATE ThermalController.cpp AcsController.cpp
|
||||
PowerController.cpp)
|
||||
endif()
|
||||
|
||||
|
@ -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
2
tmtc
@ -1 +1 @@
|
||||
Subproject commit 39e6a0488922590900b862e5e70524be1d6ec5ba
|
||||
Subproject commit e249f147bc1738003d31290df8f2b525d91c3482
|
Loading…
Reference in New Issue
Block a user