diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 02e0adea..4a9db02a 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -23,7 +23,8 @@ CoreController::Chip CoreController::currentChip = Chip::NO_CHIP; CoreController::Copy CoreController::currentCopy = Copy::NO_COPY; 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; try { result = initWatchdogFifo(); @@ -52,15 +53,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) { } void CoreController::performControlOperation() { - 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; - } - } + performWatchdogControlOperation(); } ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, @@ -432,12 +425,18 @@ ReturnValue_t CoreController::initWatchdogFifo() { " watchdog" << std::endl; return HasReturnvaluesIF::RETURN_OK; } - // Open FIFO write only and non-blocking - watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY); + // Open FIFO write only and non-blocking to prevent SW from killing itself. + watchdogFifoFd = open(watchdog::FIFO_NAME.c_str(), O_WRONLY | O_NONBLOCK); if(watchdogFifoFd < 0) { - std::cerr << "Opening pipe " << watchdog::FIFO_NAME << "write-only failed with " << - errno << ": " << strerror(errno) << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + if(errno == ENXIO) { + watchdogFifoFd = RETRY_FIFO_OPEN; + 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; } @@ -457,3 +456,37 @@ void CoreController::initPrint() { } #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; + } + } + } + +} diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index ea212a16..92b22dd4 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -1,6 +1,7 @@ #ifndef BSP_Q7S_CORE_CORECONTROLLER_H_ #define BSP_Q7S_CORE_CORECONTROLLER_H_ +#include #include "fsfw/controller/ExtendedControllerBase.h" #include "bsp_q7s/memory/SdCardManager.h" @@ -70,7 +71,12 @@ private: void initPrint(); + // Designated value for rechecking FIFO open + static constexpr int RETRY_FIFO_OPEN = -2; int watchdogFifoFd = 0; + + PeriodicOperationDivider opDivider; + void performWatchdogControlOperation(); }; diff --git a/watchdog/Watchdog.cpp b/watchdog/Watchdog.cpp index 9e316451..f3627a75 100644 --- a/watchdog/Watchdog.cpp +++ b/watchdog/Watchdog.cpp @@ -64,7 +64,11 @@ int WatchdogTask::performOperation() { break; } case(LoopResult::TIMEOUT): { - performTimeoutOperation(); + performNotRunningOperation(loopResult); + break; + } + case(LoopResult::HUNG_UP): { + performNotRunningOperation(loopResult); break; } case(LoopResult::RESTART_RQ): { @@ -159,6 +163,7 @@ WatchdogTask::LoopResult WatchdogTask::pollEvent(struct pollfd& waiter) { } else if (waiter.revents & POLLHUP) { // Writer closed its end + return LoopResult::HUNG_UP; } return LoopResult::FAULT; } @@ -189,9 +194,9 @@ int WatchdogTask::performRunningOperation() { } if(not obswRunning) { - if(printTimeoutLatch) { + if(printNotRunningLatch) { // Reset latch so user can see timeouts - printTimeoutLatch = false; + printNotRunningLatch = false; } obswRunning = true; @@ -210,25 +215,35 @@ int WatchdogTask::performRunningOperation() { return 0; } -int WatchdogTask::performTimeoutOperation() { +int WatchdogTask::performNotRunningOperation(LoopResult type) { // Latch prevents spam on console - if(not printTimeoutLatch) { - std::cout << "eive-watchdog: The FIFO timed out!" << std::endl; - printTimeoutLatch = true; + if(not printNotRunningLatch) { + if(type == LoopResult::HUNG_UP) { + 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 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; } + if(type == LoopResult::HUNG_UP) { + using namespace std::chrono_literals; + // Prevent spam + std::this_thread::sleep_for(2000ms); + } return 0; } diff --git a/watchdog/Watchdog.h b/watchdog/Watchdog.h index 649fca6e..fb7ac65b 100644 --- a/watchdog/Watchdog.h +++ b/watchdog/Watchdog.h @@ -19,6 +19,7 @@ public: CANCEL_RQ, RESTART_RQ, TIMEOUT, + HUNG_UP, FAULT }; @@ -32,7 +33,7 @@ private: bool obswRunning = false; bool watchdogRunning = false; - bool printTimeoutLatch = false; + bool printNotRunningLatch = false; std::array buf; States state = States::NOT_STARTED; @@ -41,7 +42,7 @@ private: LoopResult parseCommandByte(ssize_t readLen); int performRunningOperation(); - int performTimeoutOperation(); + int performNotRunningOperation(LoopResult type); int performSuspendOperation(); };