eive-obsw/bsp_q7s/obsw.cpp

183 lines
6.0 KiB
C++
Raw Normal View History

2021-06-30 15:18:41 +02:00
#include "obsw.h"
2021-07-24 13:47:09 +02:00
2023-10-19 14:43:29 +02:00
#include <libxiphos.h>
2023-01-18 13:43:28 +01:00
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
2021-07-29 16:31:04 +02:00
#include <filesystem>
2023-01-13 11:44:16 +01:00
#include <fstream>
2023-01-13 11:59:11 +01:00
#include <iostream>
2022-01-17 15:58:27 +01:00
#include "OBSWConfig.h"
2023-02-23 23:56:11 +01:00
#include "bsp_q7s/core/WatchdogHandler.h"
2022-04-22 14:09:08 +02:00
#include "commonConfig.h"
2022-01-17 15:58:27 +01:00
#include "fsfw/tasks/TaskFactory.h"
2022-03-14 17:53:48 +01:00
#include "fsfw/version.h"
2023-10-19 14:43:29 +02:00
#include "memory/scratchApi.h"
2023-03-24 20:50:33 +01:00
#include "mission/acs/defs.h"
2023-03-24 19:37:03 +01:00
#include "mission/com/defs.h"
2023-04-06 16:50:33 +02:00
#include "mission/system/systemTree.h"
2022-05-23 18:37:04 +02:00
#include "q7sConfig.h"
2023-07-03 16:55:45 +02:00
#include "scheduling.h"
2022-04-19 17:24:04 +02:00
#include "watchdog/definitions.h"
2021-07-29 16:31:04 +02:00
2023-03-06 00:55:12 +01:00
static constexpr int OBSW_ALREADY_RUNNING = -2;
2022-05-19 16:00:26 +02:00
#if OBSW_Q7S_EM == 0
static const char* DEV_STRING = "Xiphos Q7S FM";
#else
static const char* DEV_STRING = "Xiphos Q7S EM";
#endif
2023-02-23 23:56:11 +01:00
WatchdogHandler WATCHDOG_HANDLER;
2023-03-06 00:55:12 +01:00
int obsw::obsw(int argc, char* argv[]) {
2022-03-14 17:53:48 +01:00
using namespace fsfw;
2022-01-17 15:58:27 +01:00
std::cout << "-- EIVE OBSW --" << std::endl;
2022-05-19 16:00:26 +02:00
std::cout << "-- Compiled for Linux (" << DEV_STRING << ") --" << std::endl;
2022-04-22 15:58:15 +02:00
std::cout << "-- OBSW v" << common::OBSW_VERSION << " | FSFW v" << fsfw::FSFW_VERSION << " --"
2022-04-22 14:09:08 +02:00
<< std::endl;
2022-01-17 15:58:27 +01:00
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
2021-06-30 15:18:41 +02:00
2021-07-29 13:07:07 +02:00
#if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1
2023-03-08 14:50:25 +01:00
std::error_code e;
2022-01-17 15:58:27 +01:00
// Check special file here. This file is created or deleted by the eive-watchdog application
// or systemd service!
2023-03-08 14:50:25 +01:00
if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME, e)) {
2022-01-17 15:58:27 +01:00
sif::warning << "File " << watchdog::RUNNING_FILE_NAME
<< " exists so the software might "
"already be running. Check if obsw systemd service has been stopped."
2022-01-17 15:58:27 +01:00
<< std::endl;
return OBSW_ALREADY_RUNNING;
}
2021-07-29 13:07:07 +02:00
#endif
2023-01-13 11:43:44 +01:00
2023-10-19 13:31:43 +02:00
autoSwitchHandling();
2023-02-23 23:56:11 +01:00
// Delay the boot if applicable.
bootDelayHandling();
bool initWatchFunction = false;
2023-03-06 00:55:12 +01:00
std::string fullExecPath = argv[0];
if (fullExecPath.find("/usr/bin") != std::string::npos) {
2023-02-23 23:56:11 +01:00
initWatchFunction = true;
}
ReturnValue_t result = WATCHDOG_HANDLER.initialize(initWatchFunction);
if (result != returnvalue::OK) {
std::cerr << "Initiating EIVE watchdog handler failed" << std::endl;
}
scheduling::initMission();
// Command the EIVE system to safe mode
#if OBSW_COMMAND_SAFE_MODE_AT_STARTUP == 1
2023-03-14 13:32:13 +01:00
// This ensures that the PCDU switches were updated.
TaskFactory::delayTask(1000);
2023-03-14 15:26:39 +01:00
commandComSubsystemRxOnly();
2023-02-23 23:56:11 +01:00
commandEiveSystemToSafe();
#else
announceAllModes();
#endif
for (;;) {
WATCHDOG_HANDLER.periodicOperation();
2023-03-06 00:55:12 +01:00
TaskFactory::delayTask(2000);
2023-02-23 23:56:11 +01:00
}
return 0;
}
2023-10-19 13:31:43 +02:00
void obsw::autoSwitchHandling() {
std::string autoSwitchTarget;
2023-10-19 15:23:23 +02:00
auto switchToTarget = [&](xsc_libnor_chip_t chip, xsc_libnor_copy_t copy) {
sif::warning << "Detected ASWI=" << autoSwitchTarget
<< " in ProASIC scratch buffer, auto-switching to image " << int(chip) << " "
<< int(copy) << std::endl;
2023-10-19 15:24:52 +02:00
scratch::clearValue(scratch::AUTO_SWITCH_IMAGE);
2023-10-19 15:18:39 +02:00
// A bit of delay to ensure printout works..
TaskFactory::delayTask(500);
2023-10-19 14:43:29 +02:00
xsc_boot_copy(chip, copy);
2023-10-19 13:31:43 +02:00
};
2023-10-19 14:43:29 +02:00
if (scratch::readString(scratch::AUTO_SWITCH_IMAGE, autoSwitchTarget) == returnvalue::OK) {
2023-10-19 13:31:43 +02:00
if (autoSwitchTarget == "00") {
switchToTarget(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_NOMINAL);
} else if (autoSwitchTarget == "01") {
switchToTarget(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_GOLD);
} else if (autoSwitchTarget == "10") {
switchToTarget(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_NOMINAL);
2023-10-19 14:43:29 +02:00
} else if (autoSwitchTarget == "11") {
2023-10-19 13:31:43 +02:00
switchToTarget(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_GOLD);
} else {
2023-10-19 14:43:29 +02:00
sif::warning << "Invalid Auto Switch Image (ASWI) value detected: " << autoSwitchTarget
<< std::endl;
2023-10-19 13:31:43 +02:00
}
}
}
2023-02-23 23:56:11 +01:00
void obsw::bootDelayHandling() {
2023-01-13 13:14:11 +01:00
const char* homedir = nullptr;
homedir = getenv("HOME");
2023-01-18 13:43:28 +01:00
if (homedir == nullptr) {
homedir = getpwuid(getuid())->pw_dir;
2023-01-13 13:14:11 +01:00
}
std::filesystem::path bootDelayFile = std::filesystem::path(homedir) / "boot_delay_secs.txt";
2023-03-08 14:50:25 +01:00
std::error_code e;
2023-01-13 11:43:44 +01:00
// Init delay handling.
2023-03-08 14:50:25 +01:00
if (std::filesystem::exists(bootDelayFile, e)) {
2023-01-13 13:14:11 +01:00
std::ifstream ifile(bootDelayFile);
2023-01-13 11:59:11 +01:00
std::string lineStr;
unsigned int bootDelaySecs = 0;
unsigned int line = 0;
// Try to reas delay seconds from file.
while (std::getline(ifile, lineStr)) {
std::istringstream iss(lineStr);
if (!(iss >> bootDelaySecs)) {
break;
}
line++;
}
if (line == 0) {
// If the file is empty, assume default of 6 seconds
bootDelaySecs = 6;
}
std::cout << "Delaying OBSW start for " << bootDelaySecs << " seconds" << std::endl;
2023-01-13 13:14:11 +01:00
TaskFactory::delayTask(bootDelaySecs * 1000);
2023-01-13 11:43:44 +01:00
}
2023-02-23 23:56:11 +01:00
}
2023-01-13 11:43:44 +01:00
2023-02-23 23:56:11 +01:00
void obsw::commandEiveSystemToSafe() {
2023-02-12 20:41:20 +01:00
auto sysQueueId = satsystem::EIVE_SYSTEM.getCommandQueue();
CommandMessage msg;
ModeMessage::setCmdModeMessage(msg, acs::AcsMode::SAFE, 0);
ReturnValue_t result =
MessageQueueSenderIF::sendMessage(sysQueueId, &msg, MessageQueueIF::NO_QUEUE, false);
if (result != returnvalue::OK) {
2023-03-14 15:08:56 +01:00
sif::error << "obsw: Sending safe mode command to EIVE system failed" << std::endl;
}
}
void obsw::commandComSubsystemRxOnly() {
auto* comSs = ObjectManager::instance()->get<HasModesIF>(objects::COM_SUBSYSTEM);
if (comSs == nullptr) {
sif::error << "obsw: Could not retrieve COM subsystem object" << std::endl;
return;
}
CommandMessage msg;
ModeMessage::setCmdModeMessage(msg, com::RX_ONLY, 0);
ReturnValue_t result = MessageQueueSenderIF::sendMessage(comSs->getCommandQueue(), &msg,
MessageQueueIF::NO_QUEUE, false);
if (result != returnvalue::OK) {
sif::error << "obsw: Sending RX_ONLY mode command to COM subsystem failed" << std::endl;
2023-02-12 20:41:20 +01:00
}
2023-02-23 23:56:11 +01:00
}
void obsw::announceAllModes() {
auto sysQueueId = satsystem::EIVE_SYSTEM.getCommandQueue();
CommandMessage msg;
2023-02-16 19:51:30 +01:00
ModeMessage::setModeAnnounceMessage(msg, true);
ReturnValue_t result =
MessageQueueSenderIF::sendMessage(sysQueueId, &msg, MessageQueueIF::NO_QUEUE, false);
if (result != returnvalue::OK) {
2023-03-14 15:08:56 +01:00
sif::error << "obsw: Sending safe mode command to EIVE system failed" << std::endl;
2023-02-16 19:51:30 +01:00
}
2021-06-30 15:18:41 +02:00
}