Added OBSW Watchdog #67
@ -23,7 +23,8 @@ CoreController::Chip CoreController::currentChip = Chip::NO_CHIP;
|
|||||||
CoreController::Copy CoreController::currentCopy = Copy::NO_COPY;
|
CoreController::Copy CoreController::currentCopy = Copy::NO_COPY;
|
||||||
|
|
||||||
CoreController::CoreController(object_id_t objectId):
|
CoreController::CoreController(object_id_t objectId):
|
||||||
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) {
|
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5),
|
||||||
|
opDivider(5) {
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
try {
|
try {
|
||||||
result = initWatchdogFifo();
|
result = initWatchdogFifo();
|
||||||
@ -52,15 +53,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CoreController::performControlOperation() {
|
void CoreController::performControlOperation() {
|
||||||
if(watchdogFifoFd != 0) {
|
performWatchdogControlOperation();
|
||||||
// Write to OBSW watchdog FIFO here
|
|
||||||
const char writeChar = 'a';
|
|
||||||
ssize_t writtenBytes = write(watchdogFifoFd, &writeChar, 1);
|
|
||||||
if(writtenBytes < 0) {
|
|
||||||
sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " <<
|
|
||||||
strerror(errno) << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
@ -432,12 +425,18 @@ ReturnValue_t CoreController::initWatchdogFifo() {
|
|||||||
" watchdog" << std::endl;
|
" watchdog" << std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
// Open FIFO write only and non-blocking
|
// Open FIFO write only and non-blocking to prevent SW from killing itself.
|
||||||
watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY);
|
watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY | O_NONBLOCK);
|
||||||
if(watchdogFifoFd < 0) {
|
if(watchdogFifoFd < 0) {
|
||||||
std::cerr << "Opening pipe " << watchdog::FIFO_NAME << "write-only failed with " <<
|
if(errno == ENXIO) {
|
||||||
errno << ": " << strerror(errno) << std::endl;
|
watchdogFifoFd = RETRY_FIFO_OPEN;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
sif::info << "eive-watchdog not running. FIFO can not be opened" << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sif::error << "Opening pipe " << watchdog::FIFO_NAME << " write-only failed with " <<
|
||||||
|
errno << ": " << strerror(errno) << std::endl;
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -457,3 +456,37 @@ void CoreController::initPrint() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CoreController::performWatchdogControlOperation() {
|
||||||
|
// Only perform each fifth iteration
|
||||||
|
if(watchdogFifoFd != 0 and opDivider.checkAndIncrement()) {
|
||||||
|
if(watchdogFifoFd == RETRY_FIFO_OPEN) {
|
||||||
|
// Open FIFO write only and non-blocking
|
||||||
|
watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY | O_NONBLOCK);
|
||||||
|
if(watchdogFifoFd < 0) {
|
||||||
|
if(errno == ENXIO) {
|
||||||
|
watchdogFifoFd = RETRY_FIFO_OPEN;
|
||||||
|
// No printout for now, would be spam
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sif::error << "Opening pipe " << watchdog::FIFO_NAME <<
|
||||||
|
" write-only failed with " << errno << ": " <<
|
||||||
|
strerror(errno) << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sif::info << "Opened " << watchdog::FIFO_NAME << " successfully" << std::endl;
|
||||||
|
}
|
||||||
|
else if(watchdogFifoFd > 0) {
|
||||||
|
// Write to OBSW watchdog FIFO here
|
||||||
|
const char writeChar = 'a';
|
||||||
|
ssize_t writtenBytes = write(watchdogFifoFd, &writeChar, 1);
|
||||||
|
if(writtenBytes < 0) {
|
||||||
|
sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " <<
|
||||||
|
strerror(errno) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef BSP_Q7S_CORE_CORECONTROLLER_H_
|
#ifndef BSP_Q7S_CORE_CORECONTROLLER_H_
|
||||||
#define BSP_Q7S_CORE_CORECONTROLLER_H_
|
#define BSP_Q7S_CORE_CORECONTROLLER_H_
|
||||||
|
|
||||||
|
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||||
#include "fsfw/controller/ExtendedControllerBase.h"
|
#include "fsfw/controller/ExtendedControllerBase.h"
|
||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
|
|
||||||
@ -70,7 +71,12 @@ private:
|
|||||||
|
|
||||||
void initPrint();
|
void initPrint();
|
||||||
|
|
||||||
|
// Designated value for rechecking FIFO open
|
||||||
|
static constexpr int RETRY_FIFO_OPEN = -2;
|
||||||
int watchdogFifoFd = 0;
|
int watchdogFifoFd = 0;
|
||||||
|
|
||||||
|
PeriodicOperationDivider opDivider;
|
||||||
|
void performWatchdogControlOperation();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,7 +64,11 @@ int WatchdogTask::performOperation() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(LoopResult::TIMEOUT): {
|
case(LoopResult::TIMEOUT): {
|
||||||
performTimeoutOperation();
|
performNotRunningOperation(loopResult);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(LoopResult::HUNG_UP): {
|
||||||
|
performNotRunningOperation(loopResult);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(LoopResult::RESTART_RQ): {
|
case(LoopResult::RESTART_RQ): {
|
||||||
@ -159,6 +163,7 @@ WatchdogTask::LoopResult WatchdogTask::pollEvent(struct pollfd& waiter) {
|
|||||||
}
|
}
|
||||||
else if (waiter.revents & POLLHUP) {
|
else if (waiter.revents & POLLHUP) {
|
||||||
// Writer closed its end
|
// Writer closed its end
|
||||||
|
return LoopResult::HUNG_UP;
|
||||||
}
|
}
|
||||||
return LoopResult::FAULT;
|
return LoopResult::FAULT;
|
||||||
}
|
}
|
||||||
@ -189,9 +194,9 @@ int WatchdogTask::performRunningOperation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(not obswRunning) {
|
if(not obswRunning) {
|
||||||
if(printTimeoutLatch) {
|
if(printNotRunningLatch) {
|
||||||
// Reset latch so user can see timeouts
|
// Reset latch so user can see timeouts
|
||||||
printTimeoutLatch = false;
|
printNotRunningLatch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
obswRunning = true;
|
obswRunning = true;
|
||||||
@ -210,25 +215,35 @@ int WatchdogTask::performRunningOperation() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WatchdogTask::performTimeoutOperation() {
|
int WatchdogTask::performNotRunningOperation(LoopResult type) {
|
||||||
// Latch prevents spam on console
|
// Latch prevents spam on console
|
||||||
if(not printTimeoutLatch) {
|
if(not printNotRunningLatch) {
|
||||||
std::cout << "eive-watchdog: The FIFO timed out!" << std::endl;
|
if(type == LoopResult::HUNG_UP) {
|
||||||
printTimeoutLatch = true;
|
std::cout << "eive-watchdog: FIFO writer hung up!" << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "eive-watchdog: The FIFO timed out!" << std::endl;
|
||||||
|
}
|
||||||
|
printNotRunningLatch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WATCHDOG_CREATE_FILE_IF_RUNNING == 1
|
|
||||||
if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) {
|
|
||||||
int result = std::remove(watchdog::RUNNING_FILE_NAME.c_str());
|
|
||||||
if(result != 0) {
|
|
||||||
std::cerr << "Removing " << watchdog::RUNNING_FILE_NAME << " failed with code " <<
|
|
||||||
errno << ": " << strerror(errno) << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(obswRunning) {
|
if(obswRunning) {
|
||||||
|
#if WATCHDOG_CREATE_FILE_IF_RUNNING == 1
|
||||||
|
if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) {
|
||||||
|
int result = std::remove(watchdog::RUNNING_FILE_NAME.c_str());
|
||||||
|
if(result != 0) {
|
||||||
|
std::cerr << "Removing " << watchdog::RUNNING_FILE_NAME << " failed with code " <<
|
||||||
|
errno << ": " << strerror(errno) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
obswRunning = false;
|
obswRunning = false;
|
||||||
}
|
}
|
||||||
|
if(type == LoopResult::HUNG_UP) {
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
// Prevent spam
|
||||||
|
std::this_thread::sleep_for(2000ms);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ public:
|
|||||||
CANCEL_RQ,
|
CANCEL_RQ,
|
||||||
RESTART_RQ,
|
RESTART_RQ,
|
||||||
TIMEOUT,
|
TIMEOUT,
|
||||||
|
HUNG_UP,
|
||||||
FAULT
|
FAULT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ private:
|
|||||||
|
|
||||||
bool obswRunning = false;
|
bool obswRunning = false;
|
||||||
bool watchdogRunning = false;
|
bool watchdogRunning = false;
|
||||||
bool printTimeoutLatch = false;
|
bool printNotRunningLatch = false;
|
||||||
std::array<uint8_t, 64> buf;
|
std::array<uint8_t, 64> buf;
|
||||||
States state = States::NOT_STARTED;
|
States state = States::NOT_STARTED;
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ private:
|
|||||||
LoopResult parseCommandByte(ssize_t readLen);
|
LoopResult parseCommandByte(ssize_t readLen);
|
||||||
|
|
||||||
int performRunningOperation();
|
int performRunningOperation();
|
||||||
int performTimeoutOperation();
|
int performNotRunningOperation(LoopResult type);
|
||||||
int performSuspendOperation();
|
int performSuspendOperation();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user