2021-05-26 14:16:16 +02:00
|
|
|
#ifndef BSP_Q7S_CORE_CORECONTROLLER_H_
|
|
|
|
#define BSP_Q7S_CORE_CORECONTROLLER_H_
|
|
|
|
|
2021-07-29 18:09:54 +02:00
|
|
|
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
2022-02-25 11:34:42 +01:00
|
|
|
#include <libxiphos.h>
|
|
|
|
|
|
|
|
#include <cstddef>
|
2021-05-26 14:16:16 +02:00
|
|
|
|
2022-03-14 17:52:31 +01:00
|
|
|
#include "CoreDefinitions.h"
|
2022-01-17 15:58:27 +01:00
|
|
|
#include "bsp_q7s/memory/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"
|
2022-04-08 11:22:16 +02:00
|
|
|
#include "mission/devices/devicedefinitions/GPSDefinitions.h"
|
2021-07-28 16:37:08 +02:00
|
|
|
|
2021-08-05 18:13:32 +02:00
|
|
|
class Timer;
|
|
|
|
class SdCardManager;
|
2021-07-28 16:37:08 +02:00
|
|
|
|
2022-02-25 11:34:42 +01:00
|
|
|
namespace xsc {
|
|
|
|
|
2022-02-28 19:52:43 +01:00
|
|
|
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
|
|
|
|
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
|
2022-02-25 11:34:42 +01:00
|
|
|
|
|
|
|
} // namespace xsc
|
|
|
|
|
|
|
|
struct RebootFile {
|
|
|
|
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
|
|
|
|
2022-03-01 14:51:12 +01:00
|
|
|
bool enabled = true;
|
2022-02-25 11:34:42 +01:00
|
|
|
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;
|
2022-02-25 11:34:42 +01:00
|
|
|
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;
|
2022-02-25 11:34:42 +01:00
|
|
|
};
|
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
class CoreController : public ExtendedControllerBase {
|
|
|
|
public:
|
2022-02-25 11:34:42 +01: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-02-28 16:35:16 +01:00
|
|
|
static constexpr char CONF_FOLDER[] = "conf";
|
|
|
|
static constexpr char VERSION_FILE_NAME[] = "version.txt";
|
|
|
|
static constexpr char REBOOT_FILE_NAME[] = "reboot.txt";
|
2022-04-07 17:23:50 +02:00
|
|
|
static constexpr char TIME_FILE_NAME[] = "time.txt";
|
2022-02-28 16:47:36 +01:00
|
|
|
const std::string VERSION_FILE =
|
|
|
|
"/" + std::string(CONF_FOLDER) + "/" + std::string(VERSION_FILE_NAME);
|
|
|
|
const std::string REBOOT_FILE =
|
|
|
|
"/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME);
|
2022-04-08 11:22:16 +02:00
|
|
|
const std::string TIME_FILE = "/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME);
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
2022-02-25 11:34:42 +01:00
|
|
|
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
|
2022-03-01 14:44:50 +01:00
|
|
|
static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6;
|
|
|
|
static constexpr ActionId_t SWITCH_IMG_LOCK = 7;
|
|
|
|
static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8;
|
2022-02-25 11:34:42 +01:00
|
|
|
|
2022-04-29 11:16:53 +02:00
|
|
|
//! Reboot using the xsc_boot_copy command
|
|
|
|
static constexpr ActionId_t XSC_REBOOT_OBC = 32;
|
2022-01-17 15:58:27 +01:00
|
|
|
static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
|
2022-04-29 11:16:53 +02:00
|
|
|
//! Reboot using the reboot command
|
|
|
|
static constexpr ActionId_t REBOOT_OBC = 34;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
|
|
|
|
|
|
|
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
2022-04-24 12:34:08 +02:00
|
|
|
//! [EXPORT] : [COMMENT] Software reboot occurred. Can also be a systemd reboot.
|
2022-02-25 11:34:42 +01:00
|
|
|
//! P1: Current Chip, P2: Current Copy
|
|
|
|
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::MEDIUM);
|
|
|
|
//! [EXPORT] : [COMMENT] The reboot mechanism was triggered.
|
|
|
|
//! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy,
|
|
|
|
//! P2: Each byte is the respective reboot count for the slots
|
|
|
|
static constexpr Event REBOOT_MECHANISM_TRIGGERED =
|
|
|
|
event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM);
|
|
|
|
//! Trying to find a way how to determine that the reboot came from ProASIC3 or PCDU..
|
|
|
|
static constexpr Event REBOOT_HW = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM);
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
CoreController(object_id_t objectId);
|
|
|
|
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();
|
2022-02-25 11:34:42 +01:00
|
|
|
static void getCurrentBootCopy(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
|
|
|
|
*/
|
2022-02-25 11:34:42 +01:00
|
|
|
ReturnValue_t setBootCopyProtection(xsc::Chip targetChip, xsc::Copy targetCopy, bool protect,
|
2022-01-17 15:58:27 +01:00
|
|
|
bool& protOperationPerformed, bool updateProtFile = true);
|
|
|
|
|
|
|
|
bool sdInitFinished() const;
|
|
|
|
|
|
|
|
private:
|
2022-03-13 16:32:40 +01:00
|
|
|
static constexpr MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING;
|
|
|
|
static constexpr uint32_t MUTEX_TIMEOUT = 20;
|
2022-01-17 15:58:27 +01:00
|
|
|
// Designated value for rechecking FIFO open
|
|
|
|
static constexpr int RETRY_FIFO_OPEN = -2;
|
|
|
|
int watchdogFifoFd = 0;
|
2022-04-07 17:23:50 +02:00
|
|
|
GpsHyperion::FixMode gpsFix = GpsHyperion::FixMode::UNKNOWN;
|
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,
|
|
|
|
GET_INFO,
|
|
|
|
SET_STATE_SELF,
|
|
|
|
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_INFO,
|
|
|
|
// SD initialization done
|
|
|
|
IDLE,
|
|
|
|
// Used if SD switches or mount commands are issued via telecommand
|
|
|
|
SET_STATE_FROM_COMMAND,
|
|
|
|
};
|
|
|
|
static constexpr bool BLOCKING_SD_INIT = false;
|
|
|
|
|
|
|
|
SdCardManager* sdcMan = nullptr;
|
2022-04-07 17:23:50 +02:00
|
|
|
MessageQueueIF* eventQueue = nullptr;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
struct SdInfo {
|
|
|
|
sd::SdCard pref = sd::SdCard::NONE;
|
|
|
|
sd::SdCard other = sd::SdCard::NONE;
|
2022-05-24 00:20:23 +02:00
|
|
|
sd::SdState prefState = sd::SdState::OFF;
|
2022-01-17 15:58:27 +01:00
|
|
|
sd::SdState otherState = sd::SdState::OFF;
|
|
|
|
std::string prefChar = "0";
|
|
|
|
std::string otherChar = "1";
|
2022-05-24 00:20:23 +02:00
|
|
|
std::pair<bool, bool> mountSwitch = {true, true};
|
2022-01-17 15:58:27 +01:00
|
|
|
SdStates state = SdStates::START;
|
|
|
|
// Used to track whether a command was executed
|
|
|
|
bool commandExecuted = true;
|
|
|
|
bool initFinished = false;
|
|
|
|
SdCardManager::SdStatePair currentState;
|
|
|
|
uint16_t cycleCount = 0;
|
|
|
|
// These two flags are related to external commanding
|
|
|
|
bool commandIssued = false;
|
|
|
|
bool commandFinished = false;
|
|
|
|
sd::SdState currentlyCommandedState = sd::SdState::OFF;
|
|
|
|
sd::SdCard commandedCard = sd::SdCard::NONE;
|
|
|
|
sd::SdState commandedState = sd::SdState::OFF;
|
2022-02-28 14:13:31 +01:00
|
|
|
} sdInfo;
|
2022-02-25 11:34:42 +01:00
|
|
|
RebootFile rebootFile = {};
|
2022-04-08 11:22:16 +02:00
|
|
|
std::string currMntPrefix;
|
2022-05-11 17:02:57 +02:00
|
|
|
bool performOneShotSdCardOpsSwitch = true;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Index 0: Chip 0 Copy 0
|
|
|
|
* Index 1: Chip 0 Copy 1
|
|
|
|
* Index 2: Chip 1 Copy 0
|
|
|
|
* Index 3: Chip 1 Copy 1
|
|
|
|
*/
|
|
|
|
std::array<bool, 4> protArray;
|
2022-04-12 15:27:48 +02:00
|
|
|
PeriodicOperationDivider opDivider5;
|
|
|
|
PeriodicOperationDivider opDivider10;
|
2022-01-17 15:58:27 +01:00
|
|
|
|
2022-03-13 16:32:40 +01:00
|
|
|
core::HkSet hkSet;
|
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
|
|
|
LocalDataPoolManager& poolManager) override;
|
2022-05-24 00:53:29 +02:00
|
|
|
Countdown sdCardCheckCd = Countdown(120000);
|
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);
|
2022-02-28 16:35:16 +01:00
|
|
|
void performMountedSdCardOperations();
|
2022-01-17 15:58:27 +01:00
|
|
|
ReturnValue_t initVersionFile();
|
2022-04-07 17:23:50 +02:00
|
|
|
|
|
|
|
ReturnValue_t initClockFromTimeFile();
|
2022-05-24 00:20:23 +02:00
|
|
|
ReturnValue_t performSdCardCheck();
|
2022-04-07 17:23:50 +02:00
|
|
|
ReturnValue_t timeFileHandler();
|
2022-01-17 15:58:27 +01:00
|
|
|
ReturnValue_t initBootCopy();
|
|
|
|
ReturnValue_t initWatchdogFifo();
|
|
|
|
ReturnValue_t initSdCardBlocking();
|
|
|
|
void initPrint();
|
|
|
|
|
|
|
|
ReturnValue_t sdStateMachine();
|
|
|
|
void updateSdInfoOther();
|
|
|
|
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
|
|
|
|
bool printOutput = true);
|
|
|
|
ReturnValue_t sdColdRedundantBlockingInit();
|
2022-02-28 16:35:16 +01:00
|
|
|
|
2022-01-17 15:58:27 +01:00
|
|
|
void currentStateSetter(sd::SdCard sdCard, sd::SdState newState);
|
|
|
|
void executeNextExternalSdCommand();
|
|
|
|
void checkExternalSdCommandStatus();
|
2022-02-25 11:34:42 +01:00
|
|
|
void performRebootFileHandling(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);
|
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
|
|
|
|
|
|
|
void performWatchdogControlOperation();
|
|
|
|
|
|
|
|
ReturnValue_t handleProtInfoUpdateLine(std::string nextLine);
|
2022-02-25 11:34:42 +01:00
|
|
|
int handleBootCopyProtAtIndex(xsc::Chip targetChip, xsc::Copy targetCopy, bool protect,
|
2022-01-17 15:58:27 +01:00
|
|
|
bool& protOperationPerformed, bool selfChip, bool selfCopy,
|
|
|
|
bool allChips, bool allCopies, uint8_t arrIdx);
|
2022-02-25 11:34:42 +01:00
|
|
|
void determineAndExecuteReboot(RebootFile& rf, bool& needsReboot, xsc::Chip& tgtChip,
|
|
|
|
xsc::Copy& tgtCopy);
|
|
|
|
void resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy);
|
2022-03-01 14:44:50 +01:00
|
|
|
void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy);
|
2022-02-25 11:34:42 +01:00
|
|
|
bool parseRebootFile(std::string path, RebootFile& file);
|
|
|
|
void rewriteRebootFile(RebootFile file);
|
2022-03-13 16:32:40 +01:00
|
|
|
void readHkData();
|
2022-04-07 17:23:50 +02:00
|
|
|
bool isNumber(const std::string& s);
|
2021-08-19 13:34:44 +02:00
|
|
|
};
|
2021-05-26 14:16:16 +02:00
|
|
|
|
|
|
|
#endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */
|