eive-obsw/bsp_q7s/core/CoreController.h

402 lines
15 KiB
C
Raw Normal View History

2021-05-26 14:16:16 +02:00
#ifndef BSP_Q7S_CORE_CORECONTROLLER_H_
#define BSP_Q7S_CORE_CORECONTROLLER_H_
2023-07-03 16:55:45 +02:00
#include <bsp_q7s/core/defs.h>
2023-03-12 20:51:33 +01:00
#include <fsfw/container/DynamicFIFO.h>
#include <fsfw/container/SimpleRingBuffer.h>
2021-07-29 18:09:54 +02:00
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
2023-04-12 18:06:04 +02:00
#include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
2023-06-21 19:01:44 +02:00
#include <fsfw_hal/linux/uio/UioMapper.h>
#include <libxiphos.h>
2024-03-18 17:21:08 +01:00
#include <linux/acs/GPSDefinitions.h>
2023-03-26 16:42:00 +02:00
#include <mission/utility/trace.h>
2023-03-21 17:37:39 +01:00
#include <atomic>
#include <cstddef>
2021-05-26 14:16:16 +02:00
2022-10-14 15:33:34 +02:00
#include "OBSWConfig.h"
2022-09-16 11:53:33 +02:00
#include "bsp_q7s/fs/SdCardManager.h"
2021-07-19 12:44:43 +02:00
#include "events/subsystemIdRanges.h"
2022-01-17 15:58:27 +01:00
#include "fsfw/controller/ExtendedControllerBase.h"
2023-04-13 23:24:32 +02:00
#include "mission/sysDefs.h"
class Timer;
class SdCardManager;
2023-06-24 17:29:23 +02:00
struct RebootWatchdogFile {
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
2022-03-01 14:51:12 +01:00
bool enabled = true;
size_t maxCount = DEFAULT_MAX_BOOT_CNT;
2022-02-28 16:47:36 +01:00
uint32_t img00Cnt = 0;
uint32_t img01Cnt = 0;
uint32_t img10Cnt = 0;
uint32_t img11Cnt = 0;
2022-03-01 13:34:12 +01:00
bool img00Lock = false;
bool img01Lock = false;
bool img10Lock = false;
bool img11Lock = false;
2022-02-28 19:52:43 +01:00
uint32_t* relevantBootCnt = &img00Cnt;
bool bootFlag = false;
xsc::Chip lastChip = xsc::Chip::CHIP_0;
xsc::Copy lastCopy = xsc::Copy::COPY_0;
2022-03-01 13:34:12 +01:00
xsc::Chip mechanismNextChip = xsc::Chip::NO_CHIP;
xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY;
};
2023-06-24 17:29:23 +02:00
class RebootWatchdogPacket : public SerialLinkedListAdapter<SerializeIF> {
2023-06-22 14:25:11 +02:00
public:
2023-06-24 17:29:23 +02:00
RebootWatchdogPacket(RebootWatchdogFile& rf) {
2023-06-22 14:25:11 +02:00
enabled = rf.enabled;
maxCount = rf.maxCount;
img00Count = rf.img00Cnt;
img01Count = rf.img01Cnt;
img10Count = rf.img10Cnt;
img11Count = rf.img11Cnt;
img00Lock = rf.img00Lock;
img01Lock = rf.img01Lock;
img10Lock = rf.img10Lock;
img11Lock = rf.img11Lock;
lastChip = static_cast<uint8_t>(rf.lastChip);
lastCopy = static_cast<uint8_t>(rf.lastCopy);
nextChip = static_cast<uint8_t>(rf.mechanismNextChip);
nextCopy = static_cast<uint8_t>(rf.mechanismNextCopy);
setLinks();
}
private:
void setLinks() {
setStart(&enabled);
enabled.setNext(&maxCount);
maxCount.setNext(&img00Count);
img00Count.setNext(&img01Count);
img01Count.setNext(&img10Count);
img10Count.setNext(&img11Count);
img11Count.setNext(&img00Lock);
img00Lock.setNext(&img01Lock);
img01Lock.setNext(&img10Lock);
img10Lock.setNext(&img11Lock);
img11Lock.setNext(&lastChip);
lastChip.setNext(&lastCopy);
lastCopy.setNext(&nextChip);
nextChip.setNext(&nextCopy);
setLast(&nextCopy);
}
SerializeElement<uint8_t> enabled = false;
SerializeElement<uint32_t> maxCount = 0;
SerializeElement<uint32_t> img00Count = 0;
SerializeElement<uint32_t> img01Count = 0;
SerializeElement<uint32_t> img10Count = 0;
SerializeElement<uint32_t> img11Count = 0;
SerializeElement<uint8_t> img00Lock = false;
SerializeElement<uint8_t> img01Lock = false;
SerializeElement<uint8_t> img10Lock = false;
SerializeElement<uint8_t> img11Lock = false;
SerializeElement<uint8_t> lastChip = 0;
SerializeElement<uint8_t> lastCopy = 0;
SerializeElement<uint8_t> nextChip = 0;
SerializeElement<uint8_t> nextCopy = 0;
};
2023-06-24 17:29:23 +02:00
struct RebootCountersFile {
// 16 bit values so all boot counters fit into one event.
uint16_t img00Cnt = 0;
uint16_t img01Cnt = 0;
uint16_t img10Cnt = 0;
uint16_t img11Cnt = 0;
};
class RebootCountersPacket : public SerialLinkedListAdapter<SerializeIF> {
RebootCountersPacket(RebootCountersFile& rf) {
img00Count = rf.img00Cnt;
img01Count = rf.img01Cnt;
img10Count = rf.img10Cnt;
img11Count = rf.img11Cnt;
setLinks();
}
private:
void setLinks() {
setStart(&img00Count);
img00Count.setNext(&img01Count);
img01Count.setNext(&img10Count);
img10Count.setNext(&img11Count);
setLast(&img11Count);
}
SerializeElement<uint16_t> img00Count = 0;
SerializeElement<uint16_t> img01Count = 0;
SerializeElement<uint16_t> img10Count = 0;
SerializeElement<uint16_t> img11Count = 0;
};
2023-04-12 18:11:41 +02:00
class CoreController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
2022-01-17 15:58:27 +01:00
public:
2023-04-12 18:11:41 +02:00
enum ParamId : uint8_t { PREF_SD = 0, NUM_IDS };
2023-04-12 18:06:04 +02:00
static xsc::Chip CURRENT_CHIP;
static xsc::Copy CURRENT_COPY;
2022-01-17 15:58:27 +01:00
2022-04-17 00:56:31 +02:00
static constexpr char CHIP_PROT_SCRIPT[] = "get-chip-prot-status.sh";
2022-01-17 15:58:27 +01:00
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
2022-09-26 11:15:37 +02:00
2022-02-28 16:47:36 +01:00
const std::string VERSION_FILE =
2023-04-13 23:24:32 +02:00
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::VERSION_FILE_NAME);
const std::string LEGACY_REBOOT_WATCHDOG_FILE =
"/" + std::string(core::CONF_FOLDER) + "/" +
std::string(core::LEGACY_REBOOT_WATCHDOG_FILE_NAME);
2023-06-24 17:14:56 +02:00
const std::string REBOOT_WATCHDOG_FILE =
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_WATCHDOG_FILE_NAME);
2024-03-05 09:06:48 +01:00
const std::string LEAP_SECONDS_FILE =
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::LEAP_SECONDS_FILE_NAME);
2023-02-24 18:45:04 +01:00
const std::string BACKUP_TIME_FILE =
2023-04-13 23:24:32 +02:00
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::TIME_FILE_NAME);
2023-06-24 17:14:56 +02:00
const std::string REBOOT_COUNTERS_FILE =
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_COUNTER_FILE_NAME);
2022-01-17 15:58:27 +01:00
2022-09-26 11:31:29 +02:00
static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs";
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
static constexpr char CHIP_1_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-nom-rootfs";
static constexpr char CHIP_1_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-gold-rootfs";
2023-04-15 13:01:41 +02:00
static constexpr char LIST_DIR_DUMP_WORK_FILE[] = "/tmp/dir_listing.tmp";
2022-09-26 11:12:41 +02:00
static constexpr dur_millis_t INIT_SD_CARD_CHECK_TIMEOUT = 5000;
static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000;
2023-04-06 17:49:34 +02:00
CoreController(object_id_t objectId, bool enableHkSet);
2022-01-17 15:58:27 +01:00
virtual ~CoreController();
ReturnValue_t initialize() override;
ReturnValue_t initializeAfterTaskCreation() override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
void performControlOperation() override;
/**
* Generate a file containing the chip lock/unlock states inside /tmp/chip_prot_status.txt
* @return
*/
static ReturnValue_t generateChipStateFile();
static ReturnValue_t incrementAllocationFailureCount();
static void getCurrentBootCopy(xsc::Chip& chip, xsc::Copy& copy);
2022-09-26 12:00:57 +02:00
static const char* getXscMountDir(xsc::Chip chip, xsc::Copy copy);
2022-01-17 15:58:27 +01:00
ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true);
/**
* Checks whether the target chip and copy are write protected and protect set them to a target
* state where applicable.
* @param targetChip
* @param targetCopy
* @param protect Target state
* @param protOperationPerformed [out] Can be used to determine whether any operation
* was performed
* @param updateProtFile Specify whether the protection info file is updated
* @return
*/
ReturnValue_t setBootCopyProtectionAndUpdateFile(xsc::Chip targetChip, xsc::Copy targetCopy,
bool protect);
2022-01-17 15:58:27 +01:00
bool sdInitFinished() const;
private:
2023-02-24 18:45:04 +01:00
static constexpr uint32_t BOOT_OFFSET_SECONDS = 15;
2022-03-13 16:32:40 +01:00
static constexpr MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING;
static constexpr uint32_t MUTEX_TIMEOUT = 20;
2023-03-26 15:28:00 +02:00
bool enableHkSet = false;
GpsHyperion::FixMode gpsFix = GpsHyperion::FixMode::NOT_SEEN;
2022-01-17 15:58:27 +01:00
// States for SD state machine, which is used in non-blocking mode
enum class SdStates {
NONE,
START,
UPDATE_SD_INFO_START,
SKIP_TWO_CYCLES_IF_SD_LOCKED,
2022-01-17 15:58:27 +01:00
MOUNT_SELF,
// Determine operations for other SD card, depending on redundancy configuration
DETERMINE_OTHER,
SET_STATE_OTHER,
// Mount or unmount other
MOUNT_UNMOUNT_OTHER,
// Skip period because the shell command used to generate the info file sometimes is
// missing the last performed operation if executed too early
SKIP_CYCLE_BEFORE_INFO_UPDATE,
UPDATE_SD_INFO_END,
2022-01-17 15:58:27 +01:00
// SD initialization done
2022-09-27 10:51:07 +02:00
IDLE
2022-01-17 15:58:27 +01:00
};
2022-09-26 12:26:08 +02:00
enum class SwUpdateSources { SD_0, SD_1, TMP_DIR };
2022-01-17 15:58:27 +01:00
static constexpr bool BLOCKING_SD_INIT = false;
2023-06-21 19:01:44 +02:00
uint32_t* mappedSysRomAddr = nullptr;
2022-01-17 15:58:27 +01:00
SdCardManager* sdcMan = nullptr;
2022-04-07 17:23:50 +02:00
MessageQueueIF* eventQueue = nullptr;
2022-01-17 15:58:27 +01:00
2023-04-12 18:06:04 +02:00
uint8_t prefSdRaw = sd::SdCard::SLOT_0;
2022-09-27 10:51:07 +02:00
SdStates sdFsmState = SdStates::START;
SdStates fsmStateAfterDelay = SdStates::IDLE;
2022-09-27 10:51:07 +02:00
enum SdCfgMode { PASSIVE, COLD_REDUNDANT, HOT_REDUNDANT };
struct SdFsmParams {
SdCfgMode cfgMode = SdCfgMode::COLD_REDUNDANT;
sd::SdCard active = sd::SdCard::NONE;
2022-01-17 15:58:27 +01:00
sd::SdCard other = sd::SdCard::NONE;
2022-09-27 10:51:07 +02:00
std::string activeChar = "0";
2022-01-17 15:58:27 +01:00
std::string otherChar = "1";
sd::SdState activeState = sd::SdState::OFF;
sd::SdState otherState = sd::SdState::OFF;
2022-05-24 00:20:23 +02:00
std::pair<bool, bool> mountSwitch = {true, true};
// This flag denotes that the SD card usage is locked. This is relevant if SD cards go off
// to leave appliation using the SD cards some time to detect the SD card is not usable anymore.
// This is relevant if the active SD card is being switched. The SD card will also be locked
// when going from hot-redundant mode to cold-redundant mode.
bool lockSdCardUsage = false;
bool commandPending = true;
2022-01-17 15:58:27 +01:00
bool initFinished = false;
SdCardManager::SdStatePair currentState;
uint16_t cycleCount = 0;
uint16_t skippedCyclesCount = 0;
2022-02-28 14:13:31 +01:00
} sdInfo;
2022-09-27 10:51:07 +02:00
struct SdCommanding {
bool cmdPending = false;
MessageQueueId_t commander = MessageQueueIF::NO_QUEUE;
DeviceCommandId_t actionId;
} sdCommandingInfo;
2023-06-07 14:20:58 +02:00
struct DirListingDumpContext {
bool active;
2023-06-07 16:21:51 +02:00
bool firstDump;
2023-06-07 14:20:58 +02:00
size_t dumpedBytes;
size_t totalFileSize;
size_t listingDataOffset;
size_t maxDumpLen;
uint32_t segmentIdx;
MessageQueueId_t commander = MessageQueueIF::NO_QUEUE;
DeviceCommandId_t actionId;
};
std::array<uint8_t, 1024> dirListingBuf{};
DirListingDumpContext dumpContext{};
2023-06-24 17:29:23 +02:00
RebootWatchdogFile rebootWatchdogFile = {};
RebootCountersFile rebootCountersFile = {};
2023-03-12 20:51:33 +01:00
CommandExecutor cmdExecutor;
SimpleRingBuffer cmdReplyBuf;
DynamicFIFO<uint16_t> cmdRepliesSizes;
bool shellCmdIsExecuting = false;
MessageQueueId_t successRecipient = MessageQueueIF::NO_QUEUE;
std::string currMntPrefix;
2023-02-24 18:45:04 +01:00
bool timeFileInitDone = false;
2024-03-06 11:09:23 +01:00
bool leapSecondsInitDone = false;
2022-10-11 22:58:31 +02:00
bool performOneShotSdCardOpsSwitch = false;
uint8_t shortSdCardCdCounter = 0;
2023-02-14 10:59:35 +01:00
#if OBSW_THREAD_TRACING == 1
uint32_t opCounter;
#endif
Countdown sdCardCheckCd = Countdown(INIT_SD_CARD_CHECK_TIMEOUT);
2022-01-17 15:58:27 +01:00
/**
2023-07-26 11:07:04 +02:00
* First index: Chip.
* Second index: Copy.
2022-01-17 15:58:27 +01:00
*/
bool protArray[2][2]{};
PeriodicOperationDivider opDivider5;
PeriodicOperationDivider opDivider10;
2022-01-17 15:58:27 +01:00
2022-11-09 13:07:20 +01:00
PoolEntry<float> tempPoolEntry = PoolEntry<float>(0.0);
PoolEntry<float> psVoltageEntry = PoolEntry<float>(0.0);
PoolEntry<float> plVoltageEntry = PoolEntry<float>(0.0);
2022-03-13 16:32:40 +01:00
core::HkSet hkSet;
2023-04-12 18:06:04 +02:00
ParameterHelper paramHelper;
2022-10-14 15:33:34 +02:00
#if OBSW_SD_CARD_MUST_BE_ON == 1
bool remountAttemptFlag = true;
#endif
2023-04-12 18:11:20 +02:00
MessageQueueId_t getCommandQueue() const override;
2023-04-12 18:06:04 +02:00
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
2023-04-12 18:11:41 +02:00
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
uint16_t startAtIndex) override;
2022-01-17 15:58:27 +01:00
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
2022-01-17 15:58:27 +01:00
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t* msToReachTheMode);
void performMountedSdCardOperations();
2022-01-17 15:58:27 +01:00
ReturnValue_t initVersionFile();
2022-04-07 17:23:50 +02:00
2024-03-05 09:06:48 +01:00
void initLeapSeconds();
ReturnValue_t initLeapSecondsFromFile();
2022-04-07 17:23:50 +02:00
ReturnValue_t initClockFromTimeFile();
2024-03-05 11:51:02 +01:00
ReturnValue_t actionUpdateLeapSeconds(const uint8_t* data);
2024-03-05 09:06:48 +01:00
ReturnValue_t writeLeapSecondsToFile(const uint16_t leapSeconds);
2022-05-24 00:20:23 +02:00
ReturnValue_t performSdCardCheck();
2023-02-24 18:45:04 +01:00
ReturnValue_t backupTimeFileHandler();
2022-11-09 13:07:20 +01:00
ReturnValue_t initBootCopyFile();
2022-01-17 15:58:27 +01:00
ReturnValue_t initSdCardBlocking();
2022-09-27 12:19:42 +02:00
bool startSdStateMachine(sd::SdCard targetActiveSd, SdCfgMode mode, MessageQueueId_t commander,
DeviceCommandId_t actionId);
2022-01-17 15:58:27 +01:00
void initPrint();
ReturnValue_t sdStateMachine();
void updateInternalSdInfo();
2022-01-17 15:58:27 +01:00
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
bool printOutput = true);
2022-09-26 12:26:08 +02:00
ReturnValue_t executeSwUpdate(SwUpdateSources sourceDir, const uint8_t* data, size_t size);
2022-01-17 15:58:27 +01:00
ReturnValue_t sdColdRedundantBlockingInit();
2022-01-17 15:58:27 +01:00
void currentStateSetter(sd::SdCard sdCard, sd::SdState newState);
void executeNextExternalSdCommand();
void checkExternalSdCommandStatus();
2023-06-24 17:29:23 +02:00
void performRebootWatchdogHandling(bool recreateFile);
2023-06-24 18:06:58 +02:00
void performRebootCountersHandling(bool recreateFile);
2022-01-17 15:58:27 +01:00
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size);
2023-04-15 13:01:41 +02:00
ReturnValue_t actionListDirectoryDumpDirectly(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size);
2023-06-24 19:22:25 +02:00
ReturnValue_t performGracefulShutdown(xsc::Chip targetChip, xsc::Copy targetCopy);
2023-04-15 13:01:41 +02:00
ReturnValue_t actionListDirectoryCommonCommandCreator(const uint8_t* data, size_t size,
std::ostringstream& oss);
2022-04-29 11:16:53 +02:00
ReturnValue_t actionXscReboot(const uint8_t* data, size_t size);
ReturnValue_t actionReboot(const uint8_t* data, size_t size);
ReturnValue_t gracefulShutdownTasks(xsc::Chip chip, xsc::Copy copy, bool& protOpPerformed);
2022-01-17 15:58:27 +01:00
ReturnValue_t handleProtInfoUpdateLine(std::string nextLine);
2023-07-25 16:25:00 +02:00
ReturnValue_t handleSwitchingSdCardsOffNonBlocking();
2023-07-26 11:05:36 +02:00
bool handleBootCopyProt(xsc::Chip targetChip, xsc::Copy targetCopy, bool protect);
2023-06-25 11:04:13 +02:00
void rebootWatchdogAlgorithm(RebootWatchdogFile& rf, bool& needsReboot, xsc::Chip& tgtChip,
xsc::Copy& tgtCopy);
2023-06-24 18:06:58 +02:00
void resetRebootWatchdogCounters(xsc::Chip tgtChip, xsc::Copy tgtCopy);
2022-03-01 14:44:50 +01:00
void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy);
2023-06-24 17:29:23 +02:00
bool parseRebootWatchdogFile(std::string path, RebootWatchdogFile& file);
2023-06-24 18:06:58 +02:00
bool parseRebootCountersFile(std::string path, RebootCountersFile& file);
2023-06-24 17:29:23 +02:00
void rewriteRebootWatchdogFile(RebootWatchdogFile file);
2023-06-24 18:06:58 +02:00
void rewriteRebootCountersFile(RebootCountersFile file);
2023-03-08 11:37:11 +01:00
void announceBootCounts();
2023-06-22 14:06:34 +02:00
void announceVersionInfo();
void announceCurrentImageInfo();
2023-07-21 11:15:35 +02:00
void announceSdInfo(SdCardManager::SdStatePair sdStates);
2022-03-13 16:32:40 +01:00
void readHkData();
2023-06-07 14:20:58 +02:00
void dirListingDumpHandler();
2022-04-07 17:23:50 +02:00
bool isNumber(const std::string& s);
};
2021-05-26 14:16:16 +02:00
#endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */