Compare commits

...

34 Commits

Author SHA1 Message Date
Ulrich Mohr 45cf31c2b1 new fsfw
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
EIVE/-/pipeline/head Build queued... Details
2022-09-14 11:30:15 +02:00
Ulrich Mohr f6f6393c4a reverting mib only changes to cmake
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-09-07 12:02:18 +02:00
Ulrich Mohr 7754d65753 reverting changes to CMakeList.txt to move back topwards upstream 2022-09-07 11:09:17 +02:00
Uli c14b131e6f fixed fsfw
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-09-07 10:57:39 +02:00
Ulrich Mohr de856a514b workarounds for MIB build
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-09-06 22:17:54 +02:00
Ulrich Mohr acd365e421 Mode introspection and fixes
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-26 16:12:22 +02:00
Ulrich Mohr 06b6c0838a compiling both with and without introspection 2022-08-25 16:28:01 +02:00
Ulrich Mohr 3c762e7437 switching mission object ids to FSFW_CLASSLESS_ENUM 2022-08-25 15:13:15 +02:00
Ulrich Mohr 4a147a442c removing debug code 2022-08-25 14:44:18 +02:00
Ulrich Mohr fe8036361d I knew this was stupid: Revert "changing mission dependend object IDs to FSFW_ENUM"
This reverts commit 2800484f6b.
2022-08-25 14:43:27 +02:00
Ulrich Mohr 2800484f6b changing mission dependend object IDs to FSFW_ENUM
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-24 22:29:42 +02:00
Ulrich Mohr aaeb101442 mostly done with gomspacehandlers, some todos left
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-24 18:13:03 +02:00
Ulrich Mohr da2acd1fa8 continuing on gomspace handlers 2022-08-24 17:19:14 +02:00
Ulrich Mohr 1f47c970af working on gomespace handlers
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-23 23:34:20 +02:00
Ulrich Mohr dfb800f58a more dirty hacks to check amd64 build. To be cleaned up
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-19 14:31:48 +02:00
Ulrich Mohr a93fe8ef8e fixing bug in handlers 2022-08-19 14:31:22 +02:00
Ulrich Mohr 35effb9e68 stubs to be able to compile on modern amd64 2022-08-19 14:28:44 +02:00
Ulrich Mohr c0e896b371 working on compiling bsp_q7s on amd64
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-18 19:04:49 +02:00
Ulrich Mohr 73971ad486 fixes 2022-08-18 16:33:53 +02:00
Ulrich Mohr 45e5ea362d Merge branch 'develop' into mohr/introspection
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-18 13:15:58 +02:00
Ulrich Mohr 7bcc4b18b7 compiles 2022-08-18 10:42:18 +02:00
Ulrich Mohr a3b5993fdc compiles, does not link yet
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-17 19:19:49 +02:00
Ulrich Mohr eb886dc53c Ploc Memory Dumper 2022-08-17 19:19:20 +02:00
Ulrich Mohr a91393b4b4 Small fixes 2022-08-17 17:55:21 +02:00
Ulrich Mohr ef40db7fe4 CCSDS Handler 2022-08-17 17:54:59 +02:00
Ulrich Mohr 60a20acc5b Core controlle rincomplete, but compiles
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-17 11:21:35 +02:00
Ulrich Mohr 13cc31dca9 working on core controller
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-08-16 18:31:58 +02:00
Ulrich Mohr ad88bfa5b4 core controller bigWIP
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
2022-07-28 17:16:24 +02:00
Ulrich Mohr d92b1b170d Boilerplate Code to make ploc and star tracker compile 2022-07-27 23:09:05 +02:00
Ulrich Mohr 24297a6a97 WIP adapting PlocMpSoCHandler
EIVE/eive-obsw/pipeline/head There was a failure building this commit Details
major PITA, but does compile now, will be back with more patience
2022-07-27 22:03:41 +02:00
Ulrich Mohr c8f4f0b03e GPSHyperionController adapted 2022-07-27 22:02:37 +02:00
Ulrich Mohr eeaef13916 PdecHandler adapted 2022-07-26 21:23:41 +02:00
Ulrich Mohr a2910a401e adapted SolarArrayDeploymentHandler 2022-07-26 17:18:35 +02:00
Ulrich Mohr cd1200d23d introspection fsfw, HeaterHandler adapted 2022-07-26 17:18:04 +02:00
66 changed files with 2116 additions and 1576 deletions

View File

@ -15,6 +15,7 @@ set(OBSW_VERSION_REVISION_IF_GIT_FAILS 0)
# set(CMAKE_VERBOSE TRUE) # set(CMAKE_VERBOSE TRUE)
option( option(
EIVE_HARDCODED_TOOLCHAIN_FILE EIVE_HARDCODED_TOOLCHAIN_FILE
"\ "\
@ -160,7 +161,7 @@ if(NOT GIT_VER_HANDLING_OK)
endif() endif()
# Set names and variables # Set names and variables
set(OBSW_NAME ${CMAKE_PROJECT_NAME}) set(OBSW_NAME ${PROJECT_NAME})
set(WATCHDOG_NAME eive-watchdog) set(WATCHDOG_NAME eive-watchdog)
set(SIMPLE_OBSW_NAME eive-simple) set(SIMPLE_OBSW_NAME eive-simple)
set(UNITTEST_NAME eive-unittest) set(UNITTEST_NAME eive-unittest)
@ -182,7 +183,7 @@ set(FSFW_PATH fsfw)
set(TEST_PATH test) set(TEST_PATH test)
set(UNITTEST_PATH unittest) set(UNITTEST_PATH unittest)
set(LINUX_PATH linux) set(LINUX_PATH linux)
set(COMMON_PATH common) set(COMMON_PATH ${CMAKE_CURRENT_SOURCE_DIR}/common)
set(DUMMY_PATH dummies) set(DUMMY_PATH dummies)
set(WATCHDOG_PATH watchdog) set(WATCHDOG_PATH watchdog)
set(COMMON_CONFIG_PATH ${COMMON_PATH}/config) set(COMMON_CONFIG_PATH ${COMMON_PATH}/config)
@ -205,6 +206,7 @@ pre_source_hw_os_config()
if(TGT_BSP) if(TGT_BSP)
set(LIBGPS_VERSION_MAJOR 3) set(LIBGPS_VERSION_MAJOR 3)
# I assume a newer version than 3.17 will be installed on other Linux board # I assume a newer version than 3.17 will be installed on other Linux board
# than the Q7S # than the Q7S
set(LIBGPS_VERSION_MINOR 20) set(LIBGPS_VERSION_MINOR 20)
@ -214,7 +216,8 @@ if(TGT_BSP)
OR TGT_BSP MATCHES "arm/egse" OR TGT_BSP MATCHES "arm/egse"
OR TGT_BSP MATCHES "arm/te0720-1cfa") OR TGT_BSP MATCHES "arm/te0720-1cfa")
find_library(${LIB_GPS} gps) find_library(${LIB_GPS} gps)
set(FSFW_CONFIG_PATH "linux/fsfwconfig") set(FSFW_CONFIG_PATH ${CMAKE_CURRENT_SOURCE_DIR}/linux/fsfwconfig)
if(NOT BUILD_Q7S_SIMPLE_MODE) if(NOT BUILD_Q7S_SIMPLE_MODE)
set(EIVE_ADD_LINUX_FILES TRUE) set(EIVE_ADD_LINUX_FILES TRUE)
set(ADD_CSP_LIB TRUE) set(ADD_CSP_LIB TRUE)
@ -271,8 +274,9 @@ endif()
configure_file(${WATCHDOG_PATH}/watchdogConf.h.in watchdogConf.h) configure_file(${WATCHDOG_PATH}/watchdogConf.h.in watchdogConf.h)
# Set common config path for FSFW # Set common config path for FSFW
set(FSFW_ADDITIONAL_INC_PATHS "${COMMON_PATH}/config" set(FSFW_ADDITIONAL_INC_PATHS "${COMMON_PATH}"
${CMAKE_CURRENT_BINARY_DIR}) ${COMMON_CONFIG_PATH}
${CMAKE_CURRENT_BINARY_DIR})
# ############################################################################## # ##############################################################################
# Executable and Sources # Executable and Sources
@ -320,7 +324,7 @@ add_library(${LIB_DUMMIES})
# Add main executable # Add main executable
add_executable(${OBSW_NAME}) add_executable(${OBSW_NAME})
set(OBSW_BIN_NAME ${CMAKE_PROJECT_NAME}) set(OBSW_BIN_NAME ${PROJECT_NAME})
set_target_properties(${OBSW_NAME} PROPERTIES OUTPUT_NAME ${OBSW_BIN_NAME}) set_target_properties(${OBSW_NAME} PROPERTIES OUTPUT_NAME ${OBSW_BIN_NAME})
@ -356,7 +360,10 @@ if(EIVE_ADD_LINUX_FILES)
add_subdirectory(${LIB_ARCSEC_PATH}) add_subdirectory(${LIB_ARCSEC_PATH})
add_subdirectory(${LINUX_PATH}) add_subdirectory(${LINUX_PATH})
endif() endif()
add_subdirectory(${BSP_PATH}) add_subdirectory(${BSP_PATH})
if(ADD_CSP_LIB) if(ADD_CSP_LIB)
add_subdirectory(${LIB_CSP_PATH}) add_subdirectory(${LIB_CSP_PATH})
endif() endif()

View File

@ -9,7 +9,7 @@ add_subdirectory(simple)
target_sources(${OBSW_NAME} PUBLIC main.cpp obsw.cpp) target_sources(${OBSW_NAME} PUBLIC main.cpp obsw.cpp)
add_subdirectory(boardtest) #add_subdirectory(boardtest)
add_subdirectory(boardconfig) add_subdirectory(boardconfig)
add_subdirectory(comIF) add_subdirectory(comIF)

View File

@ -1,4 +1,4 @@
target_sources(${OBSW_NAME} PRIVATE FileSystemTest.cpp Q7STestTask.cpp) target_sources(${OBSW_NAME} PUBLIC FileSystemTest.cpp Q7STestTask.cpp)
if(EIVE_BUILD_Q7S_SIMPLE_MODE) if(EIVE_BUILD_Q7S_SIMPLE_MODE)
target_sources(${SIMPLE_OBSW_NAME} PRIVATE FileSystemTest.cpp) target_sources(${SIMPLE_OBSW_NAME} PRIVATE FileSystemTest.cpp)

View File

@ -4,11 +4,7 @@
#include "fsfw/action/HasActionsIF.h" #include "fsfw/action/HasActionsIF.h"
#include "fsfw/tasks/TaskFactory.h" #include "fsfw/tasks/TaskFactory.h"
ReturnValue_t gps::triggerGpioResetPin(const uint8_t* actionData, size_t len, void* args) { ReturnValue_t gps::triggerGpioResetPin(uint8_t gpsId, void* args) {
// At least one byte which denotes which GPS to reset is required
if (len < 1 or actionData == nullptr) {
return HasActionsIF::INVALID_PARAMETERS;
}
ResetArgs* resetArgs = reinterpret_cast<ResetArgs*>(args); ResetArgs* resetArgs = reinterpret_cast<ResetArgs*>(args);
if (args == nullptr) { if (args == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
@ -16,10 +12,8 @@ ReturnValue_t gps::triggerGpioResetPin(const uint8_t* actionData, size_t len, vo
if (resetArgs->gpioComIF == nullptr) { if (resetArgs->gpioComIF == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
gpioId_t gpioId; gpioId_t gpioId = gpioIds::GNSS_0_NRESET;
if (actionData[0] == 0) { if (gpsId == 1) {
gpioId = gpioIds::GNSS_0_NRESET;
} else {
gpioId = gpioIds::GNSS_1_NRESET; gpioId = gpioIds::GNSS_1_NRESET;
} }
resetArgs->gpioComIF->pullLow(gpioId); resetArgs->gpioComIF->pullLow(gpioId);

View File

@ -11,7 +11,7 @@ struct ResetArgs {
namespace gps { namespace gps {
ReturnValue_t triggerGpioResetPin(const uint8_t* actionData, size_t len, void* args); ReturnValue_t triggerGpioResetPin(uint8_t gpsId, void* args);
} }

View File

@ -0,0 +1,87 @@
#pragma once
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/introspection/Enum.h>
class CoreController;
namespace core {
FSFW_ENUM(ActionId, ActionId_t,
((LIST_DIRECTORY_INTO_FILE, 0, "List Directory into file"))(
(SWITCH_REBOOT_FILE_HANDLING, 5,
"Switch Reboot File Handling"))((RESET_REBOOT_COUNTERS, 6, "Reset Boot Counters"))(
(SWITCH_IMG_LOCK, 7, "Switch Image Lock"))((SET_MAX_REBOOT_CNT, 8,
"Set maximum reboot Count"))(
(XSC_REBOOT_OBC, 32, "Reboot using the xsc_boot_copy command"))(
(MOUNT_OTHER_COPY, 33, "Mount Other Copy"))((REBOOT_OBC, 34,
"Reboot using the reboot command")))
FSFW_ENUM(Boolenum, uint8_t, ((NO, 0, "NO"))((YES, 1, "Yes")))
class ListDirectoryIntoFileAction
: public TemplateAction<CoreController, ListDirectoryIntoFileAction, ActionId> {
public:
ListDirectoryIntoFileAction(CoreController *owner)
: TemplateAction(owner, ActionId::LIST_DIRECTORY_INTO_FILE){};
};
class SwitchRebootFileHandlingAction
: public TemplateAction<CoreController, SwitchRebootFileHandlingAction, ActionId> {
public:
SwitchRebootFileHandlingAction(CoreController *owner)
: TemplateAction(owner, ActionId::SWITCH_REBOOT_FILE_HANDLING){};
Parameter<Boolenum> enableRebootFile =
Parameter<Boolenum>::createParameter(this, "Enable Reboot File");
};
class ResetRebootCountersAction
: public TemplateAction<CoreController, ResetRebootCountersAction, ActionId> {
public:
FSFW_ENUM(Selection, uint8_t, ((ZERO, "0"))((ONE, "1"))((ALL, "All")))
ResetRebootCountersAction(CoreController *owner)
: TemplateAction(owner, ActionId::RESET_REBOOT_COUNTERS){};
Parameter<Selection> chip = Parameter<Selection>::createParameter(this, "Chip");
Parameter<Selection> copy = Parameter<Selection>::createParameter(this, "Copy");
};
class SwitchImageLockAction
: public TemplateAction<CoreController, SwitchImageLockAction, ActionId> {
public:
FSFW_ENUM(Selection, uint8_t, ((ZERO, "0"))((ONE, "1")))
SwitchImageLockAction(CoreController *owner) : TemplateAction(owner, ActionId::SWITCH_IMG_LOCK){};
Parameter<Boolenum> lock = Parameter<Boolenum>::createParameter(this, "Lock Image");
Parameter<Selection> chip = Parameter<Selection>::createParameter(this, "Chip");
Parameter<Selection> copy = Parameter<Selection>::createParameter(this, "Copy");
};
class SetMaxRebootCntAction
: public TemplateAction<CoreController, SetMaxRebootCntAction, ActionId> {
public:
SetMaxRebootCntAction(CoreController *owner)
: TemplateAction(owner, ActionId::SET_MAX_REBOOT_CNT){};
Parameter<uint8_t> maxCount = Parameter<uint8_t>::createParameter(this, "Count");
};
class XscRebootObcAction : public TemplateAction<CoreController, XscRebootObcAction, ActionId> {
public:
FSFW_ENUM(Selection, uint8_t, ((ZERO, "0"))((ONE, "1"))((SAME, "Same")))
XscRebootObcAction(CoreController *owner) : TemplateAction(owner, ActionId::XSC_REBOOT_OBC){};
Parameter<Selection> chip = Parameter<Selection>::createParameter(this, "Chip");
Parameter<Selection> copy = Parameter<Selection>::createParameter(this, "Copy");
};
class RebootObcAction : public TemplateAction<CoreController, RebootObcAction, ActionId> {
public:
RebootObcAction(CoreController *owner) : TemplateAction(owner, ActionId::REBOOT_OBC){};
};
} // namespace core

View File

@ -163,75 +163,73 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() {
return result; return result;
} }
ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t CoreController::executeAction(Action *action) { return action->handle(); }
const uint8_t *data, size_t size) {
switch (actionId) { ReturnValue_t CoreController::handleAction(core::SwitchRebootFileHandlingAction *action) {
case (LIST_DIRECTORY_INTO_FILE): { std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_FILE;
return actionListDirectoryIntoFile(actionId, commandedBy, data, size); // Disable the reboot file mechanism
} parseRebootFile(path, rebootFile);
case (SWITCH_REBOOT_FILE_HANDLING): { if (action->enableRebootFile.value == core::Boolenum::NO) {
if (size < 1) { rebootFile.enabled = false;
return HasActionsIF::INVALID_PARAMETERS; rewriteRebootFile(rebootFile);
} } else {
std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_FILE; rebootFile.enabled = true;
// Disable the reboot file mechanism rewriteRebootFile(rebootFile);
parseRebootFile(path, rebootFile);
if (data[0] == 0) {
rebootFile.enabled = false;
rewriteRebootFile(rebootFile);
} else if (data[0] == 1) {
rebootFile.enabled = true;
rewriteRebootFile(rebootFile);
} else {
return HasActionsIF::INVALID_PARAMETERS;
}
return HasActionsIF::EXECUTION_FINISHED;
}
case (RESET_REBOOT_COUNTERS): {
if (size == 0) {
resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY);
} else if (size == 2) {
if (data[0] > 1 or data[1] > 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
resetRebootCount(static_cast<xsc::Chip>(data[0]), static_cast<xsc::Copy>(data[1]));
}
return HasActionsIF::EXECUTION_FINISHED;
}
case (SWITCH_IMG_LOCK): {
if (size != 3) {
return HasActionsIF::INVALID_PARAMETERS;
}
if (data[1] > 1 or data[2] > 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
setRebootMechanismLock(data[0], static_cast<xsc::Chip>(data[1]),
static_cast<xsc::Copy>(data[2]));
return HasActionsIF::EXECUTION_FINISHED;
}
case (SET_MAX_REBOOT_CNT): {
if (size < 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
rebootFile.maxCount = data[0];
rewriteRebootFile(rebootFile);
return HasActionsIF::EXECUTION_FINISHED;
}
case (XSC_REBOOT_OBC): {
// Warning: This function will never return, because it reboots the system
return actionXscReboot(data, size);
}
case (REBOOT_OBC): {
// Warning: This function will never return, because it reboots the system
return actionReboot(data, size);
}
default: {
return HasActionsIF::INVALID_ACTION_ID;
}
} }
return HasActionsIF::EXECUTION_FINISHED;
}
ReturnValue_t CoreController::handleAction(core::ResetRebootCountersAction *action) {
xsc::Chip chip = xsc::NO_CHIP;
switch (action->chip.value) {
case core::ResetRebootCountersAction::Selection::ALL:
chip = xsc::ALL_CHIP;
break;
case core::ResetRebootCountersAction::Selection::ZERO:
chip = xsc::CHIP_0;
break;
case core::ResetRebootCountersAction::Selection::ONE:
chip = xsc::CHIP_1;
break;
}
xsc::Copy copy = xsc::NO_COPY;
switch (action->copy.value) {
case core::ResetRebootCountersAction::Selection::ALL:
copy = xsc::ALL_COPY;
break;
case core::ResetRebootCountersAction::Selection::ZERO:
copy = xsc::COPY_0;
break;
case core::ResetRebootCountersAction::Selection::ONE:
copy = xsc::COPY_1;
break;
}
resetRebootCount(chip, copy);
return HasActionsIF::EXECUTION_FINISHED;
}
ReturnValue_t CoreController::handleAction(core::SwitchImageLockAction *action) {
bool lock = action->lock.value == core::Boolenum::YES;
xsc::Chip chip = xsc::CHIP_0;
if (action->chip.value == core::SwitchImageLockAction::Selection::ONE) {
chip = xsc::CHIP_1;
}
xsc::Copy copy = xsc::COPY_0;
if (action->copy.value == core::SwitchImageLockAction::Selection::ONE) {
copy = xsc::COPY_0;
}
setRebootMechanismLock(lock, chip, copy);
return HasActionsIF::EXECUTION_FINISHED;
}
ReturnValue_t CoreController::handleAction(core::SetMaxRebootCntAction *action) {
std::string path = sdcMan->getCurrentMountPrefix() + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
rebootFile.maxCount = action->maxCount;
rewriteRebootFile(rebootFile);
return HasActionsIF::EXECUTION_FINISHED;
} }
ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode,
@ -748,30 +746,29 @@ ReturnValue_t CoreController::initVersionFile() {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId, ReturnValue_t CoreController::handleAction(core::ListDirectoryIntoFileAction *action) {
MessageQueueId_t commandedBy,
const uint8_t *data, size_t size) {
// TODO: Packet definition for clean deserialization // TODO: Packet definition for clean deserialization
// 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with // 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
// null termination, at least 7 bytes for minimum target file name /tmp/a with // null termination, at least 7 bytes for minimum target file name /tmp/a with
// null termination. // null termination.
if (size < 14) { // TODO make work again
return HasActionsIF::INVALID_PARAMETERS; // if (size < 14) {
} // return HasActionsIF::INVALID_PARAMETERS;
// }
// We could also make -l optional, but I can't think of a reason why to not use -l.. // We could also make -l optional, but I can't think of a reason why to not use -l..
// This flag specifies to run ls with -a // This flag specifies to run ls with -a
bool aFlag = data[0]; bool aFlag = 0; // data[0];
data += 1; // data += 1;
// This flag specifies to run ls with -R // This flag specifies to run ls with -R
bool RFlag = data[1]; bool RFlag = 0; // data[1];
data += 1; // data += 1;
size_t remainingSize = size - 2; size_t remainingSize = 0; // size - 2;
// One larger for null termination, which prevents undefined behaviour if the sent // One larger for null termination, which prevents undefined behaviour if the sent
// strings are not 0 terminated properly // strings are not 0 terminated properly
std::vector<uint8_t> repoAndTargetFileBuffer(remainingSize + 1, 0); std::vector<uint8_t> repoAndTargetFileBuffer(remainingSize + 1, 0);
std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize); // std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize);
const char *currentCharPtr = reinterpret_cast<const char *>(repoAndTargetFileBuffer.data()); const char *currentCharPtr = reinterpret_cast<const char *>(repoAndTargetFileBuffer.data());
// Full target file name // Full target file name
std::string repoName(currentCharPtr); std::string repoName(currentCharPtr);
@ -798,7 +795,7 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
int result = std::system(oss.str().c_str()); int result = std::system(oss.str().c_str());
if (result != 0) { if (result != 0) {
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile"); utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
actionHelper.finish(false, commandedBy, actionId); actionHelper.finish(false, action->commandedBy, action->getId());
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -857,11 +854,16 @@ void CoreController::initPrint() {
#endif #endif
} }
ReturnValue_t CoreController::actionXscReboot(const uint8_t *data, size_t size) { ReturnValue_t CoreController::handleAction(core::XscRebootObcAction *action) {
if (size < 1) { if (action->chip.value == core::XscRebootObcAction::Selection::SAME and
not(action->copy.value == core::XscRebootObcAction::Selection::SAME)) {
return HasActionsIF::INVALID_PARAMETERS; return HasActionsIF::INVALID_PARAMETERS;
} }
bool rebootSameBootCopy = data[0]; bool rebootSameBootCopy = false;
if (action->chip.value == core::XscRebootObcAction::Selection::SAME and
action->copy.value == core::XscRebootObcAction::Selection::SAME) {
rebootSameBootCopy = true;
}
bool protOpPerformed = false; bool protOpPerformed = false;
SdCardManager::instance()->setBlocking(true); SdCardManager::instance()->setBlocking(true);
if (rebootSameBootCopy) { if (rebootSameBootCopy) {
@ -876,19 +878,23 @@ ReturnValue_t CoreController::actionXscReboot(const uint8_t *data, size_t size)
} }
return HasActionsIF::EXECUTION_FINISHED; return HasActionsIF::EXECUTION_FINISHED;
} }
if (size < 3 or (data[1] > 1 or data[2] > 1)) {
return HasActionsIF::INVALID_PARAMETERS;
}
#if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_VERBOSE_LEVEL >= 1
sif::info << "CoreController::actionPerformReboot: Rebooting on " << static_cast<int>(data[1]) sif::info << "CoreController::actionPerformReboot: Rebooting on "
<< " " << static_cast<int>(data[2]) << std::endl; << static_cast<uint8_t>(action->chip.value) << " "
<< static_cast<uint8_t>(action->copy.value) << std::endl;
#endif #endif
// Check that the target chip and copy is writeprotected first // Check that the target chip and copy is writeprotected first
generateChipStateFile(); generateChipStateFile();
// If any boot copies are unprotected, protect them here // If any boot copies are unprotected, protect them here
auto tgtChip = static_cast<xsc::Chip>(data[1]); auto tgtChip = xsc::CHIP_0;
auto tgtCopy = static_cast<xsc::Copy>(data[2]); if (action->chip.value == core::XscRebootObcAction::Selection::ONE) {
tgtChip = xsc::CHIP_1;
}
auto tgtCopy = xsc::COPY_0;
if (action->copy.value == core::XscRebootObcAction::Selection::ONE) {
tgtCopy = xsc::COPY_1;
}
// This function can not really fail // This function can not really fail
gracefulShutdownTasks(tgtChip, tgtCopy, protOpPerformed); gracefulShutdownTasks(tgtChip, tgtCopy, protOpPerformed);
@ -932,7 +938,7 @@ ReturnValue_t CoreController::actionXscReboot(const uint8_t *data, size_t size)
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
ReturnValue_t CoreController::actionReboot(const uint8_t *data, size_t size) { ReturnValue_t CoreController::handleAction(core::RebootObcAction *action) {
bool protOpPerformed = false; bool protOpPerformed = false;
gracefulShutdownTasks(xsc::Chip::CHIP_0, xsc::Copy::COPY_0, protOpPerformed); gracefulShutdownTasks(xsc::Chip::CHIP_0, xsc::Copy::COPY_0, protOpPerformed);
std::system("reboot"); std::system("reboot");
@ -1692,24 +1698,20 @@ void CoreController::resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy) {
std::string path = currMntPrefix + REBOOT_FILE; std::string path = currMntPrefix + REBOOT_FILE;
// Disable the reboot file mechanism // Disable the reboot file mechanism
parseRebootFile(path, rebootFile); parseRebootFile(path, rebootFile);
if (tgtChip == xsc::ALL_CHIP and tgtCopy == xsc::ALL_COPY) { if (tgtChip == xsc::ALL_CHIP or tgtChip == xsc::CHIP_0) {
rebootFile.img00Cnt = 0; if (tgtCopy == xsc::ALL_COPY or tgtCopy == xsc::COPY_0) {
rebootFile.img01Cnt = 0; rebootFile.img00Cnt = 0;
rebootFile.img10Cnt = 0; }
rebootFile.img11Cnt = 0; if (tgtCopy == xsc::ALL_COPY or tgtCopy == xsc::COPY_1) {
} else { rebootFile.img01Cnt = 0;
if (tgtChip == xsc::CHIP_0) { }
if (tgtCopy == xsc::COPY_0) { }
rebootFile.img00Cnt = 0; if (tgtChip == xsc::ALL_CHIP or tgtChip == xsc::CHIP_1) {
} else { if (tgtCopy == xsc::ALL_COPY or tgtCopy == xsc::COPY_0) {
rebootFile.img01Cnt = 0; rebootFile.img10Cnt = 0;
} }
} else { if (tgtCopy == xsc::ALL_COPY or tgtCopy == xsc::COPY_1) {
if (tgtCopy == xsc::COPY_0) { rebootFile.img11Cnt = 0;
rebootFile.img10Cnt = 0;
} else {
rebootFile.img11Cnt = 0;
}
} }
} }
rewriteRebootFile(rebootFile); rewriteRebootFile(rebootFile);
@ -1849,3 +1851,7 @@ bool CoreController::isNumber(const std::string &s) {
return !s.empty() && std::find_if(s.begin(), s.end(), return !s.empty() && std::find_if(s.begin(), s.end(),
[](unsigned char c) { return !std::isdigit(c); }) == s.end(); [](unsigned char c) { return !std::isdigit(c); }) == s.end();
} }
ModeDefinitionHelper CoreController::getModeDefinitionHelper() {
return ModeDefinitionHelper::create<ControllerModes, DefaultSubmode>();
}

View File

@ -6,6 +6,7 @@
#include <cstddef> #include <cstddef>
#include "CoreActions.h"
#include "CoreDefinitions.h" #include "CoreDefinitions.h"
#include "bsp_q7s/memory/SdCardManager.h" #include "bsp_q7s/memory/SdCardManager.h"
#include "events/subsystemIdRanges.h" #include "events/subsystemIdRanges.h"
@ -61,18 +62,6 @@ class CoreController : public ExtendedControllerBase {
"/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME); "/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME);
const std::string TIME_FILE = "/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME); const std::string TIME_FILE = "/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME);
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
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;
//! Reboot using the xsc_boot_copy command
static constexpr ActionId_t XSC_REBOOT_OBC = 32;
static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
//! Reboot using the reboot command
static constexpr ActionId_t REBOOT_OBC = 34;
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
@ -94,8 +83,17 @@ class CoreController : public ExtendedControllerBase {
ReturnValue_t initializeAfterTaskCreation() override; ReturnValue_t initializeAfterTaskCreation() override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t executeAction(Action* action) override;
const uint8_t* data, size_t size) override;
ReturnValue_t handleAction(core::ListDirectoryIntoFileAction* action);
ReturnValue_t handleAction(core::SwitchRebootFileHandlingAction* action);
ReturnValue_t handleAction(core::ResetRebootCountersAction* action);
ReturnValue_t handleAction(core::SwitchImageLockAction* action);
ReturnValue_t handleAction(core::SetMaxRebootCntAction* action);
ReturnValue_t handleAction(core::XscRebootObcAction* action);
ReturnValue_t handleAction(core::RebootObcAction* action);
ModeDefinitionHelper getModeDefinitionHelper() override;
ReturnValue_t handleCommandMessage(CommandMessage* message) override; ReturnValue_t handleCommandMessage(CommandMessage* message) override;
void performControlOperation() override; void performControlOperation() override;
@ -197,6 +195,16 @@ class CoreController : public ExtendedControllerBase {
core::HkSet hkSet; core::HkSet hkSet;
core::ListDirectoryIntoFileAction listDirectoryIntoFileAction =
core::ListDirectoryIntoFileAction(this);
core::SwitchRebootFileHandlingAction switchRebootFileHandlingAction =
core::SwitchRebootFileHandlingAction(this);
core::ResetRebootCountersAction resetRebootCountersAction = core::ResetRebootCountersAction(this);
core::SwitchImageLockAction switchImageLockAction = core::SwitchImageLockAction(this);
core::SetMaxRebootCntAction setMaxRebootCntAction = core::SetMaxRebootCntAction(this);
core::XscRebootObcAction xscRebootObcAction = core::XscRebootObcAction(this);
core::RebootObcAction rebootObcAction = core::RebootObcAction(this);
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override; LocalDataPoolManager& poolManager) override;
Countdown sdCardCheckCd = Countdown(120000); Countdown sdCardCheckCd = Countdown(120000);
@ -224,8 +232,6 @@ class CoreController : public ExtendedControllerBase {
void checkExternalSdCommandStatus(); void checkExternalSdCommandStatus();
void performRebootFileHandling(bool recreateFile); void performRebootFileHandling(bool recreateFile);
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size);
ReturnValue_t actionXscReboot(const uint8_t* data, size_t size); ReturnValue_t actionXscReboot(const uint8_t* data, size_t size);
ReturnValue_t actionReboot(const uint8_t* data, size_t size); ReturnValue_t actionReboot(const uint8_t* data, size_t size);

View File

@ -92,7 +92,7 @@ ReturnValue_t readToFile(std::string name, std::ifstream& file, std::string& fil
} // End of anonymous namespace } // End of anonymous namespace
template <typename T, class = typename std::enable_if<std::is_integral<T>::value>::type> template <typename T, class>
inline ReturnValue_t writeNumber(std::string key, T num) noexcept { inline ReturnValue_t writeNumber(std::string key, T num) noexcept {
std::ostringstream oss; std::ostringstream oss;
oss << "xsc_scratch write " << key << " " << std::to_string(num); oss << "xsc_scratch write " << key << " " << std::to_string(num);
@ -104,7 +104,7 @@ inline ReturnValue_t writeNumber(std::string key, T num) noexcept {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
template <typename T, class = typename std::enable_if<std::is_integral<T>::value>::type> template <typename T, class>
inline ReturnValue_t readNumber(std::string key, T& num) noexcept { inline ReturnValue_t readNumber(std::string key, T& num) noexcept {
using namespace std; using namespace std;
ifstream file; ifstream file;

View File

@ -3,83 +3,85 @@
#include <cstdint> #include <cstdint>
#include <fsfw/introspection/ClasslessEnum.h>
namespace objects { namespace objects {
enum commonObjects : uint32_t { FSFW_CLASSLESS_ENUM(commonObjects, uint32_t,
/* First Byte 0x50-0x52 reserved for PUS Services **/ /* First Byte 0x50-0x52 reserved for PUS Services **/
CCSDS_PACKET_DISTRIBUTOR = 0x50000100, ((CCSDS_PACKET_DISTRIBUTOR, 0x50000100, "CCSDS_PACKET_DISTRIBUTOR"))
PUS_PACKET_DISTRIBUTOR = 0x50000200, ((PUS_PACKET_DISTRIBUTOR, 0x50000200, "PUS_PACKET_DISTRIBUTOR"))
TMTC_BRIDGE = 0x50000300, ((TMTC_BRIDGE, 0x50000300, "TMTC_BRIDGE"))
TMTC_POLLING_TASK = 0x50000400, ((TMTC_POLLING_TASK, 0x50000400, "TMTC_POLLING_TASK"))
FILE_SYSTEM_HANDLER = 0x50000500, ((FILE_SYSTEM_HANDLER, 0x50000500, "FILE_SYSTEM_HANDLER"))
SDC_MANAGER = 0x50000550, ((SDC_MANAGER, 0x50000550, "SDC_MANAGER"))
PTME = 0x50000600, ((PTME, 0x50000600, "PTME"))
PDEC_HANDLER = 0x50000700, ((PDEC_HANDLER, 0x50000700, "PDEC_HANDLER"))
CCSDS_HANDLER = 0x50000800, ((CCSDS_HANDLER, 0x50000800, "CCSDS_HANDLER"))
/* 0x43 ('C') for Controllers */ /* 0x43 ('C') for Controllers */
THERMAL_CONTROLLER = 0x43400001, ((THERMAL_CONTROLLER, 0x43400001, "THERMAL_CONTROLLER"))
ACS_CONTROLLER = 0x43000002, ((ACS_CONTROLLER, 0x43000002, "ACS_CONTROLLER"))
CORE_CONTROLLER = 0x43000003, ((CORE_CONTROLLER, 0x43000003, "CORE_CONTROLLER"))
/* 0x44 ('D') for device handlers */ /* 0x44 ('D') for device handlers */
MGM_0_LIS3_HANDLER = 0x44120006, ((MGM_0_LIS3_HANDLER, 0x44120006, "MGM_0_LIS3_HANDLER"))
MGM_1_RM3100_HANDLER = 0x44120107, ((MGM_1_RM3100_HANDLER, 0x44120107, "MGM_1_RM3100_HANDLER"))
MGM_2_LIS3_HANDLER = 0x44120208, ((MGM_2_LIS3_HANDLER, 0x44120208, "MGM_2_LIS3_HANDLER"))
MGM_3_RM3100_HANDLER = 0x44120309, ((MGM_3_RM3100_HANDLER, 0x44120309, "MGM_3_RM3100_HANDLER"))
GYRO_0_ADIS_HANDLER = 0x44120010, ((GYRO_0_ADIS_HANDLER, 0x44120010, "GYRO_0_ADIS_HANDLER"))
GYRO_1_L3G_HANDLER = 0x44120111, ((GYRO_1_L3G_HANDLER, 0x44120111, "GYRO_1_L3G_HANDLER"))
GYRO_2_ADIS_HANDLER = 0x44120212, ((GYRO_2_ADIS_HANDLER, 0x44120212, "GYRO_2_ADIS_HANDLER"))
GYRO_3_L3G_HANDLER = 0x44120313, ((GYRO_3_L3G_HANDLER, 0x44120313, "GYRO_3_L3G_HANDLER"))
RW1 = 0x44120047, ((RW1, 0x44120047, "RW1"))
RW2 = 0x44120148, ((RW2, 0x44120148, "RW2"))
RW3 = 0x44120249, ((RW3, 0x44120249, "RW3"))
RW4 = 0x44120350, ((RW4, 0x44120350, "RW4"))
STAR_TRACKER = 0x44130001, ((STAR_TRACKER, 0x44130001, "STAR_TRACKER"))
GPS_CONTROLLER = 0x44130045, ((GPS_CONTROLLER, 0x44130045, "GPS_CONTROLLER"))
IMTQ_HANDLER = 0x44140014, ((IMTQ_HANDLER, 0x44140014, "IMTQ_HANDLER"))
TMP1075_HANDLER_1 = 0x44420004, ((TMP1075_HANDLER_1, 0x44420004, "TMP1075_HANDLER_1"))
TMP1075_HANDLER_2 = 0x44420005, ((TMP1075_HANDLER_2, 0x44420005, "TMP1075_HANDLER_2"))
PCDU_HANDLER = 0x442000A1, ((PCDU_HANDLER, 0x442000A1, "PCDU_HANDLER"))
P60DOCK_HANDLER = 0x44250000, ((P60DOCK_HANDLER, 0x44250000, "P60DOCK_HANDLER"))
PDU1_HANDLER = 0x44250001, ((PDU1_HANDLER, 0x44250001, "PDU1_HANDLER"))
PDU2_HANDLER = 0x44250002, ((PDU2_HANDLER, 0x44250002, "PDU2_HANDLER"))
ACU_HANDLER = 0x44250003, ((ACU_HANDLER, 0x44250003, "ACU_HANDLER"))
BPX_BATT_HANDLER = 0x44260000, ((BPX_BATT_HANDLER, 0x44260000, "BPX_BATT_HANDLER"))
PLPCDU_HANDLER = 0x44300000, ((PLPCDU_HANDLER, 0x44300000, "PLPCDU_HANDLER"))
RAD_SENSOR = 0x443200A5, ((RAD_SENSOR, 0x443200A5, "RAD_SENSOR"))
PLOC_UPDATER = 0x44330000, ((PLOC_UPDATER, 0x44330000, "PLOC_UPDATER"))
PLOC_MEMORY_DUMPER = 0x44330001, ((PLOC_MEMORY_DUMPER, 0x44330001, "PLOC_MEMORY_DUMPER"))
STR_HELPER = 0x44330002, ((STR_HELPER, 0x44330002, "STR_HELPER"))
PLOC_MPSOC_HELPER = 0x44330003, ((PLOC_MPSOC_HELPER, 0x44330003, "PLOC_MPSOC_HELPER"))
AXI_PTME_CONFIG = 0x44330004, ((AXI_PTME_CONFIG, 0x44330004, "AXI_PTME_CONFIG"))
PTME_CONFIG = 0x44330005, ((PTME_CONFIG, 0x44330005, "PTME_CONFIG"))
PLOC_MPSOC_HANDLER = 0x44330015, ((PLOC_MPSOC_HANDLER, 0x44330015, "PLOC_MPSOC_HANDLER"))
PLOC_SUPERVISOR_HANDLER = 0x44330016, ((PLOC_SUPERVISOR_HANDLER, 0x44330016, "PLOC_SUPERVISOR_HANDLER"))
PLOC_SUPERVISOR_HELPER = 0x44330017, ((PLOC_SUPERVISOR_HELPER, 0x44330017, "PLOC_SUPERVISOR_HELPER"))
SOLAR_ARRAY_DEPL_HANDLER = 0x444100A2, ((SOLAR_ARRAY_DEPL_HANDLER, 0x444100A2, "SOLAR_ARRAY_DEPL_HANDLER"))
HEATER_HANDLER = 0x444100A4, ((HEATER_HANDLER, 0x444100A4, "HEATER_HANDLER"))
/** /**
* Not yet specified which pt1000 will measure which device/location in the satellite. * Not yet specified which pt1000 will measure which device/location in the satellite.
* Therefore object ids are named according to the IC naming of the RTDs in the schematic. * Therefore object ids are named according to the IC naming of the RTDs in the schematic.
*/ */
RTD_0_IC3_PLOC_HEATSPREADER = 0x44420016, ((RTD_0_IC3_PLOC_HEATSPREADER, 0x44420016, "RTD_0_IC3_PLOC_HEATSPREADER"))
RTD_1_IC4_PLOC_MISSIONBOARD = 0x44420017, ((RTD_1_IC4_PLOC_MISSIONBOARD, 0x44420017, "RTD_1_IC4_PLOC_MISSIONBOARD"))
RTD_2_IC5_4K_CAMERA = 0x44420018, ((RTD_2_IC5_4K_CAMERA, 0x44420018, "RTD_2_IC5_4K_CAMERA"))
RTD_3_IC6_DAC_HEATSPREADER = 0x44420019, ((RTD_3_IC6_DAC_HEATSPREADER, 0x44420019, "RTD_3_IC6_DAC_HEATSPREADER"))
RTD_4_IC7_STARTRACKER = 0x44420020, ((RTD_4_IC7_STARTRACKER, 0x44420020, "RTD_4_IC7_STARTRACKER"))
RTD_5_IC8_RW1_MX_MY = 0x44420021, ((RTD_5_IC8_RW1_MX_MY, 0x44420021, "RTD_5_IC8_RW1_MX_MY"))
RTD_6_IC9_DRO = 0x44420022, ((RTD_6_IC9_DRO, 0x44420022, "RTD_6_IC9_DRO"))
RTD_7_IC10_SCEX = 0x44420023, ((RTD_7_IC10_SCEX, 0x44420023, "RTD_7_IC10_SCEX"))
RTD_8_IC11_X8 = 0x44420024, ((RTD_8_IC11_X8, 0x44420024, "RTD_8_IC11_X8"))
RTD_9_IC12_HPA = 0x44420025, ((RTD_9_IC12_HPA, 0x44420025, "RTD_9_IC12_HPA"))
RTD_10_IC13_PL_TX = 0x44420026, ((RTD_10_IC13_PL_TX, 0x44420026, "RTD_10_IC13_PL_TX"))
RTD_11_IC14_MPA = 0x44420027, ((RTD_11_IC14_MPA, 0x44420027, "RTD_11_IC14_MPA"))
RTD_12_IC15_ACU = 0x44420028, ((RTD_12_IC15_ACU, 0x44420028, "RTD_12_IC15_ACU"))
RTD_13_IC16_PLPCDU_HEATSPREADER = 0x44420029, ((RTD_13_IC16_PLPCDU_HEATSPREADER, 0x44420029, "RTD_13_IC16_PLPCDU_HEATSPREADER"))
RTD_14_IC17_TCS_BOARD = 0x44420030, ((RTD_14_IC17_TCS_BOARD, 0x44420030, "RTD_14_IC17_TCS_BOARD"))
RTD_15_IC18_IMTQ = 0x44420031, ((RTD_15_IC18_IMTQ, 0x44420031, "RTD_15_IC18_IMTQ"))
// Name convention for SUS devices // Name convention for SUS devices
// SUS_<IDX>_<N/R>_LOC_X<F/M/B>Y<F/M/B>Z<F/M/B>_PT_<DIR><F/B> // SUS_<IDX>_<N/R>_LOC_X<F/M/B>Y<F/M/B>Z<F/M/B>_PT_<DIR><F/B>
@ -87,42 +89,42 @@ enum commonObjects : uint32_t {
// PT: Pointing // PT: Pointing
// N/R: Nominal/Redundant // N/R: Nominal/Redundant
// F/M/B: Forward/Middle/Backwards // F/M/B: Forward/Middle/Backwards
SUS_0_N_LOC_XFYFZM_PT_XF = 0x44120032, ((SUS_0_N_LOC_XFYFZM_PT_XF, 0x44120032, "SUS_0_N_LOC_XFYFZM_PT_XF"))
SUS_6_R_LOC_XFYBZM_PT_XF = 0x44120038, ((SUS_6_R_LOC_XFYBZM_PT_XF, 0x44120038, "SUS_6_R_LOC_XFYBZM_PT_XF"))
SUS_1_N_LOC_XBYFZM_PT_XB = 0x44120033, ((SUS_1_N_LOC_XBYFZM_PT_XB, 0x44120033, "SUS_1_N_LOC_XBYFZM_PT_XB"))
SUS_7_R_LOC_XBYBZM_PT_XB = 0x44120039, ((SUS_7_R_LOC_XBYBZM_PT_XB, 0x44120039, "SUS_7_R_LOC_XBYBZM_PT_XB"))
SUS_2_N_LOC_XFYBZB_PT_YB = 0x44120034, ((SUS_2_N_LOC_XFYBZB_PT_YB, 0x44120034, "SUS_2_N_LOC_XFYBZB_PT_YB"))
SUS_8_R_LOC_XBYBZB_PT_YB = 0x44120040, ((SUS_8_R_LOC_XBYBZB_PT_YB, 0x44120040, "SUS_8_R_LOC_XBYBZB_PT_YB"))
SUS_3_N_LOC_XFYBZF_PT_YF = 0x44120035, ((SUS_3_N_LOC_XFYBZF_PT_YF, 0x44120035, "SUS_3_N_LOC_XFYBZF_PT_YF"))
SUS_9_R_LOC_XBYBZB_PT_YF = 0x44120041, ((SUS_9_R_LOC_XBYBZB_PT_YF, 0x44120041, "SUS_9_R_LOC_XBYBZB_PT_YF"))
SUS_4_N_LOC_XMYFZF_PT_ZF = 0x44120036, ((SUS_4_N_LOC_XMYFZF_PT_ZF, 0x44120036, "SUS_4_N_LOC_XMYFZF_PT_ZF"))
SUS_10_N_LOC_XMYBZF_PT_ZF = 0x44120042, ((SUS_10_N_LOC_XMYBZF_PT_ZF, 0x44120042, "SUS_10_N_LOC_XMYBZF_PT_ZF"))
SUS_5_N_LOC_XFYMZB_PT_ZB = 0x44120037, ((SUS_5_N_LOC_XFYMZB_PT_ZB, 0x44120037, "SUS_5_N_LOC_XFYMZB_PT_ZB"))
SUS_11_R_LOC_XBYMZB_PT_ZB = 0x44120043, ((SUS_11_R_LOC_XBYMZB_PT_ZB, 0x44120043, "SUS_11_R_LOC_XBYMZB_PT_ZB"))
SYRLINKS_HK_HANDLER = 0x445300A3, ((SYRLINKS_HK_HANDLER, 0x445300A3, "SYRLINKS_HK_HANDLER"))
// 0x60 for other stuff // 0x60 for other stuff
HEATER_0_PLOC_PROC_BRD = 0x60000000, ((HEATER_0_PLOC_PROC_BRD, 0x60000000, "HEATER_0_PLOC_PROC_BRD"))
HEATER_1_PCDU_BRD = 0x60000001, ((HEATER_1_PCDU_BRD, 0x60000001, "HEATER_1_PCDU_BRD"))
HEATER_2_ACS_BRD = 0x60000002, ((HEATER_2_ACS_BRD, 0x60000002, "HEATER_2_ACS_BRD"))
HEATER_3_OBC_BRD = 0x60000003, ((HEATER_3_OBC_BRD, 0x60000003, "HEATER_3_OBC_BRD"))
HEATER_4_CAMERA = 0x60000004, ((HEATER_4_CAMERA, 0x60000004, "HEATER_4_CAMERA"))
HEATER_5_STR = 0x60000005, ((HEATER_5_STR, 0x60000005, "HEATER_5_STR"))
HEATER_6_DRO = 0x60000006, ((HEATER_6_DRO, 0x60000006, "HEATER_6_DRO"))
HEATER_7_HPA = 0x60000007, ((HEATER_7_HPA, 0x60000007, "HEATER_7_HPA"))
// 0x73 ('s') for assemblies and system/subsystem components // 0x73 ('s') for assemblies and system/subsystem components
ACS_BOARD_ASS = 0x73000001, ((ACS_BOARD_ASS, 0x73000001, "ACS_BOARD_ASS"))
SUS_BOARD_ASS = 0x73000002, ((SUS_BOARD_ASS, 0x73000002, "SUS_BOARD_ASS"))
TCS_BOARD_ASS = 0x73000003, ((TCS_BOARD_ASS, 0x73000003, "TCS_BOARD_ASS"))
RW_ASS = 0x73000004 ((RW_ASS, 0x73000004, "RW_ASS"))
}; )
} }
#endif /* COMMON_CONFIG_COMMONOBJECTS_H_ */ #endif /* COMMON_CONFIG_COMMONOBJECTS_H_ */

2
fsfw

@ -1 +1 @@
Subproject commit d975958120bd151dabdc450a104e9cc8069ff509 Subproject commit 383bafe3446a832edc466d850c637ea879fa1934

View File

@ -1,7 +1,7 @@
add_subdirectory(csp) add_subdirectory(csp)
add_subdirectory(utility) add_subdirectory(utility)
add_subdirectory(callbacks) add_subdirectory(callbacks)
add_subdirectory(boardtest) #add_subdirectory(boardtest)
add_subdirectory(devices) add_subdirectory(devices)
add_subdirectory(fsfwconfig) add_subdirectory(fsfwconfig)
add_subdirectory(obc) add_subdirectory(obc)

View File

@ -53,22 +53,24 @@ ReturnValue_t GPSHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t GPSHyperionLinuxController::executeAction(ActionId_t actionId, ModeDefinitionHelper GPSHyperionLinuxController::getModeDefinitionHelper() {
MessageQueueId_t commandedBy, //TODO verify which modes are supported
const uint8_t *data, size_t size) { return ModeDefinitionHelper::create<ControllerModes, DefaultSubmode>();
switch (actionId) { }
case (GpsHyperion::TRIGGER_RESET_PIN_GNSS): {
if (resetCallback != nullptr) { ReturnValue_t GPSHyperionLinuxController::executeAction(Action *action) {
PoolReadGuard pg(&gpsSet); return action->handle();
// Set HK entries invalid }
gpsSet.setValidity(false, true);
resetCallback(data, size, resetCallbackArgs); ReturnValue_t GPSHyperionLinuxController::handleAction(GPSHyperionLinuxAction * action) {
return HasActionsIF::EXECUTION_FINISHED; if (resetCallback != nullptr) {
} PoolReadGuard pg(&gpsSet);
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; // Set HK entries invalid
} gpsSet.setValidity(false, true);
resetCallback(static_cast<uint8_t>(action->gpsId.value), resetCallbackArgs);
return HasActionsIF::EXECUTION_FINISHED;
} }
return HasReturnvaluesIF::RETURN_OK; return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
} }
ReturnValue_t GPSHyperionLinuxController::initializeLocalDataPool( ReturnValue_t GPSHyperionLinuxController::initializeLocalDataPool(

View File

@ -2,10 +2,11 @@
#define MISSION_DEVICES_GPSHYPERIONHANDLER_H_ #define MISSION_DEVICES_GPSHYPERIONHANDLER_H_
#include "commonSubsystemIds.h" #include "commonSubsystemIds.h"
#include "devicedefinitions/GPSHyperionLinuxDefinitions.h"
#include "fsfw/FSFW.h" #include "fsfw/FSFW.h"
#include "fsfw/controller/ExtendedControllerBase.h" #include "fsfw/controller/ExtendedControllerBase.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "mission/devices/devicedefinitions/GPSDefinitions.h"
#ifdef FSFW_OSAL_LINUX #ifdef FSFW_OSAL_LINUX
#include <gps.h> #include <gps.h>
@ -30,7 +31,7 @@ class GPSHyperionLinuxController : public ExtendedControllerBase {
bool debugHyperionGps = false); bool debugHyperionGps = false);
virtual ~GPSHyperionLinuxController(); virtual ~GPSHyperionLinuxController();
using gpioResetFunction_t = ReturnValue_t (*)(const uint8_t* actionData, size_t len, void* args); using gpioResetFunction_t = ReturnValue_t (*)(uint8_t gpsId, void* args);
void setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void* args); void setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void* args);
ReturnValue_t handleCommandMessage(CommandMessage* message) override; ReturnValue_t handleCommandMessage(CommandMessage* message) override;
@ -38,8 +39,9 @@ class GPSHyperionLinuxController : public ExtendedControllerBase {
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override; uint32_t* msToReachTheMode) override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ModeDefinitionHelper getModeDefinitionHelper() override;
const uint8_t* data, size_t size) override; ReturnValue_t executeAction(Action* action) override;
ReturnValue_t handleAction(GPSHyperionLinuxAction * action);
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
protected: protected:
@ -65,6 +67,7 @@ class GPSHyperionLinuxController : public ExtendedControllerBase {
int32_t noModeSetCntr = 0; int32_t noModeSetCntr = 0;
uint32_t timeIsConstantCounter = 0; uint32_t timeIsConstantCounter = 0;
Countdown timeUpdateCd = Countdown(60); Countdown timeUpdateCd = Countdown(60);
GPSHyperionLinuxAction action = GPSHyperionLinuxAction(this);
void readGpsDataFromGpsd(); void readGpsDataFromGpsd();
}; };

View File

@ -0,0 +1,23 @@
#pragma once
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/introspection/Enum.h>
#include "mission/devices/devicedefinitions/GPSDefinitions.h"
class GPSHyperionLinuxController;
FSFW_ENUM(GPSHyperionLinuxCommands, DeviceCommandId_t,
((TRIGGER_RESET_PIN_GNSS, GpsHyperion::TRIGGER_RESET_PIN_GNSS, "Trigger Reset Pin")))
class GPSHyperionLinuxAction
: public TemplateAction<GPSHyperionLinuxController, GPSHyperionLinuxAction,
GPSHyperionLinuxCommands> {
public:
FSFW_ENUM(GpsIDs, uint8_t, ((GPS_0, 0, "GPS 0"))((GPS_1, 1, "GPS 1")))
GPSHyperionLinuxAction(GPSHyperionLinuxController *owner)
: TemplateAction(owner, GPSHyperionLinuxCommands::TRIGGER_RESET_PIN_GNSS){};
Parameter<GpsIDs> gpsId = Parameter<GpsIDs>::createParameter(this, "GPS ID");
};

View File

@ -0,0 +1,646 @@
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCCOMMONDEFINITIONS_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCCOMMONDEFINITIONS_H_
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/introspection/Enum.h>
#include "MPSoCReturnValuesIF.h"
#include "OBSWConfig.h"
#include "eive/definitions.h"
#include "fsfw/globalfunctions/CRC.h"
#include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/tmtcpacket/SpacePacket.h"
namespace mpsoc {
static const uint16_t SIZE_ACK_REPORT = 14;
static const uint16_t SIZE_EXE_REPORT = 14;
static const uint16_t SIZE_TM_MEM_READ_REPORT = 18;
static const uint16_t SIZE_TM_CAM_CMD_RPT = 18;
/**
* SpacePacket apids of PLOC telecommands and telemetry.
*/
namespace apid {
static const uint16_t TC_REPLAY_START = 0x110;
static const uint16_t TC_REPLAY_STOP = 0x111;
static const uint16_t TC_REPLAY_WRITE_SEQUENCE = 0x112;
static const uint16_t TC_DOWNLINK_PWR_ON = 0x113;
static const uint16_t TC_MEM_WRITE = 0x114;
static const uint16_t TC_MEM_READ = 0x115;
static const uint16_t TC_FLASHWRITE = 0x117;
static const uint16_t TC_FLASHFOPEN = 0x119;
static const uint16_t TC_FLASHFCLOSE = 0x11A;
static const uint16_t TC_FLASHDELETE = 0x11C;
static const uint16_t TC_MODE_REPLAY = 0x11F;
static const uint16_t TC_MODE_IDLE = 0x11E;
static const uint16_t TC_DOWNLINK_PWR_OFF = 0x124;
static const uint16_t TC_CAM_CMD_SEND = 0x12C;
static const uint16_t TM_MEMORY_READ_REPORT = 0x404;
static const uint16_t ACK_SUCCESS = 0x400;
static const uint16_t ACK_FAILURE = 0x401;
static const uint16_t EXE_SUCCESS = 0x402;
static const uint16_t EXE_FAILURE = 0x403;
static const uint16_t TM_CAM_CMD_RPT = 0x407;
} // namespace apid
/** Offset from first byte in space packet to first byte of data field */
static const uint8_t DATA_FIELD_OFFSET = 6;
static const size_t MEM_READ_RPT_LEN_OFFSET = 10;
static const char NULL_TERMINATOR = '\0';
static const uint8_t MIN_SPACE_PACKET_LENGTH = 7;
static const uint8_t SPACE_PACKET_HEADER_SIZE = 6;
/**
* The size of payload data which will be forwarded to the requesting object. e.g. PUS Service
* 8.
*/
static const uint8_t SIZE_MEM_READ_RPT_FIX = 6;
static const size_t MAX_FILENAME_SIZE = 256;
/**
* PLOC space packet length for fixed size packets. This is the size of the whole packet data
* field. For the length field in the space packet this size will be substracted by one.
*/
static const uint16_t LENGTH_TC_MEM_WRITE = 12;
static const uint16_t LENGTH_TC_MEM_READ = 8;
static const size_t MAX_REPLY_SIZE = SpacePacket::PACKET_MAX_SIZE * 3;
static const size_t MAX_COMMAND_SIZE = SpacePacket::PACKET_MAX_SIZE;
static const size_t MAX_DATA_SIZE = 1016;
/**
* The replay write sequence command has a maximum delay for the execution report which amounts to
* 30 seconds. (80 cycles * 0.5 seconds = 40 seconds).
*/
static const uint16_t TC_WRITE_SEQ_EXECUTION_DELAY = 80;
// Requires approx. 2 seconds for execution. 8 => 4 seconds
static const uint16_t TC_DOWNLINK_PWR_ON_EXECUTION_DELAY = 8;
namespace status_code {
static const uint16_t UNKNOWN_APID = 0x5DD;
static const uint16_t INCORRECT_LENGTH = 0x5DE;
static const uint16_t INCORRECT_CRC = 0x5DF;
static const uint16_t INCORRECT_PKT_SEQ_CNT = 0x5E0;
static const uint16_t TC_NOT_ALLOWED_IN_MODE = 0x5E1;
static const uint16_t TC_EXEUTION_DISABLED = 0x5E2;
static const uint16_t FLASH_MOUNT_FAILED = 0x5E3;
static const uint16_t FLASH_FILE_ALREADY_CLOSED = 0x5E4;
static const uint16_t FLASH_FILE_OPEN_FAILED = 0x5E5;
static const uint16_t FLASH_FILE_ALREDY_OPEN = 0x5E6;
static const uint16_t FLASH_FILE_NOT_OPEN = 0x5E7;
static const uint16_t FLASH_UNMOUNT_FAILED = 0x5E8;
static const uint16_t HEAP_ALLOCATION_FAILED = 0x5E9;
static const uint16_t INVALID_PARAMETER = 0x5EA;
static const uint16_t NOT_INITIALIZED = 0x5EB;
static const uint16_t REBOOT_IMMINENT = 0x5EC;
static const uint16_t CORRUPT_DATA = 0x5ED;
static const uint16_t FLASH_CORRECTABLE_MISMATCH = 0x5EE;
static const uint16_t FLASH_UNCORRECTABLE_MISMATCH = 0x5EF;
static const uint16_t RESERVED_0 = 0x5F0;
static const uint16_t RESERVED_1 = 0x5F1;
static const uint16_t RESERVED_2 = 0x5F2;
static const uint16_t RESERVED_3 = 0x5F3;
static const uint16_t RESERVED_4 = 0x5F4;
} // namespace status_code
/**
* @brief Abstract base class for TC space packet of MPSoC.
*/
class TcBase : public SpacePacket, public MPSoCReturnValuesIF {
public:
// Initial length field of space packet. Will always be updated when packet is created.
static const uint16_t INIT_LENGTH = 1;
/**
* @brief Constructor
*
* @param sequenceCount Sequence count of space packet which will be incremented with each
* sent and received packets.
*/
TcBase(uint16_t apid, uint16_t sequenceCount)
: SpacePacket(INIT_LENGTH, true, apid, sequenceCount) {}
/**
* @brief Function to initialize the space packet
*
* @param commandData Pointer to command specific data
* @param commandDataLen Length of command data
*
* @return RETURN_OK if packet creation was successful, otherwise error return value
*/
virtual ReturnValue_t createPacket(void *action) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = initPacket(action);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
protected:
/**
* @brief Must be overwritten by the child class to define the command specific parameters
*
* @param commandData Pointer to received command data
* @param commandDataLen Length of received command data
*/
virtual ReturnValue_t initPacket(void *action) {
return HasReturnvaluesIF::RETURN_OK;
}
/**
* @brief Calculates and adds the CRC
*/
ReturnValue_t addCrc() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
size_t serializedSize = 0;
uint32_t full_size = getFullSize();
uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE);
result = SerializeAdapter::serialize<uint16_t>(
&crc, this->localData.byteStream + full_size - CRC_SIZE, &serializedSize, sizeof(crc),
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::debug << "TcBase::addCrc: Failed to serialize crc field" << std::endl;
}
return result;
}
};
/**
* @brief Class for handling tm replies of the PLOC MPSoC.
*/
class TmPacket : public SpacePacket, public MPSoCReturnValuesIF {
public:
/**
* @brief Constructor creates idle packet and sets length field to maximum allowed size.
*/
TmPacket() : SpacePacket(PACKET_MAX_SIZE) {}
ReturnValue_t checkCrc() {
uint8_t *crcPtr = this->getPacketData() + this->getPacketDataLength() - 1;
uint16_t receivedCrc = *(crcPtr) << 8 | *(crcPtr + 1);
uint16_t recalculatedCrc =
CRC::crc16ccitt(this->localData.byteStream, this->getFullSize() - CRC_SIZE);
if (recalculatedCrc != receivedCrc) {
return CRC_FAILURE;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief This class helps to build the memory read command for the PLOC.
*/
class TcMemRead : public TcBase {
public:
/**
* @brief Constructor
*/
TcMemRead(uint16_t sequenceCount) : TcBase(apid::TC_MEM_READ, sequenceCount) {
this->setPacketDataLength(PACKET_LENGTH);
}
uint16_t getMemLen() const { return memLen; }
protected:
ReturnValue_t initPacket(const uint8_t *commandData, size_t commandDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, MEM_ADDRESS_SIZE);
std::memcpy(this->localData.fields.buffer + MEM_ADDRESS_SIZE, commandData + MEM_ADDRESS_SIZE,
MEM_LEN_SIZE);
size_t size = sizeof(memLen);
const uint8_t *memLenPtr = commandData + MEM_ADDRESS_SIZE;
result =
SerializeAdapter::deSerialize(&memLen, &memLenPtr, &size, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
private:
static const size_t COMMAND_LENGTH = 6;
static const size_t MEM_ADDRESS_SIZE = 4;
static const size_t MEM_LEN_SIZE = 2;
static const uint16_t PACKET_LENGTH = 7;
uint16_t memLen = 0;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen != COMMAND_LENGTH) {
return INVALID_LENGTH;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief Class to help creation of flash fopen command.
*/
class FlashFopen : public TcBase {
public:
FlashFopen(uint16_t sequenceCount) : TcBase(apid::TC_FLASHFOPEN, sequenceCount) {}
static const char APPEND = 'a';
static const char WRITE = 'w';
static const char READ = 'r';
ReturnValue_t createPacket(std::string filename, char accessMode_) {
accessMode = accessMode_;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
size_t nameSize = filename.size();
std::memcpy(this->getPacketData(), filename.c_str(), nameSize);
*(this->getPacketData() + nameSize) = NULL_TERMINATOR;
std::memcpy(this->getPacketData() + nameSize + sizeof(NULL_TERMINATOR), &accessMode,
sizeof(accessMode));
this->setPacketDataLength(nameSize + sizeof(NULL_TERMINATOR) + sizeof(accessMode) + CRC_SIZE -
1);
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
private:
char accessMode = APPEND;
};
/**
* @brief Class to help creation of flash fclose command.
*/
class FlashFclose : public TcBase {
public:
FlashFclose(uint16_t sequenceCount) : TcBase(apid::TC_FLASHFCLOSE, sequenceCount) {}
ReturnValue_t createPacket(std::string filename) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
size_t nameSize = filename.size();
std::memcpy(this->getPacketData(), filename.c_str(), nameSize);
*(this->getPacketData() + nameSize) = NULL_TERMINATOR;
this->setPacketDataLength(nameSize + sizeof(NULL_TERMINATOR) + CRC_SIZE - 1);
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
};
/**
* @brief Class to build flash write space packet.
*/
class TcFlashWrite : public TcBase {
public:
TcFlashWrite(uint16_t sequenceCount) : TcBase(apid::TC_FLASHWRITE, sequenceCount) {}
ReturnValue_t createPacket(const uint8_t *writeData, uint32_t writeLen_) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
writeLen = writeLen_;
if (writeLen > MAX_DATA_SIZE) {
sif::debug << "FlashWrite::createPacket: Command data too big" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
size_t serializedSize = 0;
result =
SerializeAdapter::serialize<uint32_t>(&writeLen, this->getPacketData(), &serializedSize,
sizeof(writeLen), SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->getPacketData() + sizeof(writeLen), writeData, writeLen);
this->setPacketDataLength(static_cast<uint16_t>(writeLen + CRC_SIZE - 1));
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return HasReturnvaluesIF::RETURN_OK;
}
private:
uint32_t writeLen = 0;
};
/**
* @brief Class to help creation of flash delete command.
*/
class TcFlashDelete : public TcBase {
public:
TcFlashDelete(uint16_t sequenceCount) : TcBase(apid::TC_FLASHDELETE, sequenceCount) {}
ReturnValue_t createPacket(std::string filename) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
size_t nameSize = filename.size();
std::memcpy(this->getPacketData(), filename.c_str(), nameSize);
*(this->getPacketData() + nameSize) = NULL_TERMINATOR;
this->setPacketDataLength(nameSize + sizeof(NULL_TERMINATOR) + CRC_SIZE - 1);
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
};
/**
* @brief Class to build replay stop space packet.
*/
class TcReplayStop : public TcBase {
public:
TcReplayStop(uint16_t sequenceCount) : TcBase(apid::TC_REPLAY_STOP, sequenceCount) {}
ReturnValue_t createPacket() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
this->setPacketDataLength(static_cast<uint16_t>(CRC_SIZE - 1));
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief This class helps to build the replay start command.
*/
class TcReplayStart : public TcBase {
public:
/**
* @brief Constructor
*/
TcReplayStart(uint16_t sequenceCount) : TcBase(apid::TC_REPLAY_START, sequenceCount) {}
protected:
ReturnValue_t initPacket(const uint8_t *commandData, size_t commandDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = checkData(*commandData);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, commandDataLen);
this->setPacketDataLength(commandDataLen + CRC_SIZE - 1);
return result;
}
private:
static const size_t COMMAND_DATA_LENGTH = 1;
static const uint8_t REPEATING = 0;
static const uint8_t ONCE = 1;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen != COMMAND_DATA_LENGTH) {
sif::warning << "TcReplayStart: Command has invalid length " << commandDataLen << std::endl;
return INVALID_LENGTH;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t checkData(uint8_t replay) {
if (replay != REPEATING && replay != ONCE) {
sif::warning << "TcReplayStart::checkData: Invalid replay value" << std::endl;
return INVALID_PARAMETER;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief This class helps to build downlink power on command.
*/
class TcDownlinkPwrOn : public TcBase {
public:
/**
* @brief Constructor
*/
TcDownlinkPwrOn(uint16_t sequenceCount) : TcBase(apid::TC_DOWNLINK_PWR_ON, sequenceCount) {}
protected:
ReturnValue_t initPacket(const uint8_t *commandData, size_t commandDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = modeCheck(*commandData);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = laneRateCheck(*(commandData + 1));
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, commandDataLen);
std::memcpy(this->localData.fields.buffer + commandDataLen, &MAX_AMPLITUDE,
sizeof(MAX_AMPLITUDE));
this->setPacketDataLength(commandDataLen + sizeof(MAX_AMPLITUDE) + CRC_SIZE - 1);
return result;
}
private:
static const uint8_t INTERFACE_ID = CLASS_ID::DWLPWRON_CMD;
//! [EXPORT] : [COMMENT] Received command has invalid JESD mode (valid modes are 0 - 5)
static const ReturnValue_t INVALID_MODE = MAKE_RETURN_CODE(0xE0);
//! [EXPORT] : [COMMENT] Received command has invalid lane rate (valid lane rate are 0 - 9)
static const ReturnValue_t INVALID_LANE_RATE = MAKE_RETURN_CODE(0xE1);
static const size_t COMMAND_DATA_LENGTH = 2;
static const uint8_t MAX_MODE = 5;
static const uint8_t MAX_LANE_RATE = 9;
static const uint16_t MAX_AMPLITUDE = 0;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen != COMMAND_DATA_LENGTH) {
sif::warning << "TcDownlinkPwrOn: Command has invalid length " << commandDataLen << std::endl;
return INVALID_LENGTH;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t modeCheck(uint8_t mode) {
if (mode > MAX_MODE) {
sif::warning << "TcDwonlinkPwrOn::modeCheck: Invalid JESD mode" << std::endl;
return INVALID_MODE;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t laneRateCheck(uint8_t laneRate) {
if (laneRate > MAX_LANE_RATE) {
sif::warning << "TcReplayStart::laneRateCheck: Invalid lane rate" << std::endl;
return INVALID_LANE_RATE;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief Class to build replay stop space packet.
*/
class TcDownlinkPwrOff : public TcBase {
public:
TcDownlinkPwrOff(uint16_t sequenceCount) : TcBase(apid::TC_DOWNLINK_PWR_OFF, sequenceCount) {}
ReturnValue_t createPacket() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
this->setPacketDataLength(static_cast<uint16_t>(CRC_SIZE - 1));
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief This class helps to build the replay start command.
*/
class TcReplayWriteSeq : public TcBase {
public:
/**
* @brief Constructor
*/
TcReplayWriteSeq(uint16_t sequenceCount)
: TcBase(apid::TC_REPLAY_WRITE_SEQUENCE, sequenceCount) {}
protected:
ReturnValue_t initPacket(const uint8_t *commandData, size_t commandDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, commandDataLen);
*(this->localData.fields.buffer + commandDataLen) = NULL_TERMINATOR;
this->setPacketDataLength(commandDataLen + sizeof(NULL_TERMINATOR) + CRC_SIZE - 1);
return result;
}
private:
static const size_t USE_DECODING_LENGTH = 1;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen > USE_DECODING_LENGTH + MAX_FILENAME_SIZE) {
sif::warning << "TcReplayWriteSeq: Command has invalid length " << commandDataLen
<< std::endl;
return INVALID_LENGTH;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief Helps to extract the fields of the flash write command from the PUS packet.
*/
class FlashWritePusCmd : public MPSoCReturnValuesIF {
public:
FlashWritePusCmd(){};
ReturnValue_t extractFields(const uint8_t *commandData, size_t commandDataLen) {
if (commandDataLen > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE + MAX_FILENAME_SIZE)) {
return INVALID_LENGTH;
}
obcFile = std::string(reinterpret_cast<const char *>(commandData));
if (obcFile.size() > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE)) {
return FILENAME_TOO_LONG;
}
mpsocFile = std::string(
reinterpret_cast<const char *>(commandData + obcFile.size() + SIZE_NULL_TERMINATOR));
if (mpsocFile.size() > MAX_FILENAME_SIZE) {
return MPSOC_FILENAME_TOO_LONG;
}
return HasReturnvaluesIF::RETURN_OK;
}
std::string getObcFile() { return obcFile; }
std::string getMPSoCFile() { return mpsocFile; }
private:
static const size_t SIZE_NULL_TERMINATOR = 1;
std::string obcFile = "";
std::string mpsocFile = "";
};
/**
* @brief Class to build replay stop space packet.
*/
class TcModeReplay : public TcBase {
public:
TcModeReplay(uint16_t sequenceCount) : TcBase(apid::TC_MODE_REPLAY, sequenceCount) {}
ReturnValue_t createPacket() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
this->setPacketDataLength(static_cast<uint16_t>(CRC_SIZE - 1));
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief Class to build mode idle command
*/
class TcModeIdle : public TcBase {
public:
TcModeIdle(uint16_t sequenceCount) : TcBase(apid::TC_MODE_IDLE, sequenceCount) {}
ReturnValue_t createPacket() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
this->setPacketDataLength(static_cast<uint16_t>(CRC_SIZE - 1));
return HasReturnvaluesIF::RETURN_OK;
}
};
class TcCamcmdSend : public TcBase {
public:
TcCamcmdSend(uint16_t sequenceCount) : TcBase(apid::TC_CAM_CMD_SEND, sequenceCount) {}
protected:
ReturnValue_t initPacket(const uint8_t *commandData, size_t commandDataLen) {
if (commandDataLen > MAX_DATA_LENGTH) {
return INVALID_LENGTH;
}
uint16_t dataLen = static_cast<uint16_t>(commandDataLen + sizeof(CARRIAGE_RETURN));
size_t size = sizeof(dataLen);
SerializeAdapter::serialize(&dataLen, this->getPacketData(), &size, sizeof(dataLen),
SerializeIF::Endianness::BIG);
std::memcpy(this->getPacketData() + sizeof(dataLen), commandData, commandDataLen);
*(this->getPacketData() + sizeof(dataLen) + commandDataLen) = CARRIAGE_RETURN;
uint16_t trueLength = sizeof(dataLen) + commandDataLen + sizeof(CARRIAGE_RETURN) + CRC_SIZE;
this->setPacketDataLength(trueLength - 1);
return HasReturnvaluesIF::RETURN_OK;
}
private:
static const uint8_t MAX_DATA_LENGTH = 10;
static const uint8_t CARRIAGE_RETURN = 0xD;
};
} // namespace mpsoc
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCCOMMONDEFINITIONS_H_ */

View File

@ -1,271 +1,146 @@
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ #ifndef MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ #define MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/introspection/Enum.h>
#include "MPSoCReturnValuesIF.h" #include "MPSoCReturnValuesIF.h"
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "PlocMPSoCCommonDefinitions.h"
#include "eive/definitions.h" #include "eive/definitions.h"
#include "fsfw/globalfunctions/CRC.h" #include "fsfw/globalfunctions/CRC.h"
#include "fsfw/serialize/SerializeAdapter.h" #include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/tmtcpacket/SpacePacket.h" #include "fsfw/tmtcpacket/SpacePacket.h"
class PlocMPSoCHandler;
FSFW_ENUM(PlocMpSoCCommands, DeviceCommandId_t,
((NONE, 0, "No Command"))((TC_MEM_WRITE, 1, "Write to Memory"))(
(TC_MEM_READ, 2, "Read from Memory"))((ACK_REPORT, 3, ""))((EXE_REPORT, 5, ""))(
(TM_MEMORY_READ_REPORT, 6, ""))((TC_FLASHWRITE, 9, "Write Flash"))(
(TC_FLASHDELETE, 10, "Delete Flash"))((TC_REPLAY_START, 11, "Start Replay"))(
(TC_REPLAY_STOP, 12, "Stop Replay"))((TC_REPLAY_WRITE_SEQUENCE, 13,
"Write Sequence"))((TC_DOWNLINK_PWR_ON, 14,
"Set Downlink Power On"))(
(TC_DOWNLINK_PWR_OFF, 15, "Set Downlink Power Off"))((TC_MODE_REPLAY, 16,
"Set Replay Mode"))(
(TC_CAM_CMD_SEND, 17, "Set Replay Mode"))((TC_MODE_IDLE, 18, "Set Idle Mode"))(
(TM_CAM_CMD_RPT, 19, ""))((SET_UART_TX_TRISTATE, 20, "Set UART TX to Tristate"))(
(RELEASE_UART_TX, 21, "Release UART TX"))((OBSW_RESET_SEQ_COUNT, 50,
"Reset OBSW Reset Sequence Count")))
class PlocMpSoCMemWriteAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCMemWriteAction, PlocMpSoCCommands> {
public:
PlocMpSoCMemWriteAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_MEM_WRITE){};
Parameter<uint32_t> address = Parameter<uint32_t>::createParameter(this, "Memory Address");
Parameter<uint32_t> memoryData = Parameter<uint32_t>::createParameter(this, "Data to be written");
};
class PlocMpSoCMemReadAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCMemReadAction, PlocMpSoCCommands> {
public:
PlocMpSoCMemReadAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_MEM_READ){};
};
class PlocMpSoCFlashDeleteAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCFlashDeleteAction, PlocMpSoCCommands> {
public:
PlocMpSoCFlashDeleteAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_FLASHDELETE){};
};
class PlocMpSoCReplayStartAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCReplayStartAction, PlocMpSoCCommands> {
public:
PlocMpSoCReplayStartAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_REPLAY_START){};
};
class PlocMpSoCReplayStopAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCReplayStopAction, PlocMpSoCCommands> {
public:
PlocMpSoCReplayStopAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_REPLAY_STOP){};
};
class PlocMpSoCReplayWriteSequenceAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCReplayWriteSequenceAction,
PlocMpSoCCommands> {
public:
PlocMpSoCReplayWriteSequenceAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_REPLAY_WRITE_SEQUENCE){};
};
class PlocMpSoCDownlinkPwrOnAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCDownlinkPwrOnAction, PlocMpSoCCommands> {
public:
PlocMpSoCDownlinkPwrOnAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_DOWNLINK_PWR_ON){};
};
class PlocMpSoCDownlinkPwrOffAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCDownlinkPwrOffAction, PlocMpSoCCommands> {
public:
PlocMpSoCDownlinkPwrOffAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_DOWNLINK_PWR_OFF){};
};
class PlocMpSoCModeReplayAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCModeReplayAction, PlocMpSoCCommands> {
public:
PlocMpSoCModeReplayAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_MODE_REPLAY){};
};
class PlocMpSoCCamCmdSendAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCCamCmdSendAction, PlocMpSoCCommands> {
public:
PlocMpSoCCamCmdSendAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_CAM_CMD_SEND){};
};
class PlocMpSoCModeIdleAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCModeIdleAction, PlocMpSoCCommands> {
public:
PlocMpSoCModeIdleAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_MODE_IDLE){};
};
class PlocMpSoCFlashWriteAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCFlashWriteAction, PlocMpSoCCommands> {
public:
PlocMpSoCFlashWriteAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::TC_FLASHWRITE){};
};
class PlocMpSoCUartTxTristateAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCUartTxTristateAction, PlocMpSoCCommands> {
public:
PlocMpSoCUartTxTristateAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::SET_UART_TX_TRISTATE){};
};
class PlocMpSoCReleaseUartTxAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCReleaseUartTxAction, PlocMpSoCCommands> {
public:
PlocMpSoCReleaseUartTxAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::RELEASE_UART_TX){};
};
class PlocMpSoCObswResetSeqCountAction
: public TemplateAction<PlocMPSoCHandler, PlocMpSoCObswResetSeqCountAction, PlocMpSoCCommands> {
public:
PlocMpSoCObswResetSeqCountAction(PlocMPSoCHandler *owner)
: TemplateAction(owner, PlocMpSoCCommands::OBSW_RESET_SEQ_COUNT){};
};
namespace mpsoc { namespace mpsoc {
static const DeviceCommandId_t NONE = 0;
static const DeviceCommandId_t TC_MEM_WRITE = 1;
static const DeviceCommandId_t TC_MEM_READ = 2;
static const DeviceCommandId_t ACK_REPORT = 3;
static const DeviceCommandId_t EXE_REPORT = 5;
static const DeviceCommandId_t TM_MEMORY_READ_REPORT = 6;
static const DeviceCommandId_t TC_FLASHFOPEN = 7;
static const DeviceCommandId_t TC_FLASHFCLOSE = 8;
static const DeviceCommandId_t TC_FLASHWRITE = 9;
static const DeviceCommandId_t TC_FLASHDELETE = 10;
static const DeviceCommandId_t TC_REPLAY_START = 11;
static const DeviceCommandId_t TC_REPLAY_STOP = 12;
static const DeviceCommandId_t TC_REPLAY_WRITE_SEQUENCE = 13;
static const DeviceCommandId_t TC_DOWNLINK_PWR_ON = 14;
static const DeviceCommandId_t TC_DOWNLINK_PWR_OFF = 15;
static const DeviceCommandId_t TC_MODE_REPLAY = 16;
static const DeviceCommandId_t TC_CAM_CMD_SEND = 17;
static const DeviceCommandId_t TC_MODE_IDLE = 18;
static const DeviceCommandId_t TM_CAM_CMD_RPT = 19;
static const DeviceCommandId_t SET_UART_TX_TRISTATE = 20;
static const DeviceCommandId_t RELEASE_UART_TX = 21;
// Will reset the sequence count of the OBSW
static const DeviceCommandId_t OBSW_RESET_SEQ_COUNT = 50;
static const uint16_t SIZE_ACK_REPORT = 14;
static const uint16_t SIZE_EXE_REPORT = 14;
static const uint16_t SIZE_TM_MEM_READ_REPORT = 18;
static const uint16_t SIZE_TM_CAM_CMD_RPT = 18;
/**
* SpacePacket apids of PLOC telecommands and telemetry.
*/
namespace apid {
static const uint16_t TC_REPLAY_START = 0x110;
static const uint16_t TC_REPLAY_STOP = 0x111;
static const uint16_t TC_REPLAY_WRITE_SEQUENCE = 0x112;
static const uint16_t TC_DOWNLINK_PWR_ON = 0x113;
static const uint16_t TC_MEM_WRITE = 0x114;
static const uint16_t TC_MEM_READ = 0x115;
static const uint16_t TC_FLASHWRITE = 0x117;
static const uint16_t TC_FLASHFOPEN = 0x119;
static const uint16_t TC_FLASHFCLOSE = 0x11A;
static const uint16_t TC_FLASHDELETE = 0x11C;
static const uint16_t TC_MODE_REPLAY = 0x11F;
static const uint16_t TC_MODE_IDLE = 0x11E;
static const uint16_t TC_DOWNLINK_PWR_OFF = 0x124;
static const uint16_t TC_CAM_CMD_SEND = 0x12C;
static const uint16_t TM_MEMORY_READ_REPORT = 0x404;
static const uint16_t ACK_SUCCESS = 0x400;
static const uint16_t ACK_FAILURE = 0x401;
static const uint16_t EXE_SUCCESS = 0x402;
static const uint16_t EXE_FAILURE = 0x403;
static const uint16_t TM_CAM_CMD_RPT = 0x407;
} // namespace apid
/** Offset from first byte in space packet to first byte of data field */
static const uint8_t DATA_FIELD_OFFSET = 6;
static const size_t MEM_READ_RPT_LEN_OFFSET = 10;
static const char NULL_TERMINATOR = '\0';
static const uint8_t MIN_SPACE_PACKET_LENGTH = 7;
static const uint8_t SPACE_PACKET_HEADER_SIZE = 6;
/**
* The size of payload data which will be forwarded to the requesting object. e.g. PUS Service
* 8.
*/
static const uint8_t SIZE_MEM_READ_RPT_FIX = 6;
static const size_t MAX_FILENAME_SIZE = 256;
/**
* PLOC space packet length for fixed size packets. This is the size of the whole packet data
* field. For the length field in the space packet this size will be substracted by one.
*/
static const uint16_t LENGTH_TC_MEM_WRITE = 12;
static const uint16_t LENGTH_TC_MEM_READ = 8;
static const size_t MAX_REPLY_SIZE = SpacePacket::PACKET_MAX_SIZE * 3;
static const size_t MAX_COMMAND_SIZE = SpacePacket::PACKET_MAX_SIZE;
static const size_t MAX_DATA_SIZE = 1016;
/**
* The replay write sequence command has a maximum delay for the execution report which amounts to
* 30 seconds. (80 cycles * 0.5 seconds = 40 seconds).
*/
static const uint16_t TC_WRITE_SEQ_EXECUTION_DELAY = 80;
// Requires approx. 2 seconds for execution. 8 => 4 seconds
static const uint16_t TC_DOWNLINK_PWR_ON_EXECUTION_DELAY = 8;
namespace status_code {
static const uint16_t UNKNOWN_APID = 0x5DD;
static const uint16_t INCORRECT_LENGTH = 0x5DE;
static const uint16_t INCORRECT_CRC = 0x5DF;
static const uint16_t INCORRECT_PKT_SEQ_CNT = 0x5E0;
static const uint16_t TC_NOT_ALLOWED_IN_MODE = 0x5E1;
static const uint16_t TC_EXEUTION_DISABLED = 0x5E2;
static const uint16_t FLASH_MOUNT_FAILED = 0x5E3;
static const uint16_t FLASH_FILE_ALREADY_CLOSED = 0x5E4;
static const uint16_t FLASH_FILE_OPEN_FAILED = 0x5E5;
static const uint16_t FLASH_FILE_ALREDY_OPEN = 0x5E6;
static const uint16_t FLASH_FILE_NOT_OPEN = 0x5E7;
static const uint16_t FLASH_UNMOUNT_FAILED = 0x5E8;
static const uint16_t HEAP_ALLOCATION_FAILED = 0x5E9;
static const uint16_t INVALID_PARAMETER = 0x5EA;
static const uint16_t NOT_INITIALIZED = 0x5EB;
static const uint16_t REBOOT_IMMINENT = 0x5EC;
static const uint16_t CORRUPT_DATA = 0x5ED;
static const uint16_t FLASH_CORRECTABLE_MISMATCH = 0x5EE;
static const uint16_t FLASH_UNCORRECTABLE_MISMATCH = 0x5EF;
static const uint16_t RESERVED_0 = 0x5F0;
static const uint16_t RESERVED_1 = 0x5F1;
static const uint16_t RESERVED_2 = 0x5F2;
static const uint16_t RESERVED_3 = 0x5F3;
static const uint16_t RESERVED_4 = 0x5F4;
} // namespace status_code
/**
* @brief Abstract base class for TC space packet of MPSoC.
*/
class TcBase : public SpacePacket, public MPSoCReturnValuesIF {
public:
// Initial length field of space packet. Will always be updated when packet is created.
static const uint16_t INIT_LENGTH = 1;
/**
* @brief Constructor
*
* @param sequenceCount Sequence count of space packet which will be incremented with each
* sent and received packets.
*/
TcBase(uint16_t apid, uint16_t sequenceCount)
: SpacePacket(INIT_LENGTH, true, apid, sequenceCount) {}
/**
* @brief Function to initialize the space packet
*
* @param commandData Pointer to command specific data
* @param commandDataLen Length of command data
*
* @return RETURN_OK if packet creation was successful, otherwise error return value
*/
virtual ReturnValue_t createPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = initPacket(commandData, commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
protected:
/**
* @brief Must be overwritten by the child class to define the command specific parameters
*
* @param commandData Pointer to received command data
* @param commandDataLen Length of received command data
*/
virtual ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
return HasReturnvaluesIF::RETURN_OK;
}
/**
* @brief Calculates and adds the CRC
*/
ReturnValue_t addCrc() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
size_t serializedSize = 0;
uint32_t full_size = getFullSize();
uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE);
result = SerializeAdapter::serialize<uint16_t>(
&crc, this->localData.byteStream + full_size - CRC_SIZE, &serializedSize, sizeof(crc),
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::debug << "TcBase::addCrc: Failed to serialize crc field" << std::endl;
}
return result;
}
};
/**
* @brief Class for handling tm replies of the PLOC MPSoC.
*/
class TmPacket : public SpacePacket, public MPSoCReturnValuesIF {
public:
/**
* @brief Constructor creates idle packet and sets length field to maximum allowed size.
*/
TmPacket() : SpacePacket(PACKET_MAX_SIZE) {}
ReturnValue_t checkCrc() {
uint8_t* crcPtr = this->getPacketData() + this->getPacketDataLength() - 1;
uint16_t receivedCrc = *(crcPtr) << 8 | *(crcPtr + 1);
uint16_t recalculatedCrc =
CRC::crc16ccitt(this->localData.byteStream, this->getFullSize() - CRC_SIZE);
if (recalculatedCrc != receivedCrc) {
return CRC_FAILURE;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief This class helps to build the memory read command for the PLOC.
*/
class TcMemRead : public TcBase {
public:
/**
* @brief Constructor
*/
TcMemRead(uint16_t sequenceCount) : TcBase(apid::TC_MEM_READ, sequenceCount) {
this->setPacketDataLength(PACKET_LENGTH);
}
uint16_t getMemLen() const { return memLen; }
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, MEM_ADDRESS_SIZE);
std::memcpy(this->localData.fields.buffer + MEM_ADDRESS_SIZE, commandData + MEM_ADDRESS_SIZE,
MEM_LEN_SIZE);
size_t size = sizeof(memLen);
const uint8_t* memLenPtr = commandData + MEM_ADDRESS_SIZE;
result =
SerializeAdapter::deSerialize(&memLen, &memLenPtr, &size, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
private:
static const size_t COMMAND_LENGTH = 6;
static const size_t MEM_ADDRESS_SIZE = 4;
static const size_t MEM_LEN_SIZE = 2;
static const uint16_t PACKET_LENGTH = 7;
uint16_t memLen = 0;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen != COMMAND_LENGTH) {
return INVALID_LENGTH;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/** /**
* @brief This class helps to generate the space packet to write data to a memory address within * @brief This class helps to generate the space packet to write data to a memory address within
* the PLOC. * the PLOC.
@ -278,23 +153,31 @@ class TcMemWrite : public TcBase {
TcMemWrite(uint16_t sequenceCount) : TcBase(apid::TC_MEM_WRITE, sequenceCount) {} TcMemWrite(uint16_t sequenceCount) : TcBase(apid::TC_MEM_WRITE, sequenceCount) {}
protected: protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) { ReturnValue_t initPacket(void *actionIn) {
auto action = (PlocMpSoCMemWriteAction *)(actionIn); //TODO
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = lengthCheck(commandDataLen); // faking until framework code is ready
// uint16_t length = action->memoryData.length;
uint16_t dataLength = 1;
result = lengthCheck(dataLength);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
std::memcpy(this->localData.fields.buffer, commandData, commandDataLen); uint8_t *pointer = this->localData.fields.buffer;
uint16_t memLen = size_t size = 0;
*(commandData + MEM_ADDRESS_SIZE) << 8 | *(commandData + MEM_ADDRESS_SIZE + 1); size_t maxSize = PACKET_MAX_SIZE;
this->setPacketDataLength(memLen * 4 + FIX_LENGTH - 1); SerializeAdapter::serialize(&action->address.value, &pointer, &size, maxSize,
SerializeIF::Endianness::BIG);
SerializeAdapter::serialize(&dataLength, &pointer, &size, maxSize,
SerializeIF::Endianness::BIG);
std::memcpy(pointer, &action->memoryData.value, dataLength);
this->setPacketDataLength(dataLength * sizeof(action->memoryData.value) + FIX_LENGTH - 1);
return result; return result;
} }
private: private:
// Min length consists of 4 byte address, 2 byte mem length field, 4 byte data (1 word) // Min length consists of 4 byte data (1 word)
static const size_t MIN_COMMAND_DATA_LENGTH = 10; static const size_t MIN_COMMAND_DATA_LENGTH = 1;
static const size_t MEM_ADDRESS_SIZE = 4;
static const size_t FIX_LENGTH = 8; static const size_t FIX_LENGTH = 8;
ReturnValue_t lengthCheck(size_t commandDataLen) { ReturnValue_t lengthCheck(size_t commandDataLen) {
@ -305,400 +188,5 @@ class TcMemWrite : public TcBase {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
}; };
/**
* @brief Class to help creation of flash fopen command.
*/
class FlashFopen : public TcBase {
public:
FlashFopen(uint16_t sequenceCount) : TcBase(apid::TC_FLASHFOPEN, sequenceCount) {}
static const char APPEND = 'a';
static const char WRITE = 'w';
static const char READ = 'r';
ReturnValue_t createPacket(std::string filename, char accessMode_) {
accessMode = accessMode_;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
size_t nameSize = filename.size();
std::memcpy(this->getPacketData(), filename.c_str(), nameSize);
*(this->getPacketData() + nameSize) = NULL_TERMINATOR;
std::memcpy(this->getPacketData() + nameSize + sizeof(NULL_TERMINATOR), &accessMode,
sizeof(accessMode));
this->setPacketDataLength(nameSize + sizeof(NULL_TERMINATOR) + sizeof(accessMode) + CRC_SIZE -
1);
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
private:
char accessMode = APPEND;
};
/**
* @brief Class to help creation of flash fclose command.
*/
class FlashFclose : public TcBase {
public:
FlashFclose(uint16_t sequenceCount) : TcBase(apid::TC_FLASHFCLOSE, sequenceCount) {}
ReturnValue_t createPacket(std::string filename) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
size_t nameSize = filename.size();
std::memcpy(this->getPacketData(), filename.c_str(), nameSize);
*(this->getPacketData() + nameSize) = NULL_TERMINATOR;
this->setPacketDataLength(nameSize + sizeof(NULL_TERMINATOR) + CRC_SIZE - 1);
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
};
/**
* @brief Class to build flash write space packet.
*/
class TcFlashWrite : public TcBase {
public:
TcFlashWrite(uint16_t sequenceCount) : TcBase(apid::TC_FLASHWRITE, sequenceCount) {}
ReturnValue_t createPacket(const uint8_t* writeData, uint32_t writeLen_) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
writeLen = writeLen_;
if (writeLen > MAX_DATA_SIZE) {
sif::debug << "FlashWrite::createPacket: Command data too big" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
size_t serializedSize = 0;
result =
SerializeAdapter::serialize<uint32_t>(&writeLen, this->getPacketData(), &serializedSize,
sizeof(writeLen), SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->getPacketData() + sizeof(writeLen), writeData, writeLen);
this->setPacketDataLength(static_cast<uint16_t>(writeLen + CRC_SIZE - 1));
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return HasReturnvaluesIF::RETURN_OK;
}
private:
uint32_t writeLen = 0;
};
/**
* @brief Class to help creation of flash delete command.
*/
class TcFlashDelete : public TcBase {
public:
TcFlashDelete(uint16_t sequenceCount) : TcBase(apid::TC_FLASHDELETE, sequenceCount) {}
ReturnValue_t createPacket(std::string filename) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
size_t nameSize = filename.size();
std::memcpy(this->getPacketData(), filename.c_str(), nameSize);
*(this->getPacketData() + nameSize) = NULL_TERMINATOR;
this->setPacketDataLength(nameSize + sizeof(NULL_TERMINATOR) + CRC_SIZE - 1);
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
};
/**
* @brief Class to build replay stop space packet.
*/
class TcReplayStop : public TcBase {
public:
TcReplayStop(uint16_t sequenceCount) : TcBase(apid::TC_REPLAY_STOP, sequenceCount) {}
ReturnValue_t createPacket() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
this->setPacketDataLength(static_cast<uint16_t>(CRC_SIZE - 1));
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief This class helps to build the replay start command.
*/
class TcReplayStart : public TcBase {
public:
/**
* @brief Constructor
*/
TcReplayStart(uint16_t sequenceCount) : TcBase(apid::TC_REPLAY_START, sequenceCount) {}
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = checkData(*commandData);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, commandDataLen);
this->setPacketDataLength(commandDataLen + CRC_SIZE - 1);
return result;
}
private:
static const size_t COMMAND_DATA_LENGTH = 1;
static const uint8_t REPEATING = 0;
static const uint8_t ONCE = 1;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen != COMMAND_DATA_LENGTH) {
sif::warning << "TcReplayStart: Command has invalid length " << commandDataLen << std::endl;
return INVALID_LENGTH;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t checkData(uint8_t replay) {
if (replay != REPEATING && replay != ONCE) {
sif::warning << "TcReplayStart::checkData: Invalid replay value" << std::endl;
return INVALID_PARAMETER;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief This class helps to build downlink power on command.
*/
class TcDownlinkPwrOn : public TcBase {
public:
/**
* @brief Constructor
*/
TcDownlinkPwrOn(uint16_t sequenceCount) : TcBase(apid::TC_DOWNLINK_PWR_ON, sequenceCount) {}
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = modeCheck(*commandData);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = laneRateCheck(*(commandData + 1));
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, commandDataLen);
std::memcpy(this->localData.fields.buffer + commandDataLen, &MAX_AMPLITUDE,
sizeof(MAX_AMPLITUDE));
this->setPacketDataLength(commandDataLen + sizeof(MAX_AMPLITUDE) + CRC_SIZE - 1);
return result;
}
private:
static const uint8_t INTERFACE_ID = CLASS_ID::DWLPWRON_CMD;
//! [EXPORT] : [COMMENT] Received command has invalid JESD mode (valid modes are 0 - 5)
static const ReturnValue_t INVALID_MODE = MAKE_RETURN_CODE(0xE0);
//! [EXPORT] : [COMMENT] Received command has invalid lane rate (valid lane rate are 0 - 9)
static const ReturnValue_t INVALID_LANE_RATE = MAKE_RETURN_CODE(0xE1);
static const size_t COMMAND_DATA_LENGTH = 2;
static const uint8_t MAX_MODE = 5;
static const uint8_t MAX_LANE_RATE = 9;
static const uint16_t MAX_AMPLITUDE = 0;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen != COMMAND_DATA_LENGTH) {
sif::warning << "TcDownlinkPwrOn: Command has invalid length " << commandDataLen << std::endl;
return INVALID_LENGTH;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t modeCheck(uint8_t mode) {
if (mode > MAX_MODE) {
sif::warning << "TcDwonlinkPwrOn::modeCheck: Invalid JESD mode" << std::endl;
return INVALID_MODE;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t laneRateCheck(uint8_t laneRate) {
if (laneRate > MAX_LANE_RATE) {
sif::warning << "TcReplayStart::laneRateCheck: Invalid lane rate" << std::endl;
return INVALID_LANE_RATE;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief Class to build replay stop space packet.
*/
class TcDownlinkPwrOff : public TcBase {
public:
TcDownlinkPwrOff(uint16_t sequenceCount) : TcBase(apid::TC_DOWNLINK_PWR_OFF, sequenceCount) {}
ReturnValue_t createPacket() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
this->setPacketDataLength(static_cast<uint16_t>(CRC_SIZE - 1));
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief This class helps to build the replay start command.
*/
class TcReplayWriteSeq : public TcBase {
public:
/**
* @brief Constructor
*/
TcReplayWriteSeq(uint16_t sequenceCount)
: TcBase(apid::TC_REPLAY_WRITE_SEQUENCE, sequenceCount) {}
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = lengthCheck(commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
std::memcpy(this->localData.fields.buffer, commandData, commandDataLen);
*(this->localData.fields.buffer + commandDataLen) = NULL_TERMINATOR;
this->setPacketDataLength(commandDataLen + sizeof(NULL_TERMINATOR) + CRC_SIZE - 1);
return result;
}
private:
static const size_t USE_DECODING_LENGTH = 1;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen > USE_DECODING_LENGTH + MAX_FILENAME_SIZE) {
sif::warning << "TcReplayWriteSeq: Command has invalid length " << commandDataLen
<< std::endl;
return INVALID_LENGTH;
}
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief Helps to extract the fields of the flash write command from the PUS packet.
*/
class FlashWritePusCmd : public MPSoCReturnValuesIF {
public:
FlashWritePusCmd(){};
ReturnValue_t extractFields(const uint8_t* commandData, size_t commandDataLen) {
if (commandDataLen > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE + MAX_FILENAME_SIZE)) {
return INVALID_LENGTH;
}
obcFile = std::string(reinterpret_cast<const char*>(commandData));
if (obcFile.size() > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE)) {
return FILENAME_TOO_LONG;
}
mpsocFile = std::string(
reinterpret_cast<const char*>(commandData + obcFile.size() + SIZE_NULL_TERMINATOR));
if (mpsocFile.size() > MAX_FILENAME_SIZE) {
return MPSOC_FILENAME_TOO_LONG;
}
return HasReturnvaluesIF::RETURN_OK;
}
std::string getObcFile() { return obcFile; }
std::string getMPSoCFile() { return mpsocFile; }
private:
static const size_t SIZE_NULL_TERMINATOR = 1;
std::string obcFile = "";
std::string mpsocFile = "";
};
/**
* @brief Class to build replay stop space packet.
*/
class TcModeReplay : public TcBase {
public:
TcModeReplay(uint16_t sequenceCount) : TcBase(apid::TC_MODE_REPLAY, sequenceCount) {}
ReturnValue_t createPacket() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
this->setPacketDataLength(static_cast<uint16_t>(CRC_SIZE - 1));
return HasReturnvaluesIF::RETURN_OK;
}
};
/**
* @brief Class to build mode idle command
*/
class TcModeIdle : public TcBase {
public:
TcModeIdle(uint16_t sequenceCount) : TcBase(apid::TC_MODE_IDLE, sequenceCount) {}
ReturnValue_t createPacket() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
result = addCrc();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
this->setPacketDataLength(static_cast<uint16_t>(CRC_SIZE - 1));
return HasReturnvaluesIF::RETURN_OK;
}
};
class TcCamcmdSend : public TcBase {
public:
TcCamcmdSend(uint16_t sequenceCount) : TcBase(apid::TC_CAM_CMD_SEND, sequenceCount) {}
protected:
ReturnValue_t initPacket(const uint8_t* commandData, size_t commandDataLen) {
if (commandDataLen > MAX_DATA_LENGTH) {
return INVALID_LENGTH;
}
uint16_t dataLen = static_cast<uint16_t>(commandDataLen + sizeof(CARRIAGE_RETURN));
size_t size = sizeof(dataLen);
SerializeAdapter::serialize(&dataLen, this->getPacketData(), &size, sizeof(dataLen),
SerializeIF::Endianness::BIG);
std::memcpy(this->getPacketData() + sizeof(dataLen), commandData, commandDataLen);
*(this->getPacketData() + sizeof(dataLen) + commandDataLen) = CARRIAGE_RETURN;
uint16_t trueLength = sizeof(dataLen) + commandDataLen + sizeof(CARRIAGE_RETURN) + CRC_SIZE;
this->setPacketDataLength(trueLength - 1);
return HasReturnvaluesIF::RETURN_OK;
}
private:
static const uint8_t MAX_DATA_LENGTH = 10;
static const uint8_t CARRIAGE_RETURN = 0xD;
};
} // namespace mpsoc } // namespace mpsoc
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ */ #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_PLOCMPSOCDEFINITIONS_H_ */

View File

@ -0,0 +1,20 @@
#pragma once
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/introspection/Enum.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
class PlocMemoryDumper;
FSFW_ENUM(PlocMemoryDumperCommands, DeviceCommandId_t,
((DUMP_MRAM, 1 ,"Dump Memory")))
class DumpMemoryAction : public TemplateAction<PlocMemoryDumper, DumpMemoryAction, PlocMemoryDumperCommands> {
public:
DumpMemoryAction(PlocMemoryDumper * owner): TemplateAction(owner, PlocMemoryDumperCommands::DUMP_MRAM) {}
//Memory is 512KiB
MinMaxParameter<uint32_t> startAddress = MinMaxParameter<uint32_t>::createMinMaxParameter(this, "Start Address", 0 , 0x80000);
MinMaxParameter<uint32_t> endAddress = MinMaxParameter<uint32_t>::createMinMaxParameter(this, "End Address", 0 , 0x80000);
};

View File

@ -5,6 +5,8 @@
#include "fsfw/globalfunctions/CRC.h" #include "fsfw/globalfunctions/CRC.h"
#include "linux/devices/devicedefinitions/PlocSupervisorDefinitions.h" #include "linux/devices/devicedefinitions/PlocSupervisorDefinitions.h"
// TODO this is work in progress in adapting to new actions
PlocMPSoCHandler::PlocMPSoCHandler(object_id_t objectId, object_id_t uartComIFid, PlocMPSoCHandler::PlocMPSoCHandler(object_id_t objectId, object_id_t uartComIFid,
CookieIF* comCookie, PlocMPSoCHelper* plocMPSoCHelper, CookieIF* comCookie, PlocMPSoCHelper* plocMPSoCHelper,
Gpio uartIsolatorSwitch, object_id_t supervisorHandler) Gpio uartIsolatorSwitch, object_id_t supervisorHandler)
@ -96,16 +98,14 @@ void PlocMPSoCHandler::performOperationHook() {
} }
} }
ReturnValue_t PlocMPSoCHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t PlocMPSoCHandler::executeAction(Action* action) {
const uint8_t* data, size_t size) { switch (PlocMpSoCCommands(action->getId())) {
ReturnValue_t result = RETURN_OK; case PlocMpSoCCommands::SET_UART_TX_TRISTATE: {
switch (actionId) {
case mpsoc::SET_UART_TX_TRISTATE: {
uartIsolatorSwitch.pullLow(); uartIsolatorSwitch.pullLow();
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
break; break;
} }
case mpsoc::RELEASE_UART_TX: { case PlocMpSoCCommands::RELEASE_UART_TX: {
uartIsolatorSwitch.pullHigh(); uartIsolatorSwitch.pullHigh();
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
break; break;
@ -118,32 +118,28 @@ ReturnValue_t PlocMPSoCHandler::executeAction(ActionId_t actionId, MessageQueueI
return MPSoCReturnValuesIF::MPSOC_HELPER_EXECUTING; return MPSoCReturnValuesIF::MPSOC_HELPER_EXECUTING;
} }
switch (actionId) { switch (PlocMpSoCCommands(action->getId())) {
case mpsoc::TC_FLASHWRITE: { case PlocMpSoCCommands::TC_FLASHWRITE: {
if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) { // refer handling to the handleAction() below
return MPSoCReturnValuesIF::FILENAME_TOO_LONG; return action->handle();
}
mpsoc::FlashWritePusCmd flashWritePusCmd;
result = flashWritePusCmd.extractFields(data, size);
if (result != RETURN_OK) {
return result;
}
result = plocMPSoCHelper->startFlashWrite(flashWritePusCmd.getObcFile(),
flashWritePusCmd.getMPSoCFile());
if (result != RETURN_OK) {
return result;
}
plocMPSoCHelperExecuting = true;
return EXECUTION_FINISHED;
} }
case (mpsoc::OBSW_RESET_SEQ_COUNT): { case (PlocMpSoCCommands::OBSW_RESET_SEQ_COUNT): {
sequenceCount = 0; sequenceCount = 0;
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
default: default:
break; break;
} }
return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); ReturnValue_t result = DeviceHandlerBase::executeAction(action);
if (result == RETURN_OK) {
/**
* Flushing the receive buffer to make sure there are no data left from a faulty reply.
*/
uartComIf->flushUartRxBuffer(comCookie);
}
return result;
} }
void PlocMPSoCHandler::doStartUp() { void PlocMPSoCHandler::doStartUp() {
@ -203,90 +199,29 @@ ReturnValue_t PlocMPSoCHandler::buildTransitionDeviceCommand(DeviceCommandId_t*
return NOTHING_TO_SEND; return NOTHING_TO_SEND;
} }
ReturnValue_t PlocMPSoCHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData,
size_t commandDataLen) {
ReturnValue_t result = RETURN_OK;
switch (deviceCommand) {
case (mpsoc::TC_MEM_WRITE): {
result = prepareTcMemWrite(commandData, commandDataLen);
break;
}
case (mpsoc::TC_MEM_READ): {
result = prepareTcMemRead(commandData, commandDataLen);
break;
}
case (mpsoc::TC_FLASHDELETE): {
result = prepareTcFlashDelete(commandData, commandDataLen);
break;
}
case (mpsoc::TC_REPLAY_START): {
result = prepareTcReplayStart(commandData, commandDataLen);
break;
}
case (mpsoc::TC_REPLAY_STOP): {
result = prepareTcReplayStop();
break;
}
case (mpsoc::TC_DOWNLINK_PWR_ON): {
result = prepareTcDownlinkPwrOn(commandData, commandDataLen);
break;
}
case (mpsoc::TC_DOWNLINK_PWR_OFF): {
result = prepareTcDownlinkPwrOff();
break;
}
case (mpsoc::TC_REPLAY_WRITE_SEQUENCE): {
result = prepareTcReplayWriteSequence(commandData, commandDataLen);
break;
}
case (mpsoc::TC_MODE_REPLAY): {
result = prepareTcModeReplay();
break;
}
case (mpsoc::TC_MODE_IDLE): {
result = prepareTcModeIdle();
break;
}
case (mpsoc::TC_CAM_CMD_SEND): {
result = prepareTcCamCmdSend(commandData, commandDataLen);
break;
}
default:
sif::debug << "PlocMPSoCHandler::buildCommandFromCommand: Command not implemented"
<< std::endl;
result = DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
break;
}
if (result == RETURN_OK) {
/**
* Flushing the receive buffer to make sure there are no data left from a faulty reply.
*/
uartComIf->flushUartRxBuffer(comCookie);
}
return result;
}
void PlocMPSoCHandler::fillCommandAndReplyMap() { void PlocMPSoCHandler::fillCommandAndReplyMap() {
this->insertInCommandMap(mpsoc::TC_MEM_WRITE); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_MEM_WRITE));
this->insertInCommandMap(mpsoc::TC_MEM_READ); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_MEM_READ));
this->insertInCommandMap(mpsoc::TC_FLASHDELETE); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_FLASHDELETE));
this->insertInCommandMap(mpsoc::TC_REPLAY_START); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_REPLAY_START));
this->insertInCommandMap(mpsoc::TC_REPLAY_STOP); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_REPLAY_STOP));
this->insertInCommandMap(mpsoc::TC_DOWNLINK_PWR_ON); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_DOWNLINK_PWR_ON));
this->insertInCommandMap(mpsoc::TC_DOWNLINK_PWR_OFF); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_DOWNLINK_PWR_OFF));
this->insertInCommandMap(mpsoc::TC_REPLAY_WRITE_SEQUENCE); this->insertInCommandMap(
this->insertInCommandMap(mpsoc::TC_MODE_REPLAY); static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_REPLAY_WRITE_SEQUENCE));
this->insertInCommandMap(mpsoc::TC_MODE_IDLE); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_MODE_REPLAY));
this->insertInCommandMap(mpsoc::TC_CAM_CMD_SEND); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_MODE_IDLE));
this->insertInCommandMap(mpsoc::RELEASE_UART_TX); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TC_CAM_CMD_SEND));
this->insertInCommandMap(mpsoc::SET_UART_TX_TRISTATE); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::RELEASE_UART_TX));
this->insertInReplyMap(mpsoc::ACK_REPORT, 3, nullptr, mpsoc::SIZE_ACK_REPORT); this->insertInCommandMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::SET_UART_TX_TRISTATE));
this->insertInReplyMap(mpsoc::EXE_REPORT, 3, nullptr, mpsoc::SIZE_EXE_REPORT); this->insertInReplyMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::ACK_REPORT), 3, nullptr,
this->insertInReplyMap(mpsoc::TM_MEMORY_READ_REPORT, 2, nullptr, mpsoc::SIZE_TM_MEM_READ_REPORT); mpsoc::SIZE_ACK_REPORT);
this->insertInReplyMap(mpsoc::TM_CAM_CMD_RPT, 2, nullptr, SpacePacket::PACKET_MAX_SIZE); this->insertInReplyMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::EXE_REPORT), 3, nullptr,
mpsoc::SIZE_EXE_REPORT);
this->insertInReplyMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_MEMORY_READ_REPORT),
2, nullptr, mpsoc::SIZE_TM_MEM_READ_REPORT);
this->insertInReplyMap(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_CAM_CMD_RPT), 2,
nullptr, SpacePacket::PACKET_MAX_SIZE);
} }
ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t* start, size_t remainingSize, ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t* start, size_t remainingSize,
@ -300,28 +235,28 @@ ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t* start, size_t remain
switch (apid) { switch (apid) {
case (mpsoc::apid::ACK_SUCCESS): case (mpsoc::apid::ACK_SUCCESS):
*foundLen = mpsoc::SIZE_ACK_REPORT; *foundLen = mpsoc::SIZE_ACK_REPORT;
*foundId = mpsoc::ACK_REPORT; *foundId = static_cast<DeviceCommandId_t>(PlocMpSoCCommands::ACK_REPORT);
break; break;
case (mpsoc::apid::ACK_FAILURE): case (mpsoc::apid::ACK_FAILURE):
*foundLen = mpsoc::SIZE_ACK_REPORT; *foundLen = mpsoc::SIZE_ACK_REPORT;
*foundId = mpsoc::ACK_REPORT; *foundId = static_cast<DeviceCommandId_t>(PlocMpSoCCommands::ACK_REPORT);
break; break;
case (mpsoc::apid::TM_MEMORY_READ_REPORT): case (mpsoc::apid::TM_MEMORY_READ_REPORT):
*foundLen = tmMemReadReport.rememberRequestedSize; *foundLen = tmMemReadReport.rememberRequestedSize;
*foundId = mpsoc::TM_MEMORY_READ_REPORT; *foundId = static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_MEMORY_READ_REPORT);
break; break;
case (mpsoc::apid::TM_CAM_CMD_RPT): case (mpsoc::apid::TM_CAM_CMD_RPT):
*foundLen = spacePacket.getFullSize(); *foundLen = spacePacket.getFullSize();
tmCamCmdRpt.rememberSpacePacketSize = *foundLen; tmCamCmdRpt.rememberSpacePacketSize = *foundLen;
*foundId = mpsoc::TM_CAM_CMD_RPT; *foundId = static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_CAM_CMD_RPT);
break; break;
case (mpsoc::apid::EXE_SUCCESS): case (mpsoc::apid::EXE_SUCCESS):
*foundLen = mpsoc::SIZE_EXE_REPORT; *foundLen = mpsoc::SIZE_EXE_REPORT;
*foundId = mpsoc::EXE_REPORT; *foundId = static_cast<DeviceCommandId_t>(PlocMpSoCCommands::EXE_REPORT);
break; break;
case (mpsoc::apid::EXE_FAILURE): case (mpsoc::apid::EXE_FAILURE):
*foundLen = mpsoc::SIZE_EXE_REPORT; *foundLen = mpsoc::SIZE_EXE_REPORT;
*foundId = mpsoc::EXE_REPORT; *foundId = static_cast<DeviceCommandId_t>(PlocMpSoCCommands::EXE_REPORT);
break; break;
default: { default: {
sif::debug << "PlocMPSoCHandler::scanForReply: Reply has invalid apid" << std::endl; sif::debug << "PlocMPSoCHandler::scanForReply: Reply has invalid apid" << std::endl;
@ -342,20 +277,22 @@ ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t* start, size_t remain
ReturnValue_t PlocMPSoCHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) { ReturnValue_t PlocMPSoCHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
switch (id) { PlocMpSoCCommands enumId = PlocMpSoCCommands(id);
case mpsoc::ACK_REPORT: {
switch (enumId) {
case PlocMpSoCCommands::ACK_REPORT: {
result = handleAckReport(packet); result = handleAckReport(packet);
break; break;
} }
case (mpsoc::TM_MEMORY_READ_REPORT): { case (PlocMpSoCCommands::TM_MEMORY_READ_REPORT): {
result = handleMemoryReadReport(packet); result = handleMemoryReadReport(packet);
break; break;
} }
case (mpsoc::TM_CAM_CMD_RPT): { case (PlocMpSoCCommands::TM_CAM_CMD_RPT): {
result = handleCamCmdRpt(packet); result = handleCamCmdRpt(packet);
break; break;
} }
case (mpsoc::EXE_REPORT): { case (PlocMpSoCCommands::EXE_REPORT): {
result = handleExecutionReport(packet); result = handleExecutionReport(packet);
break; break;
} }
@ -390,12 +327,17 @@ void PlocMPSoCHandler::handleEvent(EventMessage* eventMessage) {
} }
} }
ReturnValue_t PlocMPSoCHandler::prepareTcMemWrite(const uint8_t* commandData, ReturnValue_t PlocMPSoCHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
size_t commandDataLen) { const uint8_t* commandData,
size_t commandDataLen) {
return NOTHING_TO_SEND;
}
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCMemWriteAction* action) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcMemWrite tcMemWrite(sequenceCount); mpsoc::TcMemWrite tcMemWrite(sequenceCount);
result = tcMemWrite.createPacket(commandData, commandDataLen); result = tcMemWrite.createPacket(action);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sequenceCount--; sequenceCount--;
return result; return result;
@ -403,13 +345,11 @@ ReturnValue_t PlocMPSoCHandler::prepareTcMemWrite(const uint8_t* commandData,
copyToCommandBuffer(&tcMemWrite); copyToCommandBuffer(&tcMemWrite);
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCMemReadAction* action) {
ReturnValue_t PlocMPSoCHandler::prepareTcMemRead(const uint8_t* commandData,
size_t commandDataLen) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcMemRead tcMemRead(sequenceCount); mpsoc::TcMemRead tcMemRead(sequenceCount);
result = tcMemRead.createPacket(commandData, commandDataLen); // result = tcMemRead.createPacket(commandData, commandDataLen);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sequenceCount--; sequenceCount--;
return result; return result;
@ -418,17 +358,15 @@ ReturnValue_t PlocMPSoCHandler::prepareTcMemRead(const uint8_t* commandData,
tmMemReadReport.rememberRequestedSize = tcMemRead.getMemLen() * 4 + TmMemReadReport::FIX_SIZE; tmMemReadReport.rememberRequestedSize = tcMemRead.getMemLen() * 4 + TmMemReadReport::FIX_SIZE;
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCFlashDeleteAction* action) {
ReturnValue_t PlocMPSoCHandler::prepareTcFlashDelete(const uint8_t* commandData, // if (commandDataLen > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) {
size_t commandDataLen) { // return MPSoCReturnValuesIF::NAME_TOO_LONG;
if (commandDataLen > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) { // }
return MPSoCReturnValuesIF::NAME_TOO_LONG;
}
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcFlashDelete tcFlashDelete(sequenceCount); mpsoc::TcFlashDelete tcFlashDelete(sequenceCount);
result = tcFlashDelete.createPacket( // result = tcFlashDelete.createPacket(
std::string(reinterpret_cast<const char*>(commandData), commandDataLen)); // std::string(reinterpret_cast<const char*>(commandData), commandDataLen));
if (result != RETURN_OK) { if (result != RETURN_OK) {
sequenceCount--; sequenceCount--;
return result; return result;
@ -436,13 +374,11 @@ ReturnValue_t PlocMPSoCHandler::prepareTcFlashDelete(const uint8_t* commandData,
copyToCommandBuffer(&tcFlashDelete); copyToCommandBuffer(&tcFlashDelete);
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCReplayStartAction* action) {
ReturnValue_t PlocMPSoCHandler::prepareTcReplayStart(const uint8_t* commandData,
size_t commandDataLen) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcReplayStart tcReplayStart(sequenceCount); mpsoc::TcReplayStart tcReplayStart(sequenceCount);
result = tcReplayStart.createPacket(commandData, commandDataLen); // result = tcReplayStart.createPacket(commandData, commandDataLen);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sequenceCount--; sequenceCount--;
return result; return result;
@ -450,8 +386,7 @@ ReturnValue_t PlocMPSoCHandler::prepareTcReplayStart(const uint8_t* commandData,
copyToCommandBuffer(&tcReplayStart); copyToCommandBuffer(&tcReplayStart);
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCReplayStopAction* action) {
ReturnValue_t PlocMPSoCHandler::prepareTcReplayStop() {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcReplayStop tcReplayStop(sequenceCount); mpsoc::TcReplayStop tcReplayStop(sequenceCount);
@ -464,12 +399,11 @@ ReturnValue_t PlocMPSoCHandler::prepareTcReplayStop() {
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::prepareTcDownlinkPwrOn(const uint8_t* commandData, ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCDownlinkPwrOnAction* action) {
size_t commandDataLen) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcDownlinkPwrOn tcDownlinkPwrOn(sequenceCount); mpsoc::TcDownlinkPwrOn tcDownlinkPwrOn(sequenceCount);
result = tcDownlinkPwrOn.createPacket(commandData, commandDataLen); // result = tcDownlinkPwrOn.createPacket(commandData, commandDataLen);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sequenceCount--; sequenceCount--;
return result; return result;
@ -477,8 +411,7 @@ ReturnValue_t PlocMPSoCHandler::prepareTcDownlinkPwrOn(const uint8_t* commandDat
copyToCommandBuffer(&tcDownlinkPwrOn); copyToCommandBuffer(&tcDownlinkPwrOn);
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCDownlinkPwrOffAction* action) {
ReturnValue_t PlocMPSoCHandler::prepareTcDownlinkPwrOff() {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcDownlinkPwrOff tcDownlinkPwrOff(sequenceCount); mpsoc::TcDownlinkPwrOff tcDownlinkPwrOff(sequenceCount);
@ -491,12 +424,11 @@ ReturnValue_t PlocMPSoCHandler::prepareTcDownlinkPwrOff() {
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::prepareTcReplayWriteSequence(const uint8_t* commandData, ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCReplayWriteSequenceAction* action) {
size_t commandDataLen) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcReplayWriteSeq tcReplayWriteSeq(sequenceCount); mpsoc::TcReplayWriteSeq tcReplayWriteSeq(sequenceCount);
result = tcReplayWriteSeq.createPacket(commandData, commandDataLen); // result = tcReplayWriteSeq.createPacket(commandData, commandDataLen);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sequenceCount--; sequenceCount--;
return result; return result;
@ -505,7 +437,7 @@ ReturnValue_t PlocMPSoCHandler::prepareTcReplayWriteSequence(const uint8_t* comm
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::prepareTcModeReplay() { ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCModeReplayAction* action) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcModeReplay tcModeReplay(sequenceCount); mpsoc::TcModeReplay tcModeReplay(sequenceCount);
@ -517,11 +449,11 @@ ReturnValue_t PlocMPSoCHandler::prepareTcModeReplay() {
memcpy(commandBuffer, tcModeReplay.getWholeData(), tcModeReplay.getFullSize()); memcpy(commandBuffer, tcModeReplay.getWholeData(), tcModeReplay.getFullSize());
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = tcModeReplay.getFullSize(); rawPacketLen = tcModeReplay.getFullSize();
nextReplyId = mpsoc::ACK_REPORT; nextReplyId = PlocMpSoCCommands::ACK_REPORT;
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::prepareTcModeIdle() { ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCModeIdleAction* action) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcModeIdle tcModeIdle(sequenceCount); mpsoc::TcModeIdle tcModeIdle(sequenceCount);
@ -533,22 +465,52 @@ ReturnValue_t PlocMPSoCHandler::prepareTcModeIdle() {
memcpy(commandBuffer, tcModeIdle.getWholeData(), tcModeIdle.getFullSize()); memcpy(commandBuffer, tcModeIdle.getWholeData(), tcModeIdle.getFullSize());
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = tcModeIdle.getFullSize(); rawPacketLen = tcModeIdle.getFullSize();
nextReplyId = mpsoc::ACK_REPORT; nextReplyId = PlocMpSoCCommands::ACK_REPORT;
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t PlocMPSoCHandler::prepareTcCamCmdSend(const uint8_t* commandData, ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCCamCmdSendAction* action) {
size_t commandDataLen) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sequenceCount++; sequenceCount++;
mpsoc::TcCamcmdSend tcCamCmdSend(sequenceCount); mpsoc::TcCamcmdSend tcCamCmdSend(sequenceCount);
result = tcCamCmdSend.createPacket(commandData, commandDataLen); // result = tcCamCmdSend.createPacket(commandData, commandDataLen);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sequenceCount--; sequenceCount--;
return result; return result;
} }
copyToCommandBuffer(&tcCamCmdSend); copyToCommandBuffer(&tcCamCmdSend);
nextReplyId = mpsoc::TM_CAM_CMD_RPT; nextReplyId = PlocMpSoCCommands::TM_CAM_CMD_RPT;
return RETURN_OK;
}
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCFlashWriteAction* action) {
ReturnValue_t result = RETURN_OK;
// if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) {
// return MPSoCReturnValuesIF::FILENAME_TOO_LONG;
// }
mpsoc::FlashWritePusCmd flashWritePusCmd;
// result = flashWritePusCmd.extractFields(data, size);
if (result != RETURN_OK) {
return result;
}
result = plocMPSoCHelper->startFlashWrite(flashWritePusCmd.getObcFile(),
flashWritePusCmd.getMPSoCFile());
if (result != RETURN_OK) {
return result;
}
plocMPSoCHelperExecuting = true;
return EXECUTION_FINISHED;
}
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCUartTxTristateAction* action) {
// not used
return RETURN_OK;
}
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCReleaseUartTxAction* action) {
// not used
return RETURN_OK;
}
ReturnValue_t PlocMPSoCHandler::handleAction(PlocMpSoCObswResetSeqCountAction* action) {
// not used
return RETURN_OK; return RETURN_OK;
} }
@ -559,7 +521,7 @@ void PlocMPSoCHandler::copyToCommandBuffer(mpsoc::TcBase* tc) {
memcpy(commandBuffer, tc->getWholeData(), tc->getFullSize()); memcpy(commandBuffer, tc->getWholeData(), tc->getFullSize());
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = tc->getFullSize(); rawPacketLen = tc->getFullSize();
nextReplyId = mpsoc::ACK_REPORT; nextReplyId = PlocMpSoCCommands::ACK_REPORT;
} }
ReturnValue_t PlocMPSoCHandler::verifyPacket(const uint8_t* start, size_t foundLen) { ReturnValue_t PlocMPSoCHandler::verifyPacket(const uint8_t* start, size_t foundLen) {
@ -577,10 +539,10 @@ ReturnValue_t PlocMPSoCHandler::handleAckReport(const uint8_t* data) {
result = verifyPacket(data, mpsoc::SIZE_ACK_REPORT); result = verifyPacket(data, mpsoc::SIZE_ACK_REPORT);
if (result == MPSoCReturnValuesIF::CRC_FAILURE) { if (result == MPSoCReturnValuesIF::CRC_FAILURE) {
sif::warning << "PlocMPSoCHandler::handleAckReport: CRC failure" << std::endl; sif::warning << "PlocMPSoCHandler::handleAckReport: CRC failure" << std::endl;
nextReplyId = mpsoc::NONE; nextReplyId = PlocMpSoCCommands::NONE;
replyRawReplyIfnotWiretapped(data, mpsoc::SIZE_ACK_REPORT); replyRawReplyIfnotWiretapped(data, mpsoc::SIZE_ACK_REPORT);
triggerEvent(MPSOC_HANDLER_CRC_FAILURE); triggerEvent(MPSOC_HANDLER_CRC_FAILURE);
sendFailureReport(mpsoc::ACK_REPORT, MPSoCReturnValuesIF::CRC_FAILURE); sendFailureReport(PlocMpSoCCommands::ACK_REPORT, MPSoCReturnValuesIF::CRC_FAILURE);
disableAllReplies(); disableAllReplies();
return IGNORE_REPLY_DATA; return IGNORE_REPLY_DATA;
} }
@ -596,9 +558,9 @@ ReturnValue_t PlocMPSoCHandler::handleAckReport(const uint8_t* data) {
if (commandId != DeviceHandlerIF::NO_COMMAND_ID) { if (commandId != DeviceHandlerIF::NO_COMMAND_ID) {
triggerEvent(ACK_FAILURE, commandId, status); triggerEvent(ACK_FAILURE, commandId, status);
} }
sendFailureReport(mpsoc::ACK_REPORT, status); sendFailureReport(PlocMpSoCCommands::ACK_REPORT, status);
disableAllReplies(); disableAllReplies();
nextReplyId = mpsoc::NONE; nextReplyId = PlocMpSoCCommands::NONE;
result = IGNORE_REPLY_DATA; result = IGNORE_REPLY_DATA;
break; break;
} }
@ -622,7 +584,7 @@ ReturnValue_t PlocMPSoCHandler::handleExecutionReport(const uint8_t* data) {
result = verifyPacket(data, mpsoc::SIZE_EXE_REPORT); result = verifyPacket(data, mpsoc::SIZE_EXE_REPORT);
if (result == MPSoCReturnValuesIF::CRC_FAILURE) { if (result == MPSoCReturnValuesIF::CRC_FAILURE) {
sif::warning << "PlocMPSoCHandler::handleExecutionReport: CRC failure" << std::endl; sif::warning << "PlocMPSoCHandler::handleExecutionReport: CRC failure" << std::endl;
nextReplyId = mpsoc::NONE; nextReplyId = PlocMpSoCCommands::NONE;
return result; return result;
} }
@ -644,7 +606,7 @@ ReturnValue_t PlocMPSoCHandler::handleExecutionReport(const uint8_t* data) {
sif::debug << "PlocMPSoCHandler::handleExecutionReport: Unknown command id" << std::endl; sif::debug << "PlocMPSoCHandler::handleExecutionReport: Unknown command id" << std::endl;
} }
printStatus(data); printStatus(data);
sendFailureReport(mpsoc::EXE_REPORT, MPSoCReturnValuesIF::RECEIVED_EXE_FAILURE); sendFailureReport(PlocMpSoCCommands::EXE_REPORT, MPSoCReturnValuesIF::RECEIVED_EXE_FAILURE);
disableExeReportReply(); disableExeReportReply();
result = IGNORE_REPLY_DATA; result = IGNORE_REPLY_DATA;
break; break;
@ -655,7 +617,7 @@ ReturnValue_t PlocMPSoCHandler::handleExecutionReport(const uint8_t* data) {
break; break;
} }
} }
nextReplyId = mpsoc::NONE; nextReplyId = PlocMpSoCCommands::NONE;
return result; return result;
} }
@ -670,8 +632,8 @@ ReturnValue_t PlocMPSoCHandler::handleMemoryReadReport(const uint8_t* data) {
*(data + mpsoc::MEM_READ_RPT_LEN_OFFSET) << 8 | *(data + mpsoc::MEM_READ_RPT_LEN_OFFSET + 1); *(data + mpsoc::MEM_READ_RPT_LEN_OFFSET) << 8 | *(data + mpsoc::MEM_READ_RPT_LEN_OFFSET + 1);
/** Send data to commanding queue */ /** Send data to commanding queue */
handleDeviceTM(data + mpsoc::DATA_FIELD_OFFSET, mpsoc::SIZE_MEM_READ_RPT_FIX + memLen * 4, handleDeviceTM(data + mpsoc::DATA_FIELD_OFFSET, mpsoc::SIZE_MEM_READ_RPT_FIX + memLen * 4,
mpsoc::TM_MEMORY_READ_REPORT); static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_MEMORY_READ_REPORT));
nextReplyId = mpsoc::EXE_REPORT; nextReplyId = PlocMpSoCCommands::EXE_REPORT;
return result; return result;
} }
@ -694,7 +656,7 @@ ReturnValue_t PlocMPSoCHandler::handleCamCmdRpt(const uint8_t* data) {
<< static_cast<unsigned int>(ackValue) << std::endl; << static_cast<unsigned int>(ackValue) << std::endl;
#endif /* OBSW_DEBUG_PLOC_MPSOC == 1 */ #endif /* OBSW_DEBUG_PLOC_MPSOC == 1 */
handleDeviceTM(packet.getPacketData() + sizeof(uint16_t), packet.getPacketDataLength() - 1, handleDeviceTM(packet.getPacketData() + sizeof(uint16_t), packet.getPacketDataLength() - 1,
mpsoc::TM_CAM_CMD_RPT); static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_CAM_CMD_RPT));
return result; return result;
} }
@ -705,41 +667,47 @@ ReturnValue_t PlocMPSoCHandler::enableReplyInReplyMap(DeviceCommandMap::iterator
uint8_t enabledReplies = 0; uint8_t enabledReplies = 0;
switch (command->first) { PlocMpSoCCommands enumCommand = PlocMpSoCCommands(command->first);
case mpsoc::TC_MEM_WRITE:
case mpsoc::TC_FLASHDELETE: switch (enumCommand) {
case mpsoc::TC_REPLAY_START: case PlocMpSoCCommands::TC_MEM_WRITE:
case mpsoc::TC_REPLAY_STOP: case PlocMpSoCCommands::TC_FLASHDELETE:
case mpsoc::TC_DOWNLINK_PWR_ON: case PlocMpSoCCommands::TC_REPLAY_START:
case mpsoc::TC_DOWNLINK_PWR_OFF: case PlocMpSoCCommands::TC_REPLAY_STOP:
case mpsoc::TC_REPLAY_WRITE_SEQUENCE: case PlocMpSoCCommands::TC_DOWNLINK_PWR_ON:
case mpsoc::TC_MODE_REPLAY: case PlocMpSoCCommands::TC_DOWNLINK_PWR_OFF:
case mpsoc::TC_MODE_IDLE: case PlocMpSoCCommands::TC_REPLAY_WRITE_SEQUENCE:
case PlocMpSoCCommands::TC_MODE_REPLAY:
case PlocMpSoCCommands::TC_MODE_IDLE:
enabledReplies = 2; enabledReplies = 2;
break; break;
case mpsoc::TC_MEM_READ: { case PlocMpSoCCommands::TC_MEM_READ: {
enabledReplies = 3; enabledReplies = 3;
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, result = DeviceHandlerBase::enableReplyInReplyMap(
mpsoc::TM_MEMORY_READ_REPORT); command, enabledReplies, true,
static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_MEMORY_READ_REPORT));
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
<< mpsoc::TM_MEMORY_READ_REPORT << " not in replyMap" << std::endl; << static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_MEMORY_READ_REPORT)
<< " not in replyMap" << std::endl;
return result; return result;
} }
break; break;
} }
case mpsoc::TC_CAM_CMD_SEND: { case PlocMpSoCCommands::TC_CAM_CMD_SEND: {
enabledReplies = 3; enabledReplies = 3;
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, result = DeviceHandlerBase::enableReplyInReplyMap(
mpsoc::TM_CAM_CMD_RPT); command, enabledReplies, true,
static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_CAM_CMD_RPT));
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
<< mpsoc::TM_CAM_CMD_RPT << " not in replyMap" << std::endl; << static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_CAM_CMD_RPT)
<< " not in replyMap" << std::endl;
return result; return result;
} }
break; break;
} }
case mpsoc::OBSW_RESET_SEQ_COUNT: case PlocMpSoCCommands::OBSW_RESET_SEQ_COUNT:
break; break;
default: default:
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Unknown command id" << std::endl; sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Unknown command id" << std::endl;
@ -750,32 +718,36 @@ ReturnValue_t PlocMPSoCHandler::enableReplyInReplyMap(DeviceCommandMap::iterator
* Every command causes at least one acknowledgment and one execution report. Therefore both * Every command causes at least one acknowledgment and one execution report. Therefore both
* replies will be enabled here. * replies will be enabled here.
*/ */
result = result = DeviceHandlerBase::enableReplyInReplyMap(
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, mpsoc::ACK_REPORT); command, enabledReplies, true, static_cast<DeviceCommandId_t>(PlocMpSoCCommands::ACK_REPORT));
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " << mpsoc::ACK_REPORT sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
<< static_cast<DeviceCommandId_t>(PlocMpSoCCommands::ACK_REPORT)
<< " not in replyMap" << std::endl; << " not in replyMap" << std::endl;
} }
result = result = DeviceHandlerBase::enableReplyInReplyMap(
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, mpsoc::EXE_REPORT); command, enabledReplies, true, static_cast<DeviceCommandId_t>(PlocMpSoCCommands::EXE_REPORT));
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " << mpsoc::EXE_REPORT sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
<< static_cast<DeviceCommandId_t>(PlocMpSoCCommands::EXE_REPORT)
<< " not in replyMap" << std::endl; << " not in replyMap" << std::endl;
} }
switch (command->first) { switch (enumCommand) {
case mpsoc::TC_REPLAY_WRITE_SEQUENCE: { case PlocMpSoCCommands::TC_REPLAY_WRITE_SEQUENCE: {
DeviceReplyIter iter = deviceReplyMap.find(mpsoc::EXE_REPORT); DeviceReplyIter iter =
deviceReplyMap.find(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::EXE_REPORT));
// Overwrite delay cycles because replay write sequence command can required up to // Overwrite delay cycles because replay write sequence command can required up to
// 30 seconds for execution // 30 seconds for execution
iter->second.delayCycles = mpsoc::TC_WRITE_SEQ_EXECUTION_DELAY; iter->second.delayCycles = mpsoc::TC_WRITE_SEQ_EXECUTION_DELAY;
break; break;
} }
case mpsoc::TC_DOWNLINK_PWR_ON: { case PlocMpSoCCommands::TC_DOWNLINK_PWR_ON: {
DeviceReplyIter iter = deviceReplyMap.find(mpsoc::EXE_REPORT); DeviceReplyIter iter =
deviceReplyMap.find(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::EXE_REPORT));
// //
iter->second.delayCycles = mpsoc::TC_DOWNLINK_PWR_ON; iter->second.delayCycles = mpsoc::TC_DOWNLINK_PWR_ON_EXECUTION_DELAY;
break; break;
} }
default: default:
@ -786,24 +758,24 @@ ReturnValue_t PlocMPSoCHandler::enableReplyInReplyMap(DeviceCommandMap::iterator
} }
void PlocMPSoCHandler::setNextReplyId() { void PlocMPSoCHandler::setNextReplyId() {
switch (getPendingCommand()) { switch (PlocMpSoCCommands(getPendingCommand())) {
case mpsoc::TC_MEM_READ: case PlocMpSoCCommands::TC_MEM_READ:
nextReplyId = mpsoc::TM_MEMORY_READ_REPORT; nextReplyId = PlocMpSoCCommands::TM_MEMORY_READ_REPORT;
break; break;
default: default:
/* If no telemetry is expected the next reply is always the execution report */ /* If no telemetry is expected the next reply is always the execution report */
nextReplyId = mpsoc::EXE_REPORT; nextReplyId = PlocMpSoCCommands::EXE_REPORT;
break; break;
} }
} }
size_t PlocMPSoCHandler::getNextReplyLength(DeviceCommandId_t commandId) { size_t PlocMPSoCHandler::getNextReplyLength(DeviceCommandId_t commandId) {
size_t replyLen = 0; size_t replyLen = 0;
if (nextReplyId == mpsoc::NONE) { if (nextReplyId == PlocMpSoCCommands::NONE) {
return replyLen; return replyLen;
} }
DeviceReplyIter iter = deviceReplyMap.find(nextReplyId); DeviceReplyIter iter = deviceReplyMap.find(static_cast<DeviceCommandId_t>(nextReplyId));
if (iter != deviceReplyMap.end()) { if (iter != deviceReplyMap.end()) {
if (iter->second.delayCycles == 0) { if (iter->second.delayCycles == 0) {
@ -811,11 +783,11 @@ size_t PlocMPSoCHandler::getNextReplyLength(DeviceCommandId_t commandId) {
return replyLen; return replyLen;
} }
switch (nextReplyId) { switch (nextReplyId) {
case mpsoc::TM_MEMORY_READ_REPORT: { case PlocMpSoCCommands::TM_MEMORY_READ_REPORT: {
replyLen = tmMemReadReport.rememberRequestedSize; replyLen = tmMemReadReport.rememberRequestedSize;
break; break;
} }
case mpsoc::TM_CAM_CMD_RPT: case PlocMpSoCCommands::TM_CAM_CMD_RPT:
// Read acknowledgment, camera and execution report in one go because length of camera // Read acknowledgment, camera and execution report in one go because length of camera
// report is not fixed // report is not fixed
replyLen = SpacePacket::PACKET_MAX_SIZE; replyLen = SpacePacket::PACKET_MAX_SIZE;
@ -827,7 +799,8 @@ size_t PlocMPSoCHandler::getNextReplyLength(DeviceCommandId_t commandId) {
} }
} else { } else {
sif::debug << "PlocMPSoCHandler::getNextReplyLength: No entry for reply with reply id " sif::debug << "PlocMPSoCHandler::getNextReplyLength: No entry for reply with reply id "
<< std::hex << nextReplyId << " in deviceReplyMap" << std::endl; << std::hex << static_cast<DeviceCommandId_t>(nextReplyId) << " in deviceReplyMap"
<< std::endl;
} }
return replyLen; return replyLen;
@ -924,31 +897,33 @@ void PlocMPSoCHandler::handleDeviceTM(const uint8_t* data, size_t dataSize,
} }
void PlocMPSoCHandler::disableAllReplies() { void PlocMPSoCHandler::disableAllReplies() {
using namespace mpsoc;
DeviceReplyMap::iterator iter; DeviceReplyMap::iterator iter;
/* Disable ack reply */ /* Disable ack reply */
iter = deviceReplyMap.find(ACK_REPORT); iter = deviceReplyMap.find(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::ACK_REPORT));
DeviceReplyInfo* info = &(iter->second); DeviceReplyInfo* info = &(iter->second);
info->delayCycles = 0; info->delayCycles = 0;
info->command = deviceCommandMap.end(); info->command = deviceCommandMap.end();
DeviceCommandId_t commandId = getPendingCommand(); DeviceCommandId_t commandId = getPendingCommand();
PlocMpSoCCommands enumCommand = PlocMpSoCCommands(commandId);
/* If the command expects a telemetry packet the appropriate tm reply will be disabled here */ /* If the command expects a telemetry packet the appropriate tm reply will be disabled here */
switch (commandId) { switch (enumCommand) {
case TC_MEM_WRITE: case PlocMpSoCCommands::TC_MEM_WRITE:
break; break;
case TC_MEM_READ: { case PlocMpSoCCommands::TC_MEM_READ: {
iter = deviceReplyMap.find(TM_MEMORY_READ_REPORT); iter = deviceReplyMap.find(
static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_MEMORY_READ_REPORT));
info = &(iter->second); info = &(iter->second);
info->delayCycles = 0; info->delayCycles = 0;
info->active = false; info->active = false;
info->command = deviceCommandMap.end(); info->command = deviceCommandMap.end();
break; break;
} }
case TC_CAM_CMD_SEND: { case PlocMpSoCCommands::TC_CAM_CMD_SEND: {
iter = deviceReplyMap.find(TM_CAM_CMD_RPT); iter = deviceReplyMap.find(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::TM_CAM_CMD_RPT));
info = &(iter->second); info = &(iter->second);
info->delayCycles = 0; info->delayCycles = 0;
info->active = false; info->active = false;
@ -964,11 +939,11 @@ void PlocMPSoCHandler::disableAllReplies() {
/* We always need to disable the execution report reply here */ /* We always need to disable the execution report reply here */
disableExeReportReply(); disableExeReportReply();
nextReplyId = mpsoc::NONE; nextReplyId = PlocMpSoCCommands::NONE;
} }
void PlocMPSoCHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status) { void PlocMPSoCHandler::sendFailureReport(PlocMpSoCCommands replyId, ReturnValue_t status) {
DeviceReplyIter iter = deviceReplyMap.find(replyId); DeviceReplyIter iter = deviceReplyMap.find(static_cast<DeviceCommandId_t>(replyId));
if (iter == deviceReplyMap.end()) { if (iter == deviceReplyMap.end()) {
sif::debug << "PlocMPSoCHandler::sendFailureReport: Reply not in reply map" << std::endl; sif::debug << "PlocMPSoCHandler::sendFailureReport: Reply not in reply map" << std::endl;
return; return;
@ -985,7 +960,8 @@ void PlocMPSoCHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnValue_
} }
void PlocMPSoCHandler::disableExeReportReply() { void PlocMPSoCHandler::disableExeReportReply() {
DeviceReplyIter iter = deviceReplyMap.find(mpsoc::EXE_REPORT); DeviceReplyIter iter =
deviceReplyMap.find(static_cast<DeviceCommandId_t>(PlocMpSoCCommands::EXE_REPORT));
DeviceReplyInfo* info = &(iter->second); DeviceReplyInfo* info = &(iter->second);
info->delayCycles = 0; info->delayCycles = 0;
info->command = deviceCommandMap.end(); info->command = deviceCommandMap.end();

View File

@ -48,8 +48,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
object_id_t supervisorHandler); object_id_t supervisorHandler);
virtual ~PlocMPSoCHandler(); virtual ~PlocMPSoCHandler();
virtual ReturnValue_t initialize() override; virtual ReturnValue_t initialize() override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t executeAction(Action* action) override;
const uint8_t* data, size_t size) override;
void performOperationHook() override; void performOperationHook() override;
MessageQueueIF* getCommandQueuePtr() override; MessageQueueIF* getCommandQueuePtr() override;
void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override; void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override;
@ -58,6 +57,22 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
void completionSuccessfulReceived(ActionId_t actionId) override; void completionSuccessfulReceived(ActionId_t actionId) override;
void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override; void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override;
ReturnValue_t handleAction(PlocMpSoCMemWriteAction* action);
ReturnValue_t handleAction(PlocMpSoCMemReadAction* action);
ReturnValue_t handleAction(PlocMpSoCFlashDeleteAction* action);
ReturnValue_t handleAction(PlocMpSoCReplayStartAction* action);
ReturnValue_t handleAction(PlocMpSoCReplayStopAction* action);
ReturnValue_t handleAction(PlocMpSoCReplayWriteSequenceAction* action);
ReturnValue_t handleAction(PlocMpSoCDownlinkPwrOnAction* action);
ReturnValue_t handleAction(PlocMpSoCDownlinkPwrOffAction* action);
ReturnValue_t handleAction(PlocMpSoCModeReplayAction* action);
ReturnValue_t handleAction(PlocMpSoCCamCmdSendAction* action);
ReturnValue_t handleAction(PlocMpSoCModeIdleAction* action);
ReturnValue_t handleAction(PlocMpSoCFlashWriteAction* action);
ReturnValue_t handleAction(PlocMpSoCUartTxTristateAction* action);
ReturnValue_t handleAction(PlocMpSoCReleaseUartTxAction* action);
ReturnValue_t handleAction(PlocMpSoCObswResetSeqCountAction* action);
protected: protected:
void doStartUp() override; void doStartUp() override;
void doShutDown() override; void doShutDown() override;
@ -121,7 +136,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
* because the PLOC sends as reply to each command at least one acknowledgment and execution * because the PLOC sends as reply to each command at least one acknowledgment and execution
* report. * report.
*/ */
DeviceCommandId_t nextReplyId = mpsoc::NONE; PlocMpSoCCommands nextReplyId = PlocMpSoCCommands::NONE;
UartComIF* uartComIf = nullptr; UartComIF* uartComIf = nullptr;
@ -172,6 +187,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
ReturnValue_t prepareTcReplayWriteSequence(const uint8_t* commandData, size_t commandDataLen); ReturnValue_t prepareTcReplayWriteSequence(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t prepareTcCamCmdSend(const uint8_t* commandData, size_t commandDataLen); ReturnValue_t prepareTcCamCmdSend(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t prepareTcModeIdle(); ReturnValue_t prepareTcModeIdle();
/** /**
* @brief Copies space packet into command buffer * @brief Copies space packet into command buffer
*/ */
@ -248,7 +264,7 @@ class PlocMPSoCHandler : public DeviceHandlerBase, public CommandsActionsIF {
* @param replyId The id of the reply which signals a failure. * @param replyId The id of the reply which signals a failure.
* @param status A status byte which gives information about the failure type. * @param status A status byte which gives information about the failure type.
*/ */
void sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status); void sendFailureReport(PlocMpSoCCommands replyId, ReturnValue_t status);
/** /**
* @brief This function disables the execution report reply. Within this function also the * @brief This function disables the execution report reply. Within this function also the

View File

@ -10,7 +10,7 @@
#include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw/tmtcservices/SourceSequenceCounter.h" #include "fsfw/tmtcservices/SourceSequenceCounter.h"
#include "fsfw_hal/linux/uart/UartComIF.h" #include "fsfw_hal/linux/uart/UartComIF.h"
#include "linux/devices/devicedefinitions/PlocMPSoCDefinitions.h" #include "linux/devices/devicedefinitions/PlocMPSoCCommonDefinitions.h"
#ifdef XIPHOS_Q7S #ifdef XIPHOS_Q7S
#include "bsp_q7s/memory/SdCardManager.h" #include "bsp_q7s/memory/SdCardManager.h"
#endif #endif

View File

@ -40,40 +40,27 @@ ReturnValue_t PlocMemoryDumper::performOperation(uint8_t operationCode) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t PlocMemoryDumper::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t PlocMemoryDumper::executeAction(Action* action) { return action->handle(); }
const uint8_t* data, size_t size) {
ReturnValue_t PlocMemoryDumper::handleAction(DumpMemoryAction* action) {
if (state != State::IDLE) { if (state != State::IDLE) {
return IS_BUSY; return IS_BUSY;
} }
switch (actionId) { if (action->endAddress <= action->startAddress) {
case DUMP_MRAM: { return MRAM_INVALID_ADDRESS_COMBINATION;
size_t deserializeSize = sizeof(mram.startAddress) + sizeof(mram.endAddress);
SerializeAdapter::deSerialize(&mram.startAddress, &data, &deserializeSize,
SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&mram.endAddress, &data, &deserializeSize,
SerializeIF::Endianness::BIG);
if (mram.endAddress > MAX_MRAM_ADDRESS) {
return MRAM_ADDRESS_TOO_HIGH;
}
if (mram.endAddress <= mram.startAddress) {
return MRAM_INVALID_ADDRESS_COMBINATION;
}
state = State::COMMAND_FIRST_MRAM_DUMP;
break;
}
default: {
sif::warning << "PlocMemoryDumper::executeAction: Received command with invalid action id"
<< std::endl;
return INVALID_ACTION_ID;
}
} }
mram.startAddress = action->startAddress;
mram.endAddress = action->endAddress;
state = State::COMMAND_FIRST_MRAM_DUMP;
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
MessageQueueId_t PlocMemoryDumper::getCommandQueue() const { return commandQueue->getId(); } MessageQueueId_t PlocMemoryDumper::getCommandQueue() const { return commandQueue->getId(); }
ActionHelper* PlocMemoryDumper::getActionHelper() { return &actionHelper; }
MessageQueueIF* PlocMemoryDumper::getCommandQueuePtr() { return commandQueue; } MessageQueueIF* PlocMemoryDumper::getCommandQueuePtr() { return commandQueue; }
void PlocMemoryDumper::readCommandQueue() { void PlocMemoryDumper::readCommandQueue() {

View File

@ -2,6 +2,7 @@
#define MISSION_DEVICES_PLOCMEMORYDUMPER_H_ #define MISSION_DEVICES_PLOCMEMORYDUMPER_H_
#include <linux/devices/devicedefinitions/PlocMemDumpDefinitions.h> #include <linux/devices/devicedefinitions/PlocMemDumpDefinitions.h>
#include <linux/devices/devicedefinitions/PlocMemDumpActions.h>
#include <linux/devices/devicedefinitions/PlocSupervisorDefinitions.h> #include <linux/devices/devicedefinitions/PlocSupervisorDefinitions.h>
#include "OBSWConfig.h" #include "OBSWConfig.h"
@ -37,8 +38,9 @@ class PlocMemoryDumper : public SystemObject,
virtual ~PlocMemoryDumper(); virtual ~PlocMemoryDumper();
ReturnValue_t performOperation(uint8_t operationCode = 0) override; ReturnValue_t performOperation(uint8_t operationCode = 0) override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t executeAction(Action* action) override;
const uint8_t* data, size_t size); ReturnValue_t handleAction(DumpMemoryAction* action);
ActionHelper *getActionHelper() override;
MessageQueueId_t getCommandQueue() const; MessageQueueId_t getCommandQueue() const;
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
MessageQueueIF* getCommandQueuePtr() override; MessageQueueIF* getCommandQueuePtr() override;
@ -53,9 +55,6 @@ class PlocMemoryDumper : public SystemObject,
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MEMORY_DUMPER; static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MEMORY_DUMPER;
//! [EXPORT] : [COMMENT] The capacity of the MRAM amounts to 512 kB. Thus the maximum address must
//! not be higher than 0x7d000.
static const ReturnValue_t MRAM_ADDRESS_TOO_HIGH = MAKE_RETURN_CODE(0xA0);
//! [EXPORT] : [COMMENT] The specified end address is lower than the start address //! [EXPORT] : [COMMENT] The specified end address is lower than the start address
static const ReturnValue_t MRAM_INVALID_ADDRESS_COMBINATION = MAKE_RETURN_CODE(0xA1); static const ReturnValue_t MRAM_INVALID_ADDRESS_COMBINATION = MAKE_RETURN_CODE(0xA1);
@ -73,7 +72,6 @@ class PlocMemoryDumper : public SystemObject,
// Maximum size of mram dump which can be retrieved with one command // Maximum size of mram dump which can be retrieved with one command
static const uint32_t MAX_MRAM_DUMP_SIZE = 100000; static const uint32_t MAX_MRAM_DUMP_SIZE = 100000;
static const uint32_t MAX_MRAM_ADDRESS = 0x7d000;
MessageQueueIF* commandQueue = nullptr; MessageQueueIF* commandQueue = nullptr;

View File

@ -80,12 +80,15 @@ void PlocSupervisorHandler::performOperationHook() {
} }
} }
ReturnValue_t PlocSupervisorHandler::executeAction(ActionId_t actionId, ReturnValue_t PlocSupervisorHandler::executeAction(Action* action) {
MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) {
using namespace supv; using namespace supv;
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
//TODO
ActionId_t actionId = 0;
uint8_t *data = nullptr;
size_t size = 0;
switch (actionId) { switch (actionId) {
case TERMINATE_SUPV_HELPER: { case TERMINATE_SUPV_HELPER: {
supvHelper->stopProcess(); supvHelper->stopProcess();
@ -138,7 +141,7 @@ ReturnValue_t PlocSupervisorHandler::executeAction(ActionId_t actionId,
default: default:
break; break;
} }
return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); return DeviceHandlerBase::executeAction(action);
} }
void PlocSupervisorHandler::doStartUp() { void PlocSupervisorHandler::doStartUp() {
@ -828,7 +831,7 @@ void PlocSupervisorHandler::handleEvent(EventMessage* eventMessage) {
event == PlocSupvHelper::SUPV_UPDATE_SUCCESSFUL || event == PlocSupvHelper::SUPV_UPDATE_SUCCESSFUL ||
event == PlocSupvHelper::SUPV_CONTINUE_UPDATE_FAILED || event == PlocSupvHelper::SUPV_CONTINUE_UPDATE_FAILED ||
event == PlocSupvHelper::SUPV_CONTINUE_UPDATE_SUCCESSFUL) { event == PlocSupvHelper::SUPV_CONTINUE_UPDATE_SUCCESSFUL) {
result = this->executeAction(supv::SHUTDOWN_MPSOC, NO_COMMANDER, nullptr, 0); //TODO result = this->executeAction(supv::SHUTDOWN_MPSOC, NO_COMMANDER, nullptr, 0);
if (result != RETURN_OK) { if (result != RETURN_OK) {
triggerEvent(SUPV_MPSOC_SHUWDOWN_BUILD_FAILED); triggerEvent(SUPV_MPSOC_SHUWDOWN_BUILD_FAILED);
sif::warning << "PlocSupervisorHandler::handleEvent: Failed to build MPSoC shutdown " sif::warning << "PlocSupervisorHandler::handleEvent: Failed to build MPSoC shutdown "

View File

@ -34,8 +34,7 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
virtual ReturnValue_t initialize() override; virtual ReturnValue_t initialize() override;
void performOperationHook() override; void performOperationHook() override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t executeAction(Action* action) override;
const uint8_t* data, size_t size) override;
protected: protected:
void doStartUp() override; void doStartUp() override;

View File

@ -91,10 +91,14 @@ ReturnValue_t StarTrackerHandler::initialize() {
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t StarTrackerHandler::executeAction(Action* action) {
const uint8_t* data, size_t size) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
//TODO
ActionId_t actionId = 0;
uint8_t *data = nullptr;
size_t size = 0;
switch (actionId) { switch (actionId) {
case (startracker::STOP_IMAGE_LOADER): { case (startracker::STOP_IMAGE_LOADER): {
strHelper->stopProcess(); strHelper->stopProcess();
@ -209,7 +213,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
default: default:
break; break;
} }
return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); return DeviceHandlerBase::executeAction(action);
} }
void StarTrackerHandler::performOperationHook() { void StarTrackerHandler::performOperationHook() {

View File

@ -44,8 +44,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
* @brief Overwrite this function from DHB to handle commands executed by the str image * @brief Overwrite this function from DHB to handle commands executed by the str image
* loader task. * loader task.
*/ */
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t executeAction(Action* action) override;
const uint8_t* data, size_t size) override;
void performOperationHook() override; void performOperationHook() override;

View File

@ -3,7 +3,7 @@
#include <cstdint> #include <cstdint>
#include "common/config/commonSubsystemIds.h" #include <config/commonSubsystemIds.h>
#include "fsfw/events/fwSubsystemIdRanges.h" #include "fsfw/events/fwSubsystemIdRanges.h"
/** /**

View File

@ -2,6 +2,7 @@
#define LINUX_FSFWCONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ #define LINUX_FSFWCONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
#include <fsfw/objectmanager/frameworkObjects.h> #include <fsfw/objectmanager/frameworkObjects.h>
#include <fsfw/introspection/ClasslessEnum.h>
#include <cstdint> #include <cstdint>
@ -33,36 +34,34 @@ Fourth byte is a unique counter.
*/ */
namespace objects { namespace objects {
enum sourceObjects : uint32_t { FSFW_CLASSLESS_ENUM(systemObjects, uint32_t,
/* 0x53 reserved for FSFW */ /* 0x53 reserved for FSFW */
FW_ADDRESS_START = PUS_SERVICE_1_VERIFICATION, ((PUS_SERVICE_6, 0x51000500, "PUS_SERVICE_6"))
FW_ADDRESS_END = TIME_STAMPER,
PUS_SERVICE_6 = 0x51000500,
CCSDS_IP_CORE_BRIDGE = 0x73500000, ((CCSDS_IP_CORE_BRIDGE, 0x73500000, "CCSDS_IP_CORE_BRIDGE"))
TM_FUNNEL = 0x73000100, ((TM_FUNNEL, 0x73000100, "TM_FUNNEL"))
/* 0x49 ('I') for Communication Interfaces **/ /* 0x49 ('I') for Communication Interfaces **/
ARDUINO_COM_IF = 0x49000000, ((ARDUINO_COM_IF, 0x49000000, "ARDUINO_COM_IF"))
CSP_COM_IF = 0x49050001, ((CSP_COM_IF, 0x49050001, "CSP_COM_IF"))
I2C_COM_IF = 0x49040002, ((I2C_COM_IF, 0x49040002, "I2C_COM_IF"))
UART_COM_IF = 0x49030003, ((UART_COM_IF, 0x49030003, "UART_COM_IF"))
SPI_MAIN_COM_IF = 0x49020004, ((SPI_MAIN_COM_IF, 0x49020004, "SPI_MAIN_COM_IF"))
GPIO_IF = 0x49010005, ((GPIO_IF, 0x49010005, "GPIO_IF"))
SPI_RW_COM_IF = 0x49020005, ((SPI_RW_COM_IF, 0x49020005, "SPI_RW_COM_IF"))
SPI_RTD_COM_IF = 0x49020006, ((SPI_RTD_COM_IF, 0x49020006, "SPI_RTD_COM_IF"))
/* 0x54 ('T') for test handlers */ /* 0x54 ('T') for test handlers */
TEST_TASK = 0x54694269, ((TEST_TASK, 0x54694269, "TEST_TASK"))
LIBGPIOD_TEST = 0x54123456, ((LIBGPIOD_TEST, 0x54123456, "LIBGPIOD_TEST"))
SPI_TEST = 0x54000010, ((SPI_TEST, 0x54000010, "SPI_TEST"))
UART_TEST = 0x54000020, ((UART_TEST, 0x54000020, "UART_TEST"))
I2C_TEST = 0x54000030, ((I2C_TEST, 0x54000030, "I2C_TEST"))
DUMMY_INTERFACE = 0x5400CAFE, ((DUMMY_INTERFACE, 0x5400CAFE, "DUMMY_INTERFACE"))
DUMMY_HANDLER = 0x5400AFFE, ((DUMMY_HANDLER, 0x5400AFFE, "DUMMY_HANDLER"))
P60DOCK_TEST_TASK = 0x00005060, ((P60DOCK_TEST_TASK, 0x00005060, "P60DOCK_TEST_TASK"))
DUMMY_COM_IF = 0x54000040 ((DUMMY_COM_IF, 0x54000040, "DUMMY_COM_IF"))
}; )
} }
#endif /* LINUX_FSFWCONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */ #endif /* LINUX_FSFWCONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */

View File

@ -1,7 +1,7 @@
#ifndef FSFWCONFIG_RETURNVALUES_CLASSIDS_H_ #ifndef FSFWCONFIG_RETURNVALUES_CLASSIDS_H_
#define FSFWCONFIG_RETURNVALUES_CLASSIDS_H_ #define FSFWCONFIG_RETURNVALUES_CLASSIDS_H_
#include <common/config/commonClassIds.h> #include <config/commonClassIds.h>
#include <fsfw/returnvalues/FwClassIds.h> #include <fsfw/returnvalues/FwClassIds.h>
/** /**

View File

@ -0,0 +1,24 @@
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/introspection/Enum.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
class PdecHandler;
FSFW_ENUM(PdecCommands, DeviceCommandId_t,((PRINT_CLCW, "Print CLCW")) ((PRINT_PDEC_MON, "Print PDEC Mon Status")))
class PdecPrintClcwAction
: public TemplateAction<PdecHandler, PdecPrintClcwAction,
PdecCommands> {
public:
PdecPrintClcwAction(PdecHandler *owner)
: TemplateAction(owner, PdecCommands::PRINT_CLCW) {};
};
class PdecPrintMonAction
: public TemplateAction<PdecHandler, PdecPrintMonAction,
PdecCommands> {
public:
PdecPrintMonAction(PdecHandler *owner)
: TemplateAction(owner, PdecCommands::PRINT_PDEC_MON) {};
};

View File

@ -79,6 +79,8 @@ ReturnValue_t PdecHandler::initialize() {
MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); } MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); }
ActionHelper* PdecHandler::getActionHelper() { return &actionHelper; }
void PdecHandler::writePdecConfig() { void PdecHandler::writePdecConfig() {
PdecConfig pdecConfig; PdecConfig pdecConfig;
@ -514,16 +516,14 @@ std::string PdecHandler::getMonStatusString(uint32_t status) {
} }
} }
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t PdecHandler::executeAction(Action* action) { return action->handle(); }
const uint8_t* data, size_t size) {
switch (actionId) { ReturnValue_t PdecHandler::handleAction(PdecPrintClcwAction* action) {
case PRINT_CLCW: printClcw();
printClcw(); return EXECUTION_FINISHED;
return EXECUTION_FINISHED; }
case PRINT_PDEC_MON:
printPdecMon(); ReturnValue_t PdecHandler::handleAction(PdecPrintMonAction* action) {
return EXECUTION_FINISHED; printPdecMon();
default: return EXECUTION_FINISHED;
return COMMAND_NOT_IMPLEMENTED;
}
} }

View File

@ -3,6 +3,7 @@
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "PdecConfig.h" #include "PdecConfig.h"
#include "PdecDefinitions.h"
#include "fsfw/action/ActionHelper.h" #include "fsfw/action/ActionHelper.h"
#include "fsfw/action/HasActionsIF.h" #include "fsfw/action/HasActionsIF.h"
#include "fsfw/objectmanager/SystemObject.h" #include "fsfw/objectmanager/SystemObject.h"
@ -57,8 +58,10 @@ class PdecHandler : public SystemObject,
MessageQueueId_t getCommandQueue() const; MessageQueueId_t getCommandQueue() const;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ActionHelper* getActionHelper() override;
const uint8_t* data, size_t size) override; ReturnValue_t executeAction(Action* action) override;
ReturnValue_t handleAction(PdecPrintClcwAction* action);
ReturnValue_t handleAction(PdecPrintMonAction* action);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
@ -89,9 +92,6 @@ class PdecHandler : public SystemObject,
static const ReturnValue_t AD_DISCARDED_WAIT = MAKE_RETURN_CODE(0xA4); static const ReturnValue_t AD_DISCARDED_WAIT = MAKE_RETURN_CODE(0xA4);
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5); static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
//! [EXPORT] : [COMMENT] Received action message with unknown action id
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
static const ReturnValue_t NO_REPORT = MAKE_RETURN_CODE(0xA6); static const ReturnValue_t NO_REPORT = MAKE_RETURN_CODE(0xA6);
//! Error in version number and reserved A and B fields //! Error in version number and reserved A and B fields
static const ReturnValue_t ERROR_VERSION_NUMBER = MAKE_RETURN_CODE(0xA7); static const ReturnValue_t ERROR_VERSION_NUMBER = MAKE_RETURN_CODE(0xA7);
@ -110,11 +110,6 @@ class PdecHandler : public SystemObject,
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE; static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
// Action IDs
static const ActionId_t PRINT_CLCW = 0;
// Print PDEC monitor register
static const ActionId_t PRINT_PDEC_MON = 1;
static const uint8_t STAT_POSITION = 31; static const uint8_t STAT_POSITION = 31;
static const uint8_t FRAME_ANA_POSITION = 28; static const uint8_t FRAME_ANA_POSITION = 28;
static const uint8_t IREASON_POSITION = 25; static const uint8_t IREASON_POSITION = 25;
@ -371,6 +366,9 @@ class PdecHandler : public SystemObject,
ActionHelper actionHelper; ActionHelper actionHelper;
PdecPrintClcwAction pdecPrintClcwAction = PdecPrintClcwAction(this);
PdecPrintMonAction pdecPrintMonAction = PdecPrintMonAction(this);
StorageManagerIF* tcStore = nullptr; StorageManagerIF* tcStore = nullptr;
MessageQueueIF* commandQueue = nullptr; MessageQueueIF* commandQueue = nullptr;

View File

@ -61,6 +61,10 @@ ReturnValue_t AcsController::checkModeCommand(Mode_t mode, Submode_t submode,
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ModeDefinitionHelper AcsController::getModeDefinitionHelper() {
return ModeDefinitionHelper::create<ControllerModes, DefaultSubmode>();
}
void AcsController::copyMgmData() { void AcsController::copyMgmData() {
{ {
PoolReadGuard pg(&mgm0Lis3Set); PoolReadGuard pg(&mgm0Lis3Set);

View File

@ -30,6 +30,8 @@ class AcsController : public ExtendedControllerBase {
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override; uint32_t* msToReachTheMode) override;
ModeDefinitionHelper getModeDefinitionHelper() override;
// MGMs // MGMs
acsctrl::MgmData mgmData; acsctrl::MgmData mgmData;

View File

@ -231,6 +231,10 @@ ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode
return RETURN_OK; return RETURN_OK;
} }
ModeDefinitionHelper ThermalController::getModeDefinitionHelper() {
return ModeDefinitionHelper::create<ControllerModes, DefaultSubmode>();
}
void ThermalController::copySensors() { void ThermalController::copySensors() {
PoolReadGuard pg0(&max31865Set0); PoolReadGuard pg0(&max31865Set0);
if (pg0.getReadResult() == HasReturnvaluesIF::RETURN_OK) { if (pg0.getReadResult() == HasReturnvaluesIF::RETURN_OK) {

View File

@ -27,6 +27,8 @@ class ThermalController : public ExtendedControllerBase {
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override; uint32_t* msToReachTheMode) override;
ModeDefinitionHelper getModeDefinitionHelper() override;
private: private:
static const uint32_t DELAY = 500; static const uint32_t DELAY = 500;

View File

@ -13,7 +13,7 @@ ACUHandler::~ACUHandler() {}
ReturnValue_t ACUHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) { ReturnValue_t ACUHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
*id = GOMSPACE::REQUEST_HK_TABLE; *id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0); return requestHkTableAction.handle();
} }
void ACUHandler::fillCommandAndReplyMap() { GomspaceDeviceHandler::fillCommandAndReplyMap(); } void ACUHandler::fillCommandAndReplyMap() { GomspaceDeviceHandler::fillCommandAndReplyMap(); }

View File

@ -33,59 +33,11 @@ ReturnValue_t GomspaceDeviceHandler::buildTransitionDeviceCommand(DeviceCommandI
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, ReturnValue_t GomspaceDeviceHandler::handleAction(PrintSwitchVIAction* action) {
const uint8_t* commandData, return printStatus(action->getId());
size_t commandDataLen) { }
ReturnValue_t result = childCommandHook(deviceCommand, commandData, commandDataLen); ReturnValue_t GomspaceDeviceHandler::handleAction(PrintLatchupsAction* action) {
switch (deviceCommand) { return printStatus(action->getId());
case (GOMSPACE::PING): {
result = generatePingCommand(commandData, commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
break;
}
case (GOMSPACE::REBOOT): {
generateRebootCommand();
break;
}
case (GOMSPACE::PARAM_SET): {
result = generateSetParamCommand(commandData, commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
break;
}
case (GOMSPACE::PARAM_GET): {
result = generateGetParamCommand(commandData, commandDataLen);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
break;
}
case (GOMSPACE::GNDWDT_RESET): {
result = generateResetWatchdogCmd();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
break;
}
case (GOMSPACE::PRINT_SWITCH_V_I):
case (GOMSPACE::PRINT_LATCHUPS): {
result = printStatus(deviceCommand);
break;
}
case (GOMSPACE::REQUEST_HK_TABLE): {
result = generateRequestFullHkTableCmd(hkTableReplySize);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
break;
}
default:
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
return HasReturnvaluesIF::RETURN_OK;
} }
void GomspaceDeviceHandler::fillCommandAndReplyMap() { void GomspaceDeviceHandler::fillCommandAndReplyMap() {
@ -172,7 +124,8 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
if (*packet != PARAM_SET_OK) { if (*packet != PARAM_SET_OK) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
setParamCallback(setParamCacher, true); // TODO fix
setParamCallback(setParamCacher.getParameter(), setParamCacher.getParameter(), setParamCacher.getParameterSize(), true);
break; break;
} }
case (GOMSPACE::REQUEST_HK_TABLE): { case (GOMSPACE::REQUEST_HK_TABLE): {
@ -187,29 +140,23 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
void GomspaceDeviceHandler::setNormalDatapoolEntriesInvalid() {} void GomspaceDeviceHandler::setNormalDatapoolEntriesInvalid() {}
ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* commandData, ReturnValue_t GomspaceDeviceHandler::handleAction(ParamSetAction* action) {
size_t commandDataLen) {
ReturnValue_t result =
setParamCacher.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG);
// This breaks layering but I really don't want to accept this command.. // This breaks layering but I really don't want to accept this command..
if (setParamCacher.getAddress() == PDU2::CONFIG_ADDRESS_OUT_EN_Q7S and if (action->address == PDU2::CONFIG_ADDRESS_OUT_EN_Q7S and
this->getObjectId() == objects::PDU2_HANDLER) { this->getObjectId() == objects::PDU2_HANDLER) {
triggerEvent(power::SWITCHING_Q7S_DENIED, 0, 0); triggerEvent(power::SWITCHING_Q7S_DENIED, 0, 0);
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
if (result != HasReturnvaluesIF::RETURN_OK) { //cache for later use
sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter " setParamCacher.set(action->address, action->parameter,
"message" static_cast<uint8_t>(action->parameterSize.value));
<< std::endl; ReturnValue_t result = setParamCallback(action->address, action->parameter,
return result; static_cast<uint8_t>(action->parameterSize.value), false);
}
result = setParamCallback(setParamCacher, false);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
/* Get and check address */ /* Get and check address */
uint16_t address = setParamCacher.getAddress(); if (action->address > maxConfigTableAddress) {
if (address > maxConfigTableAddress) {
sif::error << "GomspaceDeviceHandler: Invalid address for set parameter " sif::error << "GomspaceDeviceHandler: Invalid address for set parameter "
<< "action" << std::endl; << "action" << std::endl;
return INVALID_ADDRESS; return INVALID_ADDRESS;
@ -219,13 +166,52 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm
uint16_t total = 0; uint16_t total = 0;
/* CSP reply only contains the transaction state */ /* CSP reply only contains the transaction state */
uint16_t querySize = 1; uint16_t querySize = 1;
const uint8_t* parameterPtr = setParamCacher.getParameter(); size_t parameterSize = 0;
uint8_t parameterSize = setParamCacher.getParameterSize(); uint8_t parameterBytes[4];
uint16_t payloadlength = sizeof(address) + parameterSize; uint8_t* uselessPointer = parameterBytes;
switch (action->parameterSize.value) {
case ParamSetAction::ParameterByteSize::ONE_BYTE: {
if (action->parameter > 255) {
return INVALID_PARAMETERS;
}
uint8_t oneByte = action->parameter.value;
result = SerializeAdapter::serialize<uint8_t>(&oneByte, &uselessPointer, &parameterSize,
sizeof(parameterBytes),
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
parameterSize = 1;
} break;
case ParamSetAction::ParameterByteSize::TWO_BYTES: {
if (action->parameter > 65535) {
return INVALID_PARAMETERS;
}
uint16_t twoBytes = action->parameter.value;
result = SerializeAdapter::serialize<uint16_t>(&twoBytes, &uselessPointer, &parameterSize,
sizeof(parameterBytes),
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
parameterSize = 2;
} break;
case ParamSetAction::ParameterByteSize::FOUR_BYTES:
result = SerializeAdapter::serialize<uint32_t>(&(action->parameter.value), &uselessPointer,
&parameterSize, sizeof(parameterBytes),
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
parameterSize = 4;
break;
}
uint16_t payloadlength = sizeof(action->address) + parameterSize;
/* Generate command for CspComIF */ /* Generate command for CspComIF */
CspSetParamCommand setParamCmd(querySize, payloadlength, checksum, seq, total, address, CspSetParamCommand setParamCmd(querySize, payloadlength, checksum, seq, total, action->address,
parameterPtr, parameterSize); parameterBytes, parameterSize);
size_t cspPacketLen = 0; size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket; uint8_t* buffer = cspPacket;
result = setParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket), result = setParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
@ -249,34 +235,18 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(const uint8_t* commandData, ReturnValue_t GomspaceDeviceHandler::handleAction(ParamGetAction* action) {
size_t commandDataLen) {
ReturnValue_t result; ReturnValue_t result;
/* Unpack the received action message */ auto tableId = action->tableId.value;
GetParamMessageUnpacker getParamMessage;
result = getParamMessage.deSerialize(&commandData, &commandDataLen, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Failed to deserialize message to extract information "
"from get parameter message"
<< std::endl;
return result;
}
/* Get an check table id to read from */
uint8_t tableId = getParamMessage.getTableId();
if (tableId != CONFIG_TABLE_ID && tableId != HK_TABLE_ID) {
sif::error << "GomspaceDeviceHandler: Invalid table id in get parameter"
" message"
<< std::endl;
return INVALID_TABLE_ID;
}
/* Get and check address */ /* Get and check address */
uint16_t address = getParamMessage.getAddress(); uint16_t address = action->address;
if (address > maxHkTableAddress && tableId == HK_TABLE_ID) { if (address > maxHkTableAddress && tableId == ParamGetAction::TableId::HK_TABLE_ID) {
sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from " sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from "
<< "housekeeping table" << std::endl; << "housekeeping table" << std::endl;
return INVALID_ADDRESS; return INVALID_ADDRESS;
} }
if (address > maxConfigTableAddress && tableId == CONFIG_TABLE_ID) { if (address > maxConfigTableAddress && tableId == ParamGetAction::TableId::CONFIG_TABLE_ID) {
sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from " sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from "
<< "configuration table" << std::endl; << "configuration table" << std::endl;
return INVALID_ADDRESS; return INVALID_ADDRESS;
@ -285,16 +255,11 @@ ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(const uint8_t* comm
uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM; uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM;
uint16_t seq = 0; uint16_t seq = 0;
uint16_t total = 0; uint16_t total = 0;
uint8_t parameterSize = getParamMessage.getParameterSize(); uint8_t parameterSize = static_cast<uint8_t>(action->parameterSize.value);
if (parameterSize > sizeof(uint32_t)) {
sif::error << "GomspaceDeviceHandler: GET_PARAM: Invalid parameter "
<< "size" << std::endl;
return INVALID_PARAM_SIZE;
}
uint16_t querySize = parameterSize + GOMSPACE::GS_HDR_LENGTH; uint16_t querySize = parameterSize + GOMSPACE::GS_HDR_LENGTH;
/* Generate the CSP command to send to the P60 Dock */ /* Generate the CSP command to send to the P60 Dock */
CspGetParamCommand getParamCmd(querySize, tableId, length, checksum, seq, total, address); CspGetParamCommand getParamCmd(querySize, static_cast<uint8_t>(tableId), length, checksum, seq, total, address);
size_t cspPacketLen = 0; size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket; uint8_t* buffer = cspPacket;
result = getParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket), result = getParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
@ -303,12 +268,14 @@ ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(const uint8_t* comm
sif::error << "GomspaceDeviceHandler: Failed to serialize command to " sif::error << "GomspaceDeviceHandler: Failed to serialize command to "
<< "get parameter" << std::endl; << "get parameter" << std::endl;
} }
if (cspPacketLen > MAX_PACKET_LEN) {
// checked by serialize above
/* if (cspPacketLen > MAX_PACKET_LEN) {
sif::error << "GomspaceDeviceHandler: Received invalid get parameter " sif::error << "GomspaceDeviceHandler: Received invalid get parameter "
"command" "command"
<< std::endl; << std::endl;
return PACKET_TOO_LONG; return PACKET_TOO_LONG;
} }*/
rawPacket = cspPacket; rawPacket = cspPacket;
rawPacketLen = cspPacketLen; rawPacketLen = cspPacketLen;
rememberRequestedSize = querySize; rememberRequestedSize = querySize;
@ -316,9 +283,8 @@ ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(const uint8_t* comm
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t GomspaceDeviceHandler::generatePingCommand(const uint8_t* commandData, ReturnValue_t GomspaceDeviceHandler::handleAction(PingAction* action) {
size_t commandDataLen) { CspPingCommand cspPingCommand(&action->pingData.value, 1); // TODO array
CspPingCommand cspPingCommand(commandData, commandDataLen);
size_t cspPacketLen = 0; size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket; uint8_t* buffer = cspPacket;
ReturnValue_t result = cspPingCommand.serialize(&buffer, &cspPacketLen, sizeof(cspPacket), ReturnValue_t result = cspPingCommand.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
@ -327,24 +293,27 @@ ReturnValue_t GomspaceDeviceHandler::generatePingCommand(const uint8_t* commandD
sif::error << "GomspaceDeviceHandler: Failed to serialize ping command" << std::endl; sif::error << "GomspaceDeviceHandler: Failed to serialize ping command" << std::endl;
return result; return result;
} }
/* Checked by the serialize function
if (cspPacketLen > MAX_PACKET_LEN) { if (cspPacketLen > MAX_PACKET_LEN) {
sif::error << "GomspaceDeviceHandler: Received invalid ping message" << std::endl; sif::error << "GomspaceDeviceHandler: Received invalid ping message" << std::endl;
return PACKET_TOO_LONG; return PACKET_TOO_LONG;
} }*/
rawPacket = cspPacket; rawPacket = cspPacket;
rawPacketLen = cspPacketLen; rawPacketLen = cspPacketLen;
rememberCommandId = GOMSPACE::PING; rememberCommandId = GOMSPACE::PING;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void GomspaceDeviceHandler::generateRebootCommand() { ReturnValue_t GomspaceDeviceHandler::handleAction(RebootAction* action) {
uint8_t cspPort = GOMSPACE::REBOOT_PORT; uint8_t cspPort = GOMSPACE::REBOOT_PORT;
uint16_t querySize = 0; uint16_t querySize = 0;
*cspPacket = GOMSPACE::REBOOT_PORT; *cspPacket = GOMSPACE::REBOOT_PORT;
// TODO the following two lines look strange...
*(cspPacket + 1) = querySize; *(cspPacket + 1) = querySize;
size_t cspPacketLen = sizeof(cspPort) + sizeof(cspPacketLen); size_t cspPacketLen = sizeof(cspPort) + sizeof(cspPacketLen);
rawPacket = cspPacket; rawPacket = cspPacket;
rawPacketLen = cspPacketLen; rawPacketLen = cspPacketLen;
return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t GomspaceDeviceHandler::childCommandHook(DeviceCommandId_t cmd, ReturnValue_t GomspaceDeviceHandler::childCommandHook(DeviceCommandId_t cmd,
@ -353,8 +322,8 @@ ReturnValue_t GomspaceDeviceHandler::childCommandHook(DeviceCommandId_t cmd,
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
} }
ReturnValue_t GomspaceDeviceHandler::setParamCallback(SetParamMessageUnpacker& unpacker, ReturnValue_t GomspaceDeviceHandler::setParamCallback(uint16_t address, uint32_t value,
bool afterExecution) { uint8_t valueBytes, bool afterExecution) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -396,7 +365,7 @@ ReturnValue_t GomspaceDeviceHandler::initializePduPool(
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() { ReturnValue_t GomspaceDeviceHandler::handleAction(GndwdtResetAction* action) {
WatchdogResetCommand watchdogResetCommand; WatchdogResetCommand watchdogResetCommand;
size_t cspPacketLen = 0; size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket; uint8_t* buffer = cspPacket;
@ -415,9 +384,9 @@ ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t GomspaceDeviceHandler::generateRequestFullHkTableCmd(uint16_t hkTableReplySize) { ReturnValue_t GomspaceDeviceHandler::handleAction(RequestHkTableAction* action) {
uint16_t querySize = hkTableReplySize; uint16_t querySize = hkTableReplySize;
uint8_t tableId = HK_TABLE_ID; uint8_t tableId = static_cast<uint8_t>(ParamGetAction::TableId::HK_TABLE_ID);
RequestFullTableCommand requestFullTableCommand(querySize, tableId); RequestFullTableCommand requestFullTableCommand(querySize, tableId);
size_t cspPacketLen = 0; size_t cspPacketLen = 0;

View File

@ -4,6 +4,7 @@
#include <mission/devices/devicedefinitions/GomSpacePackets.h> #include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "mission/devices/devicedefinitions/GomspaceActions.h"
#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h"
#include "returnvalues/classIds.h" #include "returnvalues/classIds.h"
@ -48,12 +49,43 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
*/ */
void setModeNormal(); void setModeNormal();
/**
* @brief Function to generate the ping command for the ComIF.
*/
ReturnValue_t handleAction(PingAction *action);
/**
* @brief Function to generate the command to reboot a gomspace device
* via the ComIF.
*/
ReturnValue_t handleAction(RebootAction *action);
/**
* @brief Function to generate the command to force a ground watchdog
* reset in a gomspace device.
*/
ReturnValue_t handleAction(GndwdtResetAction *action);
/**
* @brief Function to generate the command to get a parameter from a
* gomspace device. Command will be sent to the ComIF over the
* rawPacket buffer.
*/
ReturnValue_t handleAction(ParamGetAction *action);
/**
* @brief Function to generate the command to set a parameter. Command
* will be sent to the ComIF over the rawPacket buffer.
*/
ReturnValue_t handleAction(ParamSetAction *action);
ReturnValue_t handleAction(RequestHkTableAction *action);
ReturnValue_t handleAction(PrintSwitchVIAction *action);
ReturnValue_t handleAction(PrintLatchupsAction *action);
protected: protected:
static const uint8_t MAX_PACKET_LEN = 36; static const uint8_t MAX_PACKET_LEN = 36;
static const uint8_t PARAM_SET_OK = 1; static const uint8_t PARAM_SET_OK = 1;
static const uint8_t PING_REPLY_SIZE = 2; static const uint8_t PING_REPLY_SIZE = 2;
static const uint8_t CONFIG_TABLE_ID = 1;
static const uint8_t HK_TABLE_ID = 4;
uint8_t rememberRequestedSize = 0; uint8_t rememberRequestedSize = 0;
uint8_t rememberCommandId = GOMSPACE::NONE; uint8_t rememberCommandId = GOMSPACE::NONE;
@ -67,28 +99,31 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
LocalPoolDataSetBase *hkTableDataset = nullptr; LocalPoolDataSetBase *hkTableDataset = nullptr;
PingAction pingAction = PingAction(this);
RebootAction rebootAction = RebootAction(this);
GndwdtResetAction gndwdtResetAction = GndwdtResetAction(this);
ParamGetAction paramGetAction = ParamGetAction(this);
ParamSetAction paramSetAction = ParamSetAction(this);
RequestHkTableAction requestHkTableAction = RequestHkTableAction(this);
PrintSwitchVIAction printSwitchVIAction = PrintSwitchVIAction(this);
PrintLatchupsAction printLatchupsAction = PrintLatchupsAction(this);
void doStartUp() override; void doStartUp() override;
void doShutDown() override; void doShutDown() override;
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override; ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override;
virtual void fillCommandAndReplyMap() override; virtual void fillCommandAndReplyMap() override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) override;
ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId, ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId,
size_t *foundLen) override; size_t *foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override; ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
void setNormalDatapoolEntriesInvalid() override; void setNormalDatapoolEntriesInvalid() override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
/**
* @brief The command to generate a request to receive the full housekeeping table is device
* specific. Thus the child has to build this command.
*/
virtual ReturnValue_t generateRequestFullHkTableCmd(uint16_t hkTableSize);
/** /**
* This command handles printing the HK table to the console. This is useful for debugging * This command handles printing the HK table to the console. This is useful for debugging
* purposes * purposes
* @return * @return
* TODO replace by overriding the handleAction()?
*/ */
virtual ReturnValue_t printStatus(DeviceCommandId_t cmd); virtual ReturnValue_t printStatus(DeviceCommandId_t cmd);
@ -117,46 +152,18 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
std::array<uint8_t, PDU::CHANNELS_LEN> initOutEnb); std::array<uint8_t, PDU::CHANNELS_LEN> initOutEnb);
private: private:
SetParamMessageUnpacker setParamCacher; SetParamMessageCache setParamCacher;
/**
* @brief Function to generate the command to set a parameter. Command
* will be sent to the ComIF over the rawPacket buffer.
*/
ReturnValue_t generateSetParamCommand(const uint8_t *commandData, size_t commandDataLen);
/** /**
* Callback is called on a parameter set command. It is called before executing it and after * Callback is called on a parameter set command. It is called before executing it and
* after successful execution * after successful execution
* @param unpacker Passed before * @param unpacker Passed before
* @param beforeSet False for callback before execution, true if called after successful * @param beforeSet False for callback before execution, true if called after successful
* execution * execution
* @return * @return
*/ */
virtual ReturnValue_t setParamCallback(SetParamMessageUnpacker &unpacker, bool afterExecution); virtual ReturnValue_t setParamCallback(uint16_t address, uint32_t value, uint8_t valueBytes,
bool afterExecution);
/**
* @brief Function to generate the command to get a parameter from a
* gomspace device. Command will be sent to the ComIF over the
* rawPacket buffer.
*/
ReturnValue_t generateGetParamCommand(const uint8_t *commandData, size_t commandDataLen);
/**
* @brief Function to generate the ping command for the ComIF.
*/
ReturnValue_t generatePingCommand(const uint8_t *commandData, size_t commandDataLen);
/**
* @brief Function to generate the command to reboot a gomspace device
* via the ComIF.
*/
void generateRebootCommand();
/**
* @brief Function to generate the command to force a ground watchdog
* reset in a gomspace device.
*/
ReturnValue_t generateResetWatchdogCmd();
}; };
#endif /* MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_ */ #endif /* MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_ */

View File

@ -104,39 +104,21 @@ void HeaterHandler::readCommandQueue() {
} while (result == RETURN_OK); } while (result == RETURN_OK);
} }
ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t HeaterHandler::executeAction(Action* action) { return action->handle(); }
const uint8_t* data, size_t size) {
if (data == nullptr or size < 3) {
return HasActionsIF::INVALID_PARAMETERS;
}
if (actionId != SWITCH_HEATER) {
return COMMAND_NOT_SUPPORTED;
}
auto switchNr = data[0];
if (switchNr > 7) {
return HasActionsIF::INVALID_PARAMETERS;
}
auto& heater = heaterVec.at(switchNr);
auto actionRaw = data[1]; ReturnValue_t HeaterHandler::handleAction(SetHeaterAction* heaterAction) {
if (actionRaw != 0 and actionRaw != 1) { auto& heater = heaterVec.at(heaterAction->switchNr);
return HasActionsIF::INVALID_PARAMETERS; auto action = heaterAction->switchAction.value;
}
auto action = static_cast<SwitchAction>(data[1]);
// Always accepts OFF commands // Always accepts OFF commands
if (action == SwitchAction::SET_SWITCH_ON) { if (action == SetHeaterAction::SwitchAction::SET_SWITCH_ON) {
HasHealthIF::HealthState health = heater.healthDevice->getHealth(); HasHealthIF::HealthState health = heater.healthDevice->getHealth();
if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY or if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY or
health == HasHealthIF::NEEDS_RECOVERY) { health == HasHealthIF::NEEDS_RECOVERY) {
return HasHealthIF::OBJECT_NOT_HEALTHY; return HasHealthIF::OBJECT_NOT_HEALTHY;
} }
CmdSourceParam cmdSource = CmdSourceParam::EXTERNAL; auto cmdSource = heaterAction->cmdSource.value;
uint8_t cmdSourceRaw = data[2]; if (health == HasHealthIF::EXTERNAL_CONTROL and
if (cmdSourceRaw > 1) { cmdSource == SetHeaterAction::CmdSourceParam::INTERNAL) {
return HasActionsIF::INVALID_PARAMETERS;
}
cmdSource = static_cast<CmdSourceParam>(data[2]);
if (health == HasHealthIF::EXTERNAL_CONTROL and cmdSource == CmdSourceParam::INTERNAL) {
return HasHealthIF::IS_EXTERNALLY_CONTROLLED; return HasHealthIF::IS_EXTERNALLY_CONTROLLED;
} }
} }
@ -146,7 +128,7 @@ ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId, MessageQueueId_t
} }
heater.action = action; heater.action = action;
heater.cmdActive = true; heater.cmdActive = true;
heater.replyQueue = commandedBy; heater.replyQueue = heaterAction->commandedBy;
return RETURN_OK; return RETURN_OK;
} }
@ -158,13 +140,13 @@ ReturnValue_t HeaterHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t o
switch (onOff) { switch (onOff) {
case PowerSwitchIF::SWITCH_ON: case PowerSwitchIF::SWITCH_ON:
commandData[0] = switchNr; commandData[0] = switchNr;
commandData[1] = SET_SWITCH_ON; commandData[1] = static_cast<uint8_t>(SetHeaterAction::SwitchAction::SET_SWITCH_ON);
commandData[2] = CmdSourceParam::INTERNAL; commandData[2] = static_cast<uint8_t>(SetHeaterAction::CmdSourceParam::INTERNAL);
break; break;
case PowerSwitchIF::SWITCH_OFF: case PowerSwitchIF::SWITCH_OFF:
commandData[0] = switchNr; commandData[0] = switchNr;
commandData[1] = SET_SWITCH_OFF; commandData[1] = static_cast<uint8_t>(SetHeaterAction::SwitchAction::SET_SWITCH_OFF);
commandData[2] = CmdSourceParam::INTERNAL; commandData[2] = static_cast<uint8_t>(SetHeaterAction::CmdSourceParam::INTERNAL);
break; break;
default: default:
sif::error << "HeaterHandler::sendSwitchCommand: Invalid switch request" << std::endl; sif::error << "HeaterHandler::sendSwitchCommand: Invalid switch request" << std::endl;
@ -174,7 +156,8 @@ ReturnValue_t HeaterHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t o
result = ipcStore->addData(&storeAddress, commandData, sizeof(commandData)); result = ipcStore->addData(&storeAddress, commandData, sizeof(commandData));
if (result == RETURN_OK) { if (result == RETURN_OK) {
CommandMessage message; CommandMessage message;
ActionMessage::setCommand(&message, SWITCH_HEATER, storeAddress); ActionMessage::setCommand(&message, static_cast<ActionId_t>(HeaterCommands::SWITCH_HEATER),
storeAddress);
/* Send heater command to own command queue */ /* Send heater command to own command queue */
result = commandQueue->sendMessage(commandQueue->getId(), &message, 0); result = commandQueue->sendMessage(commandQueue->getId(), &message, 0);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -193,7 +176,7 @@ void HeaterHandler::handleSwitchHandling() {
// will shut down the heater // will shut down the heater
if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY) { if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY) {
heaterVec[idx].cmdActive = true; heaterVec[idx].cmdActive = true;
heaterVec[idx].action = SET_SWITCH_OFF; heaterVec[idx].action = SetHeaterAction::SwitchAction::SET_SWITCH_OFF;
triggerEvent(FAULTY_HEATER_WAS_ON, idx, 0); triggerEvent(FAULTY_HEATER_WAS_ON, idx, 0);
handleSwitchOffCommand(static_cast<heater::Switchers>(idx)); handleSwitchOffCommand(static_cast<heater::Switchers>(idx));
continue; continue;
@ -201,10 +184,10 @@ void HeaterHandler::handleSwitchHandling() {
} }
if (heaterVec[idx].cmdActive) { if (heaterVec[idx].cmdActive) {
switch (heaterVec[idx].action) { switch (heaterVec[idx].action) {
case SET_SWITCH_ON: case SetHeaterAction::SwitchAction::SET_SWITCH_ON:
handleSwitchOnCommand(static_cast<heater::Switchers>(idx)); handleSwitchOnCommand(static_cast<heater::Switchers>(idx));
break; break;
case SET_SWITCH_OFF: case SetHeaterAction::SwitchAction::SET_SWITCH_OFF:
handleSwitchOffCommand(static_cast<heater::Switchers>(idx)); handleSwitchOffCommand(static_cast<heater::Switchers>(idx));
break; break;
default: default:
@ -228,7 +211,8 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switchers heaterIdx) {
heater.cmdActive = false; heater.cmdActive = false;
heater.waitMainSwitchOn = false; heater.waitMainSwitchOn = false;
if (heater.replyQueue != commandQueue->getId()) { if (heater.replyQueue != commandQueue->getId()) {
actionHelper.finish(false, heater.replyQueue, heater.action, MAIN_SWITCH_SET_TIMEOUT); actionHelper.finish(false, heater.replyQueue, static_cast<ActionId_t>(heater.action),
MAIN_SWITCH_SET_TIMEOUT);
} }
return; return;
} }
@ -254,9 +238,11 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switchers heaterIdx) {
// HeaterHandler itself // HeaterHandler itself
if (heater.replyQueue != commandQueue->getId()) { if (heater.replyQueue != commandQueue->getId()) {
if (result == RETURN_OK) { if (result == RETURN_OK) {
actionHelper.finish(true, heater.replyQueue, heater.action, result); actionHelper.finish(true, heater.replyQueue, static_cast<ActionId_t>(heater.action),
result);
} else { } else {
actionHelper.finish(false, heater.replyQueue, heater.action, result); actionHelper.finish(false, heater.replyQueue, static_cast<ActionId_t>(heater.action),
result);
} }
} }
heater.cmdActive = false; heater.cmdActive = false;
@ -272,7 +258,8 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switchers heaterIdx) {
sif::debug << "HeaterHandler::handleSwitchHandling: Failed to get state of" sif::debug << "HeaterHandler::handleSwitchHandling: Failed to get state of"
<< " main line switch" << std::endl; << " main line switch" << std::endl;
if (heater.replyQueue != commandQueue->getId()) { if (heater.replyQueue != commandQueue->getId()) {
actionHelper.finish(false, heater.replyQueue, heater.action, mainSwitchState); actionHelper.finish(false, heater.replyQueue, static_cast<ActionId_t>(heater.action),
mainSwitchState);
} }
heater.cmdActive = false; heater.cmdActive = false;
} }
@ -308,9 +295,9 @@ void HeaterHandler::handleSwitchOffCommand(heater::Switchers heaterIdx) {
if (heater.replyQueue != NO_COMMANDER) { if (heater.replyQueue != NO_COMMANDER) {
// Report back switch command reply if necessary // Report back switch command reply if necessary
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
actionHelper.finish(true, heater.replyQueue, heater.action, result); actionHelper.finish(true, heater.replyQueue, static_cast<ActionId_t>(heater.action), result);
} else { } else {
actionHelper.finish(false, heater.replyQueue, heater.action, result); actionHelper.finish(false, heater.replyQueue, static_cast<ActionId_t>(heater.action), result);
} }
} }
heater.cmdActive = false; heater.cmdActive = false;
@ -333,6 +320,8 @@ bool HeaterHandler::allSwitchesOff() {
MessageQueueId_t HeaterHandler::getCommandQueue() const { return commandQueue->getId(); } MessageQueueId_t HeaterHandler::getCommandQueue() const { return commandQueue->getId(); }
ActionHelper* HeaterHandler::getActionHelper() { return &actionHelper; }
ReturnValue_t HeaterHandler::sendFuseOnCommand(uint8_t fuseNr) { return RETURN_OK; } ReturnValue_t HeaterHandler::sendFuseOnCommand(uint8_t fuseNr) { return RETURN_OK; }
ReturnValue_t HeaterHandler::getSwitchState(uint8_t switchNr) const { ReturnValue_t HeaterHandler::getSwitchState(uint8_t switchNr) const {

View File

@ -17,6 +17,7 @@
#include <array> #include <array>
#include <vector> #include <vector>
#include "devicedefinitions/HeaterDefinitions.h"
#include "devices/heaterSwitcherList.h" #include "devices/heaterSwitcherList.h"
class PowerSwitchIF; class PowerSwitchIF;
@ -47,11 +48,6 @@ class HeaterHandler : public ExecutableObjectIF,
static const ReturnValue_t MAIN_SWITCH_SET_TIMEOUT = MAKE_RETURN_CODE(0xA4); static const ReturnValue_t MAIN_SWITCH_SET_TIMEOUT = MAKE_RETURN_CODE(0xA4);
static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5); static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5);
enum CmdSourceParam : uint8_t { INTERNAL = 0, EXTERNAL = 1 };
/** Device command IDs */
static const DeviceCommandId_t SWITCH_HEATER = 0x0;
HeaterHandler(object_id_t setObjectId, GpioIF* gpioInterface_, HeaterHelper helper, HeaterHandler(object_id_t setObjectId, GpioIF* gpioInterface_, HeaterHelper helper,
PowerSwitchIF* mainLineSwitcherObjectId, power::Switch_t mainLineSwitch); PowerSwitchIF* mainLineSwitcherObjectId, power::Switch_t mainLineSwitch);
@ -70,8 +66,10 @@ class HeaterHandler : public ExecutableObjectIF,
uint32_t getSwitchDelayMs(void) const override; uint32_t getSwitchDelayMs(void) const override;
MessageQueueId_t getCommandQueue() const override; MessageQueueId_t getCommandQueue() const override;
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ActionHelper* getActionHelper() override;
const uint8_t* data, size_t size) override; ReturnValue_t executeAction(Action* action) override;
ReturnValue_t handleAction(SetHeaterAction* heaterAction);
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
private: private:
@ -89,7 +87,6 @@ class HeaterHandler : public ExecutableObjectIF,
static const MessageQueueId_t NO_COMMANDER = 0; static const MessageQueueId_t NO_COMMANDER = 0;
enum SwitchState : bool { ON = true, OFF = false }; enum SwitchState : bool { ON = true, OFF = false };
enum SwitchAction : uint8_t { SET_SWITCH_OFF, SET_SWITCH_ON, NONE };
/** /**
* @brief Struct holding information about a heater command to execute. * @brief Struct holding information about a heater command to execute.
@ -106,7 +103,7 @@ class HeaterHandler : public ExecutableObjectIF,
: healthDevice(pair.first), gpioId(pair.second), switchState(initState) {} : healthDevice(pair.first), gpioId(pair.second), switchState(initState) {}
HealthDevice* healthDevice = nullptr; HealthDevice* healthDevice = nullptr;
gpioId_t gpioId = gpio::NO_GPIO; gpioId_t gpioId = gpio::NO_GPIO;
SwitchAction action = SwitchAction::NONE; SetHeaterAction::SwitchAction action = SetHeaterAction::SwitchAction::NONE;
MessageQueueId_t replyQueue = MessageQueueIF::NO_QUEUE; MessageQueueId_t replyQueue = MessageQueueIF::NO_QUEUE;
bool cmdActive = false; bool cmdActive = false;
SwitchState switchState = SwitchState::OFF; SwitchState switchState = SwitchState::OFF;
@ -140,6 +137,8 @@ class HeaterHandler : public ExecutableObjectIF,
ActionHelper actionHelper; ActionHelper actionHelper;
SetHeaterAction setHeaterAction = SetHeaterAction(this);
StorageManagerIF* ipcStore = nullptr; StorageManagerIF* ipcStore = nullptr;
void readCommandQueue(); void readCommandQueue();

View File

@ -16,7 +16,7 @@ P60DockHandler::~P60DockHandler() {}
ReturnValue_t P60DockHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) { ReturnValue_t P60DockHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
*id = GOMSPACE::REQUEST_HK_TABLE; *id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0); return requestHkTableAction.handle();
} }
void P60DockHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) { void P60DockHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {

View File

@ -16,7 +16,7 @@ PDU1Handler::~PDU1Handler() {}
ReturnValue_t PDU1Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) { ReturnValue_t PDU1Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
*id = GOMSPACE::REQUEST_HK_TABLE; *id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0); return requestHkTableAction.handle();
} }
void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) { void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
@ -29,49 +29,48 @@ void PDU1Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, vo
this->hookArgs = args; this->hookArgs = args;
} }
ReturnValue_t PDU1Handler::setParamCallback(SetParamMessageUnpacker &unpacker, ReturnValue_t PDU1Handler::setParamCallback(uint16_t address, uint32_t value, uint8_t valueBytes, bool afterExecution) {
bool afterExecution) {
using namespace PDU1; using namespace PDU1;
GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU1; GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU1;
if (not afterExecution) { if (not afterExecution) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
if (channelSwitchHook != nullptr and unpacker.getParameterSize() == 1) { if (channelSwitchHook != nullptr and valueBytes == 1) {
switch (unpacker.getAddress()) { switch (address) {
case (CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3): { case (CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3): {
channelSwitchHook(pdu, 0, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 0, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_SYRLINKS): { case (CONFIG_ADDRESS_OUT_EN_SYRLINKS): {
channelSwitchHook(pdu, 1, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 1, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_STAR_TRACKER): { case (CONFIG_ADDRESS_OUT_EN_STAR_TRACKER): {
channelSwitchHook(pdu, 2, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 2, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_MGT): { case (CONFIG_ADDRESS_OUT_EN_MGT): {
channelSwitchHook(pdu, 3, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 3, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL): { case (CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL): {
channelSwitchHook(pdu, 4, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 4, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP): { case (CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP): {
channelSwitchHook(pdu, 5, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 5, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_PLOC): { case (CONFIG_ADDRESS_OUT_EN_PLOC): {
channelSwitchHook(pdu, 6, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 6, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A): { case (CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A): {
channelSwitchHook(pdu, 7, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 7, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_CHANNEL8): { case (CONFIG_ADDRESS_OUT_EN_CHANNEL8): {
channelSwitchHook(pdu, 8, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 8, value, hookArgs);
break; break;
} }
} }

View File

@ -38,7 +38,7 @@ class PDU1Handler : public GomspaceDeviceHandler {
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override; virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
ReturnValue_t printStatus(DeviceCommandId_t cmd) override; ReturnValue_t printStatus(DeviceCommandId_t cmd) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExectuion) override; ReturnValue_t setParamCallback(uint16_t address, uint32_t value, uint8_t valueBytes, bool afterExecution) override;
private: private:
static constexpr uint8_t MAX_CHANNEL_STR_WIDTH = 24; static constexpr uint8_t MAX_CHANNEL_STR_WIDTH = 24;

View File

@ -16,7 +16,7 @@ PDU2Handler::~PDU2Handler() {}
ReturnValue_t PDU2Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) { ReturnValue_t PDU2Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
*id = GOMSPACE::REQUEST_HK_TABLE; *id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0); return requestHkTableAction.handle();
} }
void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) { void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
@ -127,49 +127,48 @@ void PDU2Handler::printHkTableLatchups() {
printerHelper("Payload Camera", Channels::PAYLOAD_CAMERA); printerHelper("Payload Camera", Channels::PAYLOAD_CAMERA);
} }
ReturnValue_t PDU2Handler::setParamCallback(SetParamMessageUnpacker &unpacker, ReturnValue_t PDU2Handler::setParamCallback(uint16_t address, uint32_t value, uint8_t valueBytes, bool afterExecution) {
bool afterExecution) {
using namespace PDU2; using namespace PDU2;
GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2; GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2;
if (not afterExecution) { if (not afterExecution) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
if (channelSwitchHook != nullptr and unpacker.getParameterSize() == 1) { if (channelSwitchHook != nullptr and valueBytes == 1) {
switch (unpacker.getAddress()) { switch (address) {
case (CONFIG_ADDRESS_OUT_EN_Q7S): { case (CONFIG_ADDRESS_OUT_EN_Q7S): {
channelSwitchHook(pdu, 0, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 0, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH1): { case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH1): {
channelSwitchHook(pdu, 1, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 1, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_RW): { case (CONFIG_ADDRESS_OUT_EN_RW): {
channelSwitchHook(pdu, 2, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 2, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN): { case (CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN): {
channelSwitchHook(pdu, 3, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 3, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_SUS_REDUNDANT): { case (CONFIG_ADDRESS_OUT_EN_SUS_REDUNDANT): {
channelSwitchHook(pdu, 4, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 4, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM): { case (CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM): {
channelSwitchHook(pdu, 5, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 5, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6): { case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6): {
channelSwitchHook(pdu, 6, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 6, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_B): { case (CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_B): {
channelSwitchHook(pdu, 7, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 7, value, hookArgs);
break; break;
} }
case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_CAMERA): { case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_CAMERA): {
channelSwitchHook(pdu, 8, unpacker.getParameter()[0], hookArgs); channelSwitchHook(pdu, 8, value, hookArgs);
break; break;
} }
} }

View File

@ -36,7 +36,7 @@ class PDU2Handler : public GomspaceDeviceHandler {
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override; virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
ReturnValue_t printStatus(DeviceCommandId_t cmd) override; ReturnValue_t printStatus(DeviceCommandId_t cmd) override;
ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExecution) override; ReturnValue_t setParamCallback(uint16_t address, uint32_t value, uint8_t valueBytes, bool afterExecution) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
private: private:

View File

@ -111,8 +111,10 @@ void SolarArrayDeploymentHandler::performWaitOn8VActions() {
} else { } else {
if (mainSwitchCountdown.hasTimedOut()) { if (mainSwitchCountdown.hasTimedOut()) {
triggerEvent(MAIN_SWITCH_ON_TIMEOUT); triggerEvent(MAIN_SWITCH_ON_TIMEOUT);
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, actionHelper.finish(
MAIN_SWITCH_TIMEOUT_FAILURE); false, rememberCommanderId,
static_cast<DeviceCommandId_t>(SolarArrayDeploymentCommands::DEPLOY_SOLAR_ARRAYS),
MAIN_SWITCH_TIMEOUT_FAILURE);
stateMachine = WAIT_ON_DELOYMENT_COMMAND; stateMachine = WAIT_ON_DELOYMENT_COMMAND;
} }
} }
@ -129,7 +131,10 @@ void SolarArrayDeploymentHandler::switchDeploymentTransistors() {
* the deployment sequence. */ * the deployment sequence. */
stateMachine = WAIT_ON_DELOYMENT_COMMAND; stateMachine = WAIT_ON_DELOYMENT_COMMAND;
triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED);
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); actionHelper.finish(
false, rememberCommanderId,
static_cast<DeviceCommandId_t>(SolarArrayDeploymentCommands::DEPLOY_SOLAR_ARRAYS),
SWITCHING_DEPL_SA1_FAILED);
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
} }
result = gpioInterface->pullHigh(deplSA2); result = gpioInterface->pullHigh(deplSA2);
@ -139,7 +144,10 @@ void SolarArrayDeploymentHandler::switchDeploymentTransistors() {
<< std::endl; << std::endl;
stateMachine = WAIT_ON_DELOYMENT_COMMAND; stateMachine = WAIT_ON_DELOYMENT_COMMAND;
triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED);
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED); actionHelper.finish(
false, rememberCommanderId,
static_cast<DeviceCommandId_t>(SolarArrayDeploymentCommands::DEPLOY_SOLAR_ARRAYS),
SWITCHING_DEPL_SA2_FAILED);
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
} }
deploymentCountdown.setTimeout(burnTimeMs); deploymentCountdown.setTimeout(burnTimeMs);
@ -149,7 +157,10 @@ void SolarArrayDeploymentHandler::switchDeploymentTransistors() {
void SolarArrayDeploymentHandler::handleDeploymentFinish() { void SolarArrayDeploymentHandler::handleDeploymentFinish() {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
if (deploymentCountdown.hasTimedOut()) { if (deploymentCountdown.hasTimedOut()) {
actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, RETURN_OK); actionHelper.finish(
true, rememberCommanderId,
static_cast<DeviceCommandId_t>(SolarArrayDeploymentCommands::DEPLOY_SOLAR_ARRAYS),
RETURN_OK);
result = gpioInterface->pullLow(deplSA1); result = gpioInterface->pullLow(deplSA1);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
@ -181,27 +192,24 @@ void SolarArrayDeploymentHandler::readCommandQueue() {
} }
} }
ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, ReturnValue_t SolarArrayDeploymentHandler::executeAction(Action* action) {
MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) {
ReturnValue_t result;
if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) { if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) {
sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in" sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in"
<< "waiting-on-command-state" << std::endl; << "waiting-on-command-state" << std::endl;
return DEPLOYMENT_ALREADY_EXECUTING; return DEPLOYMENT_ALREADY_EXECUTING;
} }
if (actionId != DEPLOY_SOLAR_ARRAYS) { // delegates to SolarArrayDeploymentHandler::handleAction()
sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command" return action->handle();
<< std::endl; }
result = COMMAND_NOT_SUPPORTED;
} else { ReturnValue_t SolarArrayDeploymentHandler::handleAction(SolarArrayDeploymentAction* action) {
stateMachine = SWITCH_8V_ON; stateMachine = SWITCH_8V_ON;
rememberCommanderId = commandedBy; rememberCommanderId = action->commandedBy;
result = RETURN_OK; return RETURN_OK;
}
return result;
} }
MessageQueueId_t SolarArrayDeploymentHandler::getCommandQueue() const { MessageQueueId_t SolarArrayDeploymentHandler::getCommandQueue() const {
return commandQueue->getId(); return commandQueue->getId();
} }
ActionHelper* SolarArrayDeploymentHandler::getActionHelper() { return &actionHelper; }

View File

@ -14,6 +14,8 @@
#include <unordered_map> #include <unordered_map>
#include "devicedefinitions/SolarArrayDeploymentDefinitions.h"
/** /**
* @brief This class is used to control the solar array deployment. * @brief This class is used to control the solar array deployment.
* *
@ -24,8 +26,6 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
public HasReturnvaluesIF, public HasReturnvaluesIF,
public HasActionsIF { public HasActionsIF {
public: public:
static const DeviceCommandId_t DEPLOY_SOLAR_ARRAYS = 0x5;
/** /**
* @brief constructor * @brief constructor
* *
@ -51,8 +51,9 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override; virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
virtual MessageQueueId_t getCommandQueue() const override; virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, virtual ActionHelper* getActionHelper() override;
const uint8_t* data, size_t size) override; virtual ReturnValue_t executeAction(Action* action) override;
ReturnValue_t handleAction(SolarArrayDeploymentAction* action);
virtual ReturnValue_t initialize() override; virtual ReturnValue_t initialize() override;
private: private:
@ -129,6 +130,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
ActionHelper actionHelper; ActionHelper actionHelper;
SolarArrayDeploymentAction deploymentAction = SolarArrayDeploymentAction(this);
void readCommandQueue(); void readCommandQueue();
/** /**

View File

@ -332,14 +332,37 @@ class Pdu2FullTableReply : public SerialLinkedListAdapter<SerializeIF> {
LinkedElement<SerializeIF> dataset; LinkedElement<SerializeIF> dataset;
}; };
class SetParamMessageCache {
public:
SetParamMessageCache() : address(0), parameter(0), parameterSize(1) {}
void set(uint16_t address, uint32_t parameter, uint8_t parameterSize) {
this->address = address;
this->parameter = parameter;
this->parameterSize = parameterSize;
}
uint16_t getAddress() { return address; }
uint32_t getParameter() { return parameter; }
uint8_t getParameterSize() { return parameterSize; }
private:
uint16_t address;
uint32_t parameter;
uint8_t parameterSize;
};
/** /**
* @brief This class helps to unpack information from an action message * @brief This class helps to unpack information from an action message
* to set a parameter in gomspace devices. The action message can be * to set a parameter in gomspace devices. The action message can be
* for example received from the PUS Service 8. * for example received from the PUS Service 8.
*/ */
/*
class SetParamMessageUnpacker : public SerialLinkedListAdapter<SerializeIF> { class SetParamMessageUnpacker : public SerialLinkedListAdapter<SerializeIF> {
public: public:
/* Largest parameter is a uint32_t */ // Largest parameter is a uint32_t
static const uint32_t MAX_SIZE = 4; static const uint32_t MAX_SIZE = 4;
SetParamMessageUnpacker() { setLinks(); } SetParamMessageUnpacker() { setLinks(); }
@ -358,7 +381,7 @@ class SetParamMessageUnpacker : public SerialLinkedListAdapter<SerializeIF> {
SetParamMessageUnpacker(const SetParamMessageUnpacker &message); SetParamMessageUnpacker(const SetParamMessageUnpacker &message);
SerializeElement<uint16_t> address; SerializeElement<uint16_t> address;
SerializeElement<SerialFixedArrayListAdapter<uint8_t, MAX_SIZE, uint8_t>> parameter; SerializeElement<SerialFixedArrayListAdapter<uint8_t, MAX_SIZE, uint8_t>> parameter;
}; };*/
/** /**
* @brief This class generates a message which can be sent to the GomspaceDeviceHandler to * @brief This class generates a message which can be sent to the GomspaceDeviceHandler to
@ -405,6 +428,7 @@ class GomspaceSetParamMessage : public SerialLinkedListAdapter<SerializeIF> {
* to get a parameter from gomspace devices. The action message can be * to get a parameter from gomspace devices. The action message can be
* for example received from the PUS Service 8. * for example received from the PUS Service 8.
*/ */
/*
class GetParamMessageUnpacker : public SerialLinkedListAdapter<SerializeIF> { class GetParamMessageUnpacker : public SerialLinkedListAdapter<SerializeIF> {
public: public:
GetParamMessageUnpacker() { setLinks(); } GetParamMessageUnpacker() { setLinks(); }
@ -424,8 +448,8 @@ class GetParamMessageUnpacker : public SerialLinkedListAdapter<SerializeIF> {
} }
SerializeElement<uint8_t> tableId; SerializeElement<uint8_t> tableId;
SerializeElement<uint16_t> address; // The memory address offset within the table SerializeElement<uint16_t> address; // The memory address offset within the table
/* The size of the requested value (e.g. temperature is a uint16_t value) */ // The size of the requested value (e.g. temperature is a uint16_t value)
SerializeElement<uint8_t> parameterSize; SerializeElement<uint8_t> parameterSize;
}; };*/
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEPACKETS_H_ */ #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEPACKETS_H_ */

View File

@ -0,0 +1,81 @@
#pragma once
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include "GomspaceDefinitions.h"
class GomspaceDeviceHandler;
class PingAction : public TemplateAction<GomspaceDeviceHandler, PingAction, GOMSPACE::GomspaceCommands> {
public:
PingAction(GomspaceDeviceHandler* owner) : TemplateAction(owner, GOMSPACE::PING) {}
// TODO array
Parameter<uint8_t> pingData = Parameter<uint8_t>::createParameter(this, "Ping Data");
};
class RebootAction : public TemplateAction<GomspaceDeviceHandler, RebootAction, GOMSPACE::GomspaceCommands> {
public:
RebootAction(GomspaceDeviceHandler* owner) : TemplateAction(owner, GOMSPACE::REBOOT) {}
};
class GndwdtResetAction
: public TemplateAction<GomspaceDeviceHandler, GndwdtResetAction, GOMSPACE::GomspaceCommands> {
public:
GndwdtResetAction(GomspaceDeviceHandler* owner)
: TemplateAction(owner, GOMSPACE::GNDWDT_RESET) {}
};
class ParamGetAction
: public TemplateAction<GomspaceDeviceHandler, ParamGetAction, GOMSPACE::GomspaceCommands> {
public:
FSFW_ENUM(ParameterByteSize, uint8_t,
((ONE_BYTE, 1, "One Byte"))((TWO_BYTES, 2, "Two Bytes"))((FOUR_BYTES, 4, "Four Bytes")))
FSFW_ENUM(TableId, uint8_t,
((CONFIG_TABLE_ID, 1, "Config Table"))((HK_TABLE_ID, 4, "Housekeeping Table")))
ParamGetAction(GomspaceDeviceHandler* owner)
: TemplateAction(owner, GOMSPACE::PARAM_GET) {}
Parameter<TableId> tableId =
Parameter<TableId>::createParameter(this, "Table");
Parameter<uint16_t> address = Parameter<uint16_t>::createParameter(this, "Address");
Parameter<ParameterByteSize> parameterSize =
Parameter<ParameterByteSize>::createParameter(this, "Parameter Size");
};
class ParamSetAction
: public TemplateAction<GomspaceDeviceHandler, ParamSetAction, GOMSPACE::GomspaceCommands> {
public:
FSFW_ENUM(ParameterByteSize, uint8_t,
((ONE_BYTE, 1, "One Byte"))((TWO_BYTES, 2, "Two Bytes"))((FOUR_BYTES, 4, "Four Bytes")))
ParamSetAction(GomspaceDeviceHandler* owner)
: TemplateAction(owner, GOMSPACE::PARAM_SET) {}
Parameter<uint16_t> address = Parameter<uint16_t>::createParameter(this, "Address");
Parameter<uint32_t> parameter = Parameter<uint32_t>::createParameter(this, "Parameter Value");
Parameter<ParameterByteSize> parameterSize =
Parameter<ParameterByteSize>::createParameter(this, "Parameter Size");
};
class RequestHkTableAction
: public TemplateAction<GomspaceDeviceHandler, RequestHkTableAction, GOMSPACE::GomspaceCommands> {
public:
RequestHkTableAction(GomspaceDeviceHandler* owner)
: TemplateAction(owner, GOMSPACE::REQUEST_HK_TABLE) {}
};
class PrintSwitchVIAction
: public TemplateAction<GomspaceDeviceHandler, PrintSwitchVIAction, GOMSPACE::GomspaceCommands> {
public:
PrintSwitchVIAction(GomspaceDeviceHandler* owner)
: TemplateAction(owner, GOMSPACE::PRINT_SWITCH_V_I) {}
};
class PrintLatchupsAction
: public TemplateAction<GomspaceDeviceHandler, PrintLatchupsAction, GOMSPACE::GomspaceCommands> {
public:
PrintLatchupsAction(GomspaceDeviceHandler* owner)
: TemplateAction(owner, GOMSPACE::PRINT_LATCHUPS) {}
};

View File

@ -4,6 +4,7 @@
#include <fsfw/datapoollocal/LocalPoolVariable.h> #include <fsfw/datapoollocal/LocalPoolVariable.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.h> #include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h> #include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/introspection/ClasslessEnum.h>
#include <fsfw/power/definitions.h> #include <fsfw/power/definitions.h>
#include <cstdint> #include <cstdint>
@ -12,6 +13,18 @@
namespace GOMSPACE { namespace GOMSPACE {
/**
* Device commands are derived from the rparam.h of the gomspace lib..
* IDs above 50 are reserved for device specific commands.
*/
FSFW_CLASSLESS_ENUM(
GomspaceCommands, DeviceCommandId_t,
((PING, 1, "Ping"))((NONE, 2, "None (used internally)"))((REBOOT, 4, "Reboot"))(
(GNDWDT_RESET, 9, "Reset Watchdog"))((PARAM_GET, 0, "Get Parameter"))(
(PARAM_SET, 255, "Set Parameter"))((REQUEST_HK_TABLE, 16, "Request Housekeeping Table"))(
(PRINT_SWITCH_V_I, 32, "Print switch states, voltages and currents to the console"))(
(PRINT_LATCHUPS, 33, "Print Latchups to the console")))
enum class Pdu { PDU1, PDU2 }; enum class Pdu { PDU1, PDU2 };
using ChannelSwitchHook = void (*)(Pdu pdu, uint8_t channel, bool on, void* args); using ChannelSwitchHook = void (*)(Pdu pdu, uint8_t channel, bool on, void* args);
@ -26,23 +39,6 @@ static const uint8_t REBOOT_PORT = 4;
static const uint8_t PARAM_PORT = 7; static const uint8_t PARAM_PORT = 7;
static const uint8_t P60_PORT_GNDWDT_RESET = 9; static const uint8_t P60_PORT_GNDWDT_RESET = 9;
/**
* Device commands are derived from the rparam.h of the gomspace lib..
* IDs above 50 are reserved for device specific commands.
*/
static const DeviceCommandId_t PING = 1; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t NONE = 2; // Set when no command is pending
static const DeviceCommandId_t REBOOT = 4; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t GNDWDT_RESET = 9; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t PARAM_GET = 0; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t PARAM_SET = 255; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t REQUEST_HK_TABLE = 16; //!< [EXPORT] : [COMMAND]
//! [EXPORT] : [COMMAND] Print switch states, voltages and currents to the console
//! For the ACU device, only print voltages and currents of the 6 ACU channels
static const DeviceCommandId_t PRINT_SWITCH_V_I = 32;
static const DeviceCommandId_t PRINT_LATCHUPS = 33;
} // namespace GOMSPACE } // namespace GOMSPACE
namespace P60System { namespace P60System {

View File

@ -0,0 +1,26 @@
#pragma once
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/introspection/Enum.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
class HeaterHandler;
FSFW_ENUM(HeaterCommands, DeviceCommandId_t, ((SWITCH_HEATER, 0x0, "Switch Heater")))
class SetHeaterAction : public TemplateAction<HeaterHandler, SetHeaterAction, HeaterCommands> {
public:
FSFW_ENUM(SwitchAction, uint8_t,
((SET_SWITCH_OFF, "Set switch to Off"))((SET_SWITCH_ON, "Set switch to On")) ((NONE, "No Action")))
FSFW_ENUM(CmdSourceParam, uint8_t, ((INTERNAL, 0, "Internal"))((EXTERNAL, 1, "External")))
SetHeaterAction(HeaterHandler *owner) : TemplateAction(owner, HeaterCommands::SWITCH_HEATER) {}
MinMaxParameter<uint8_t> switchNr =
MinMaxParameter<uint8_t>::createMinMaxParameter(this, "Heater number", 0, 7);
Parameter<SwitchAction> switchAction =
Parameter<SwitchAction>::createParameter(this, "Switch Action");
Parameter<CmdSourceParam> cmdSource =
Parameter<CmdSourceParam>::createParameter(this, "Command Source");
};

View File

@ -0,0 +1,18 @@
#pragma once
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/introspection/Enum.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
class SolarArrayDeploymentHandler;
FSFW_ENUM(SolarArrayDeploymentCommands, DeviceCommandId_t,((DEPLOY_SOLAR_ARRAYS, 0x05, "Deploy Solar Arrays")))
class SolarArrayDeploymentAction
: public TemplateAction<SolarArrayDeploymentHandler, SolarArrayDeploymentAction,
SolarArrayDeploymentCommands> {
public:
SolarArrayDeploymentAction(SolarArrayDeploymentHandler *owner)
: TemplateAction(owner, SolarArrayDeploymentCommands::DEPLOY_SOLAR_ARRAYS) {}
};

View File

@ -3,7 +3,7 @@
#include <cstring> #include <cstring>
void max1227::prepareExternallyClockedSingleChannelRead(uint8_t *spiBuf, uint8_t channel, void max1227::prepareExternallyClockedSingleChannelRead(uint8_t *spiBuf, uint8_t channel,
size_t &sz) { uint32_t &sz) {
spiBuf[0] = buildConvByte(ScanModes::N_ONCE, channel, false); spiBuf[0] = buildConvByte(ScanModes::N_ONCE, channel, false);
spiBuf[1] = 0x00; spiBuf[1] = 0x00;
spiBuf[2] = 0x00; spiBuf[2] = 0x00;

View File

@ -58,7 +58,7 @@ constexpr uint8_t buildSetupByte(ClkSel clkSel, RefSel refSel, DiffSel diffSel)
* @param n * @param n
* @param sz * @param sz
*/ */
void prepareExternallyClockedSingleChannelRead(uint8_t* spiBuf, uint8_t channel, size_t& sz); void prepareExternallyClockedSingleChannelRead(uint8_t* spiBuf, uint8_t channel, uint32_t& sz);
/** /**
* If there is a wakeup delay, there needs to be a 65 us delay between sending * If there is a wakeup delay, there needs to be a 65 us delay between sending

View File

@ -1,6 +1,7 @@
#include "DualLaneAssemblyBase.h" #include "DualLaneAssemblyBase.h"
#include <fsfw/ipc/QueueFactory.h> #include <fsfw/ipc/QueueFactory.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include "OBSWConfig.h" #include "OBSWConfig.h"
@ -92,6 +93,10 @@ ReturnValue_t DualLaneAssemblyBase::pwrStateMachineWrapper() {
return RETURN_OK; return RETURN_OK;
} }
ModeDefinitionHelper DualLaneAssemblyBase::getModeDefinitionHelper() {
return ModeDefinitionHelper::create<DeviceHandlerIF::DeviceHandlerMode, duallane::Submodes>();
}
ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_t submode) { ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_t submode) {
using namespace duallane; using namespace duallane;
if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) {

View File

@ -22,6 +22,8 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF {
pcdu::Switches switch1, pcdu::Switches switch2, Event pwrSwitchTimeoutEvent, pcdu::Switches switch1, pcdu::Switches switch2, Event pwrSwitchTimeoutEvent,
Event sideSwitchNotAllowedEvent, Event transitionOtherSideFailedEvent); Event sideSwitchNotAllowedEvent, Event transitionOtherSideFailedEvent);
ModeDefinitionHelper getModeDefinitionHelper() override;
protected: protected:
// This helper object complete encapsulates power switching // This helper object complete encapsulates power switching
DualLanePowerStateMachine pwrStateMachine; DualLanePowerStateMachine pwrStateMachine;

View File

@ -189,3 +189,7 @@ void RwAssembly::handleModeTransitionFailed(ReturnValue_t result) {
} }
} }
} }
ModeDefinitionHelper RwAssembly::getModeDefinitionHelper() {
return ModeDefinitionHelper::create<DeviceHandlerIF::DeviceHandlerMode, HasModesIF::DefaultSubmode>();
}

View File

@ -15,6 +15,10 @@ class RwAssembly : public AssemblyBase {
RwAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher, RwAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* pwrSwitcher,
power::Switch_t switcher, RwHelper helper); power::Switch_t switcher, RwHelper helper);
~RwAssembly() {}
ModeDefinitionHelper getModeDefinitionHelper() override;
private: private:
static constexpr uint8_t NUMBER_RWS = 4; static constexpr uint8_t NUMBER_RWS = 4;
RwHelper helper; RwHelper helper;

View File

@ -203,3 +203,7 @@ void TcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) {
triggerEvent(MODE_TRANSITION_FAILED, result); triggerEvent(MODE_TRANSITION_FAILED, result);
} }
} }
ModeDefinitionHelper TcsBoardAssembly::getModeDefinitionHelper(){
return ModeDefinitionHelper::create<DeviceHandlerIF::DeviceHandlerMode, HasModesIF::DefaultSubmode>();
}

View File

@ -22,6 +22,8 @@ class TcsBoardAssembly : public AssemblyBase, public ConfirmsFailuresIF {
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
ModeDefinitionHelper getModeDefinitionHelper();
private: private:
static constexpr uint8_t NUMBER_RTDS = 16; static constexpr uint8_t NUMBER_RTDS = 16;
PowerSwitcher switcher; PowerSwitcher switcher;

View File

@ -2,6 +2,7 @@
#define MISSION_SYSTEM_DEFINITIONS_H_ #define MISSION_SYSTEM_DEFINITIONS_H_
#include <fsfw/modes/ModeMessage.h> #include <fsfw/modes/ModeMessage.h>
#include <fsfw/introspection/ClasslessEnum.h>
namespace power { namespace power {
@ -12,7 +13,7 @@ enum class OpCodes { NONE, TO_OFF_DONE, TO_NOT_OFF_DONE, TIMEOUT_OCCURED };
namespace duallane { namespace duallane {
enum Submodes : Submode_t { A_SIDE = 0, B_SIDE = 1, DUAL_MODE = 2 }; FSFW_CLASSLESS_ENUM(Submodes, Submode_t, ((A_SIDE, 0, "Side A")) ((B_SIDE, 1, "Side B")) ((DUAL_MODE, 2, "Dual mode")))
} // namespace duallane } // namespace duallane

View File

@ -0,0 +1,73 @@
#pragma once
#include <fsfw/action/MinMaxParameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/introspection/Enum.h>
class CCSDSHandler;
FSFW_ENUM(
CCSDSCommands, DeviceCommandId_t,
((SET_LOW_RATE, 0, "Set Low rate"))((SET_HIGH_RATE, 1, "Set High Rate"))(
(EN_TRANSMITTER, 2, "Enable Transmitter"))((DISABLE_TRANSMITTER, 3, "Disable Transmitter"))(
(ARBITRARY_RATE, 4, "Set Bit Rate"))((ENABLE_TX_CLK_MANIPULATOR, 5,
"Enable Tx Clock Manipulator"))(
(DISABLE_TX_CLK_MANIPULATOR, 6, "Enable Tx Clock Manipulator"))(
(UPDATE_ON_RISING_EDGE, 7, "update data on rising edge"))((UPDATE_ON_FALLING_EDGE, 8,
"update data on falling edge")))
class SetLowRateAction : public TemplateAction<CCSDSHandler, SetLowRateAction, CCSDSCommands> {
public:
SetLowRateAction(CCSDSHandler* owner)
: TemplateAction(owner, CCSDSCommands::SET_LOW_RATE) {}
};
class SetHighRateAction : public TemplateAction<CCSDSHandler, SetHighRateAction, CCSDSCommands> {
public:
SetHighRateAction(CCSDSHandler* owner)
: TemplateAction(owner, CCSDSCommands::SET_HIGH_RATE) {}
};
class EnTransmitterAction
: public TemplateAction<CCSDSHandler, EnTransmitterAction, CCSDSCommands> {
public:
EnTransmitterAction(CCSDSHandler* owner)
: TemplateAction(owner, CCSDSCommands::EN_TRANSMITTER) {}
};
class DisableTransmitterAction
: public TemplateAction<CCSDSHandler, DisableTransmitterAction, CCSDSCommands> {
public:
DisableTransmitterAction(CCSDSHandler* owner)
: TemplateAction(owner, CCSDSCommands::DISABLE_TRANSMITTER) {}
};
class ArbitraryRateAction
: public TemplateAction<CCSDSHandler, ArbitraryRateAction, CCSDSCommands> {
public:
ArbitraryRateAction(CCSDSHandler* owner)
: TemplateAction(owner, CCSDSCommands::ARBITRARY_RATE) {}
Parameter<uint32_t> bitrate = Parameter<uint32_t>::createParameter(this, "Bitrate");
};
class EnableTxClkManipulatorAction
: public TemplateAction<CCSDSHandler, EnableTxClkManipulatorAction, CCSDSCommands> {
public:
EnableTxClkManipulatorAction(CCSDSHandler* owner)
: TemplateAction(owner, CCSDSCommands::ENABLE_TX_CLK_MANIPULATOR) {}
};
class DisableTxClkManipulatorAction
: public TemplateAction<CCSDSHandler, DisableTxClkManipulatorAction, CCSDSCommands> {
public:
DisableTxClkManipulatorAction(CCSDSHandler* owner)
: TemplateAction(owner, CCSDSCommands::DISABLE_TX_CLK_MANIPULATOR) {}
};
class UpdateOnRisingEdgeAction
: public TemplateAction<CCSDSHandler, UpdateOnRisingEdgeAction, CCSDSCommands> {
public:
UpdateOnRisingEdgeAction(CCSDSHandler* owner)
: TemplateAction(owner, CCSDSCommands::UPDATE_ON_RISING_EDGE) {}
};
class UpdateOnFallingEdgeAction
: public TemplateAction<CCSDSHandler, UpdateOnFallingEdgeAction, CCSDSCommands> {
public:
UpdateOnFallingEdgeAction(CCSDSHandler* owner)
: TemplateAction(owner, CCSDSCommands::UPDATE_ON_FALLING_EDGE) {}
};

View File

@ -159,6 +159,8 @@ void CCSDSHandler::readCommandQueue(void) {
MessageQueueId_t CCSDSHandler::getCommandQueue() const { return commandQueue->getId(); } MessageQueueId_t CCSDSHandler::getCommandQueue() const { return commandQueue->getId(); }
ActionHelper* CCSDSHandler::getActionHelper() { return &actionHelper; }
void CCSDSHandler::addVirtualChannel(VcId_t vcId, VirtualChannel* virtualChannel) { void CCSDSHandler::addVirtualChannel(VcId_t vcId, VirtualChannel* virtualChannel) {
if (vcId > common::NUMBER_OF_VIRTUAL_CHANNELS) { if (vcId > common::NUMBER_OF_VIRTUAL_CHANNELS) {
sif::warning << "CCSDSHandler::addVirtualChannel: Invalid virtual channel ID" << std::endl; sif::warning << "CCSDSHandler::addVirtualChannel: Invalid virtual channel ID" << std::endl;
@ -210,57 +212,74 @@ MessageQueueId_t CCSDSHandler::getRequestQueue() {
return tcDistributorQueueId; return tcDistributorQueueId;
} }
ReturnValue_t CCSDSHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t CCSDSHandler::executeAction(Action* action) { return action->handle(); }
const uint8_t* data, size_t size) {
ReturnValue_t result = RETURN_OK; ReturnValue_t CCSDSHandler::handleAction(SetLowRateAction* action) {
switch (actionId) { ReturnValue_t result = ptmeConfig->setRate(RATE_100KBPS);
case SET_LOW_RATE: { if (result == HasReturnvaluesIF::RETURN_OK) {
result = ptmeConfig->setRate(RATE_100KBPS); return EXECUTION_FINISHED;
break;
}
case SET_HIGH_RATE: {
result = ptmeConfig->setRate(RATE_500KBPS);
break;
}
case ARBITRARY_RATE: {
uint32_t bitrate = 0;
SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG);
result = ptmeConfig->setRate(bitrate);
break;
}
case EN_TRANSMITTER: {
enableTransmit();
return EXECUTION_FINISHED;
}
case DISABLE_TRANSMITTER: {
disableTransmit();
return EXECUTION_FINISHED;
}
case ENABLE_TX_CLK_MANIPULATOR: {
result = ptmeConfig->configTxManipulator(true);
break;
}
case DISABLE_TX_CLK_MANIPULATOR: {
result = ptmeConfig->configTxManipulator(false);
break;
}
case UPDATE_ON_RISING_EDGE: {
result = ptmeConfig->invertTxClock(false);
break;
}
case UPDATE_ON_FALLING_EDGE: {
result = ptmeConfig->invertTxClock(true);
break;
}
default:
return COMMAND_NOT_IMPLEMENTED;
} }
if (result != RETURN_OK) { return result;
return result; }
ReturnValue_t CCSDSHandler::handleAction(SetHighRateAction* action) {
ReturnValue_t result = ptmeConfig->setRate(RATE_500KBPS);
if (result == HasReturnvaluesIF::RETURN_OK) {
return EXECUTION_FINISHED;
} }
return result;
}
ReturnValue_t CCSDSHandler::handleAction(ArbitraryRateAction* action) {
ReturnValue_t result = ptmeConfig->setRate(action->bitrate);
if (result == HasReturnvaluesIF::RETURN_OK) {
return EXECUTION_FINISHED;
}
return result;
}
ReturnValue_t CCSDSHandler::handleAction(EnTransmitterAction* action) {
enableTransmit();
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
ReturnValue_t CCSDSHandler::handleAction(DisableTransmitterAction* action) {
disableTransmit();
return EXECUTION_FINISHED;
}
ReturnValue_t CCSDSHandler::handleAction(EnableTxClkManipulatorAction* action) {
ReturnValue_t result = ptmeConfig->configTxManipulator(true);
if (result == HasReturnvaluesIF::RETURN_OK) {
return EXECUTION_FINISHED;
}
return result;
}
ReturnValue_t CCSDSHandler::handleAction(DisableTxClkManipulatorAction* action) {
ReturnValue_t result = ptmeConfig->configTxManipulator(false);
if (result == HasReturnvaluesIF::RETURN_OK) {
return EXECUTION_FINISHED;
}
return result;
}
ReturnValue_t CCSDSHandler::handleAction(UpdateOnRisingEdgeAction* action) {
ReturnValue_t result = ptmeConfig->invertTxClock(false);
if (result == HasReturnvaluesIF::RETURN_OK) {
return EXECUTION_FINISHED;
}
return result;
}
ReturnValue_t CCSDSHandler::handleAction(UpdateOnFallingEdgeAction* action) {
ReturnValue_t result = ptmeConfig->invertTxClock(true);
if (result == HasReturnvaluesIF::RETURN_OK) {
return EXECUTION_FINISHED;
}
return result;
}
void CCSDSHandler::checkEvents() { void CCSDSHandler::checkEvents() {
EventMessage event; EventMessage event;
for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == RETURN_OK; for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == RETURN_OK;

View File

@ -3,6 +3,7 @@
#include <unordered_map> #include <unordered_map>
#include "CCSDSActions.h"
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "VirtualChannel.h" #include "VirtualChannel.h"
#include "fsfw/action/ActionHelper.h" #include "fsfw/action/ActionHelper.h"
@ -76,8 +77,17 @@ class CCSDSHandler : public SystemObject,
uint16_t getIdentifier() override; uint16_t getIdentifier() override;
MessageQueueId_t getRequestQueue() override; MessageQueueId_t getRequestQueue() override;
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, virtual ActionHelper* getActionHelper() override;
const uint8_t* data, size_t size); virtual ReturnValue_t executeAction(Action* action);
ReturnValue_t handleAction(SetLowRateAction* action);
ReturnValue_t handleAction(SetHighRateAction* action);
ReturnValue_t handleAction(EnTransmitterAction* action);
ReturnValue_t handleAction(DisableTransmitterAction* action);
ReturnValue_t handleAction(ArbitraryRateAction* action);
ReturnValue_t handleAction(EnableTxClkManipulatorAction* action);
ReturnValue_t handleAction(DisableTxClkManipulatorAction* action);
ReturnValue_t handleAction(UpdateOnRisingEdgeAction* action);
ReturnValue_t handleAction(UpdateOnFallingEdgeAction* action);
private: private:
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER; static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER;
@ -85,18 +95,6 @@ class CCSDSHandler : public SystemObject,
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE; static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
static const ActionId_t SET_LOW_RATE = 0;
static const ActionId_t SET_HIGH_RATE = 1;
static const ActionId_t EN_TRANSMITTER = 2;
static const ActionId_t DISABLE_TRANSMITTER = 3;
static const ActionId_t ARBITRARY_RATE = 4;
static const ActionId_t ENABLE_TX_CLK_MANIPULATOR = 5;
static const ActionId_t DISABLE_TX_CLK_MANIPULATOR = 6;
// Will update data with respect to tx clock signal of cadu bitstream on rising edge
static const ActionId_t UPDATE_ON_RISING_EDGE = 7;
// Will update data with respect to tx clock signal of cadu bitstream on falling edge
static const ActionId_t UPDATE_ON_FALLING_EDGE = 8;
// Syrlinks supports two bitrates (200 kbps and 1000 kbps) // Syrlinks supports two bitrates (200 kbps and 1000 kbps)
// Due to convolutional code added by the syrlinks the input frequency must be half the // Due to convolutional code added by the syrlinks the input frequency must be half the
// target frequency // target frequency
@ -145,6 +143,17 @@ class CCSDSHandler : public SystemObject,
bool linkState = DOWN; bool linkState = DOWN;
// instances of the actions
SetLowRateAction setLowRateAction = SetLowRateAction(this);
SetHighRateAction setHighRateAction = SetHighRateAction(this);
EnTransmitterAction enTransmitterAction = EnTransmitterAction(this);
DisableTransmitterAction disableTransmitterAction = DisableTransmitterAction(this);
ArbitraryRateAction arbitraryRateAction = ArbitraryRateAction(this);
EnableTxClkManipulatorAction enableTxClkManipulatorAction = EnableTxClkManipulatorAction(this);
DisableTxClkManipulatorAction disableTxClkManipulatorAction = DisableTxClkManipulatorAction(this);
UpdateOnRisingEdgeAction updateOnRisingEdgeAction = UpdateOnRisingEdgeAction(this);
UpdateOnFallingEdgeAction updateOnFallingEdgeAction = UpdateOnFallingEdgeAction(this);
void readCommandQueue(void); void readCommandQueue(void);
void handleTelemetry(); void handleTelemetry();
void handleTelecommands(); void handleTelecommands();