From a83136515c9614e082166aeb252e1bab96b1132f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 12 Mar 2023 20:51:33 +0100 Subject: [PATCH 1/3] command to execute shell command --- CHANGELOG.md | 4 ++++ bsp_q7s/core/CoreController.cpp | 31 ++++++++++++++++++++++++++++++- bsp_q7s/core/CoreController.h | 11 +++++++++++ fsfw | 2 +- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69d8cf6a..3606d6eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +## Added + +- Added `EXECUTE_SHELL_CMD` action command for `CoreController` to execute arbitrary Linux commands. + # [v1.37.0] 2023-03-11 eive-tmtc: v2.18.1 diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 5c4710d4..702264ab 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -32,7 +32,9 @@ xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP; xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY; CoreController::CoreController(object_id_t objectId) - : ExtendedControllerBase(objectId, 5), opDivider5(5), opDivider10(10), hkSet(this) { + : ExtendedControllerBase(objectId, 5), cmdExecutor(4096), cmdReplyBuf(4096, true), cmdRepliesSizes(128), + opDivider5(5), opDivider10(10), hkSet(this) { + cmdExecutor.setRingBuffer(&cmdReplyBuf, &cmdRepliesSizes); try { sdcMan = SdCardManager::instance(); if (sdcMan == nullptr) { @@ -100,6 +102,19 @@ void CoreController::performControlOperation() { sdStateMachine(); performMountedSdCardOperations(); readHkData(); + if(shellCmdIsExecuting) { + bool replyReceived = false; + // TODO: We could read the data in the ring buffer and send it as an action data reply. + if(cmdExecutor.check(replyReceived) == CommandExecutor::EXECUTION_FINISHED) { + actionHelper.finish(true, successRecipient, EXECUTE_SHELL_CMD); + shellCmdIsExecuting = false; + cmdReplyBuf.clear(); + while(not cmdRepliesSizes.empty()) { + cmdRepliesSizes.pop(); + } + successRecipient = MessageQueueIF::NO_QUEUE; + } + } opDivider5.checkAndIncrement(); opDivider10.checkAndIncrement(); } @@ -301,6 +316,20 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ // Warning: This function will never return, because it reboots the system return actionReboot(data, size); } + case(EXECUTE_SHELL_CMD): { + std::string cmd = std::string(cmd, size); + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or shellCmdIsExecuting) { + return HasActionsIF::IS_BUSY; + } + cmdExecutor.load(cmd, false, false); + ReturnValue_t result = cmdExecutor.execute(); + if(result != returnvalue::OK) { + return result; + } + shellCmdIsExecuting = true; + successRecipient = commandedBy; + return returnvalue::OK; + } default: { return HasActionsIF::INVALID_ACTION_ID; } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index c5e23d48..fa07ec59 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -1,6 +1,8 @@ #ifndef BSP_Q7S_CORE_CORECONTROLLER_H_ #define BSP_Q7S_CORE_CORECONTROLLER_H_ +#include +#include #include #include @@ -98,6 +100,8 @@ class CoreController : public ExtendedControllerBase { //! Reboot using the reboot command static constexpr ActionId_t REBOOT_OBC = 34; + static constexpr ActionId_t EXECUTE_SHELL_CMD = 40; + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); @@ -227,6 +231,13 @@ class CoreController : public ExtendedControllerBase { } sdCommandingInfo; RebootFile rebootFile = {}; + + CommandExecutor cmdExecutor; + SimpleRingBuffer cmdReplyBuf; + DynamicFIFO cmdRepliesSizes; + bool shellCmdIsExecuting = false; + MessageQueueId_t successRecipient = MessageQueueIF::NO_QUEUE; + std::string currMntPrefix; bool timeFileInitDone = false; bool performOneShotSdCardOpsSwitch = false; diff --git a/fsfw b/fsfw index 4d6f6e6b..9a8d775e 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 4d6f6e6b23b5c0486dad6be8abba7681114a05fe +Subproject commit 9a8d775eb1a8788ad844215bf2a42d9f707767c0 From 84adbeda3895bf43bc93dc86ee5a4d998100ec37 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 13 Mar 2023 11:34:51 +0100 Subject: [PATCH 2/3] syrlinks task name fix --- bsp_q7s/core/scheduling.cpp | 8 ++++---- mission/core/pollingSeqTables.cpp | 2 +- mission/core/pollingSeqTables.h | 2 +- tmtc | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bsp_q7s/core/scheduling.cpp b/bsp_q7s/core/scheduling.cpp index 99bb90d2..33869afd 100644 --- a/bsp_q7s/core/scheduling.cpp +++ b/bsp_q7s/core/scheduling.cpp @@ -472,9 +472,9 @@ void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction /* Polling Sequence Table Default */ #if OBSW_ADD_SPI_TEST_CODE == 0 - FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask( - "MAIN_SPI", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc); - result = pst::pstSpiAndSyrlinks(spiPst); + FixedTimeslotTaskIF* syrlinksPst = factory.createFixedTimeslotTask( + "SYRLINKS", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc); + result = pst::pstSyrlinks(syrlinksPst); if (result != returnvalue::OK) { if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { sif::warning << "scheduling::initTasks: SPI PST is empty" << std::endl; @@ -482,7 +482,7 @@ void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction sif::error << "scheduling::initTasks: Creating SPI PST failed!" << std::endl; } } else { - taskVec.push_back(spiPst); + taskVec.push_back(syrlinksPst); } #endif diff --git a/mission/core/pollingSeqTables.cpp b/mission/core/pollingSeqTables.cpp index 88b5b95a..05b4179a 100644 --- a/mission/core/pollingSeqTables.cpp +++ b/mission/core/pollingSeqTables.cpp @@ -18,7 +18,7 @@ #define RPI_TEST_GPS_HANDLER 0 #endif -ReturnValue_t pst::pstSpiAndSyrlinks(FixedTimeslotTaskIF *thisSequence) { +ReturnValue_t pst::pstSyrlinks(FixedTimeslotTaskIF *thisSequence) { uint32_t length = thisSequence->getPeriodMs(); #if OBSW_ADD_SYRLINKS == 1 diff --git a/mission/core/pollingSeqTables.h b/mission/core/pollingSeqTables.h index 99fba4ad..75e18665 100644 --- a/mission/core/pollingSeqTables.h +++ b/mission/core/pollingSeqTables.h @@ -47,7 +47,7 @@ struct AcsPstCfg { */ ReturnValue_t pstGompaceCan(FixedTimeslotTaskIF* thisSequence); -ReturnValue_t pstSpiAndSyrlinks(FixedTimeslotTaskIF* thisSequence); +ReturnValue_t pstSyrlinks(FixedTimeslotTaskIF* thisSequence); ReturnValue_t pstTcsAndAcs(FixedTimeslotTaskIF* thisSequence, AcsPstCfg cfg); diff --git a/tmtc b/tmtc index a40c881b..d8367f7e 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit a40c881b9fc292fe598204280db38720a784b71f +Subproject commit d8367f7e62a47516d7772c129c18ee8f7b07703b From 977235df8742c31d2dbff76b8f1e57b3149d1a64 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 13 Mar 2023 11:36:10 +0100 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f9681d3..be95f310 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ will consitute of a breaking change warranting a new major release: - Pointing control of the `AcsController` was still expecting submodes instead of modes. - Limitation of RW speeds was done before converting them to the correct unit scale. +- The Syrlinks task now has a proper name instead of `MAIN_SPI`. # [v1.37.0] 2023-03-11