diff --git a/CHANGELOG.md b/CHANGELOG.md index ce393fea..30890da2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ list yields a list of all related PRs for each release. GomSpace TM tables - Add API to retrieve GomSpace device parameter tables PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/287 +- Add API to save and load GomSpace config tables + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/293 +- Increase number of allowed consescutive action commands from 3 to 16 + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/294 # [v1.13.0] 24.08.2022 diff --git a/bsp_linux_board/CMakeLists.txt b/bsp_linux_board/CMakeLists.txt index 24e81b42..c1817ac1 100644 --- a/bsp_linux_board/CMakeLists.txt +++ b/bsp_linux_board/CMakeLists.txt @@ -1,5 +1,5 @@ target_sources(${OBSW_NAME} PUBLIC InitMission.cpp main.cpp gpioInit.cpp - ObjectFactory.cpp) + ObjectFactory.cpp RPiSdCardManager.cpp) add_subdirectory(boardconfig) add_subdirectory(boardtest) diff --git a/bsp_linux_board/InitMission.cpp b/bsp_linux_board/InitMission.cpp index c79af477..21cc5c23 100644 --- a/bsp_linux_board/InitMission.cpp +++ b/bsp_linux_board/InitMission.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -78,34 +79,10 @@ void initmission::initTasks() { sif::error << "Add component TMTC Polling failed" << std::endl; } -#if OBSW_ADD_SCEX == 1 - PeriodicTaskIF* scexDevHandler = factory->createPeriodicTask( - "SCEX_DEV", 35, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.5, missedDeadlineFunc); - result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::PERFORM_OPERATION); - if (result != returnvalue::OK) { - initmission::printAddObjectError("SCEX_DEV", objects::SCEX); - } - result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_WRITE); - if (result != returnvalue::OK) { - initmission::printAddObjectError("SCEX_DEV", objects::SCEX); - } - result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_WRITE); - if (result != returnvalue::OK) { - initmission::printAddObjectError("SCEX_DEV", objects::SCEX); - } - result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_READ); - if (result != returnvalue::OK) { - initmission::printAddObjectError("SCEX_DEV", objects::SCEX); - } - result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_READ); - - result = returnvalue::OK; - PeriodicTaskIF* scexReaderTask = factory->createPeriodicTask( - "SCEX_UART_READER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = scexReaderTask->addComponent(objects::SCEX_UART_READER); - if (result != returnvalue::OK) { - initmission::printAddObjectError("SCEX_UART_READER", objects::SCEX_UART_READER); - } +#if OBSW_ADD_SCEX_DEVICE == 1 + PeriodicTaskIF* scexDevHandler; + PeriodicTaskIF* scexReaderTask; + scheduling::schedulingScex(*factory, scexDevHandler, scexReaderTask); #endif /* PUS Services */ @@ -140,7 +117,7 @@ void initmission::initTasks() { #endif /* OBSW_ADD_TEST_CODE == 1 */ taskStarter(pstTasks, "PST Tasks"); -#if OBSW_ADD_SCEX == 1 +#if OBSW_ADD_SCEX_DEVICE == 1 scexDevHandler->startTask(); scexReaderTask->startTask(); #endif diff --git a/bsp_linux_board/OBSWConfig.h.in b/bsp_linux_board/OBSWConfig.h.in index 398cf19e..f17c3d48 100644 --- a/bsp_linux_board/OBSWConfig.h.in +++ b/bsp_linux_board/OBSWConfig.h.in @@ -28,7 +28,7 @@ #define OBSW_ADD_RTD_DEVICES 0 #define OBSW_ADD_PL_PCDU 0 #define OBSW_ADD_TMP_DEVICES 0 -#define OBSW_ADD_SCEX 1 +#define OBSW_ADD_SCEX_DEVICE 1 #define OBSW_ADD_RAD_SENSORS 0 #define OBSW_ADD_SYRLINKS 0 #define OBSW_STAR_TRACKER_GROUND_CONFIG 1 diff --git a/bsp_linux_board/ObjectFactory.cpp b/bsp_linux_board/ObjectFactory.cpp index 2804591b..950ae3ce 100644 --- a/bsp_linux_board/ObjectFactory.cpp +++ b/bsp_linux_board/ObjectFactory.cpp @@ -1,5 +1,6 @@ #include "ObjectFactory.h" +#include #include #include "OBSWConfig.h" @@ -81,8 +82,9 @@ void ObjectFactory::produce(void* args) { #endif #endif -#if OBSW_ADD_SCEX == 1 - createScexComponents(uart::DEV, pwrSwitcher); + auto* sdcMan = new RPiSdCardManager("/tmp"); +#if OBSW_ADD_SCEX_DEVICE == 1 + createScexComponents(uart::DEV, pwrSwitcher, *sdcMan, true); #endif #if OBSW_ADD_SUN_SENSORS == 1 diff --git a/bsp_linux_board/RPiSdCardManager.cpp b/bsp_linux_board/RPiSdCardManager.cpp index 264d3cfa..ccb4f3a9 100644 --- a/bsp_linux_board/RPiSdCardManager.cpp +++ b/bsp_linux_board/RPiSdCardManager.cpp @@ -1,23 +1,13 @@ #include "RPiSdCardManager.h" -RPiSdCardManager::RPiSdCardManager(const std::string& prefix):prefix(prefix) { +RPiSdCardManager::RPiSdCardManager(std::string prefix) : prefix(std::move(prefix)) {} -} +const std::string& RPiSdCardManager::getCurrentMountPrefix() const { return prefix; } -const std::string& RPiSdCardManager::getCurrentMountPrefix() const { - return prefix; -} +bool RPiSdCardManager::isSdCardMounted(sd::SdCard sdCard) { return true; } -bool RPiSdCardManager::isSdCardMounted(sd::SdCard sdCard) { - return true; -} - -std::optional RPiSdCardManager::getPreferredSdCard() const { - return std::nullopt; -} +std::optional RPiSdCardManager::getPreferredSdCard() const { return std::nullopt; } void RPiSdCardManager::setActiveSdCard(sd::SdCard sdCard) {} -std::optional RPiSdCardManager::getActiveSdCard() const { - return std::nullopt; -} +std::optional RPiSdCardManager::getActiveSdCard() const { return std::nullopt; } diff --git a/bsp_linux_board/RPiSdCardManager.h b/bsp_linux_board/RPiSdCardManager.h index b1c1d2cc..28413815 100644 --- a/bsp_linux_board/RPiSdCardManager.h +++ b/bsp_linux_board/RPiSdCardManager.h @@ -2,18 +2,17 @@ #define BSP_LINUX_BOARD_RPISDCARDMANAGER_H_ #include -class RPiSdCardManager: public SdCardMountedIF { -public: - RPiSdCardManager(const std::string& prefix); +class RPiSdCardManager : public SdCardMountedIF { + public: + RPiSdCardManager(std::string prefix); const std::string& getCurrentMountPrefix() const override; bool isSdCardMounted(sd::SdCard sdCard) override; std::optional getPreferredSdCard() const override; void setActiveSdCard(sd::SdCard sdCard) override; std::optional getActiveSdCard() const override; -private: + + private: std::string prefix; }; - - #endif /* BSP_LINUX_BOARD_RPISDCARDMANAGER_H_ */ diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index 2402938f..3bccf249 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -15,6 +15,8 @@ static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ul-plmpsoc"; static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ul-plsv"; static constexpr char UART_SYRLINKS_DEV[] = "/dev/ul-syrlinks"; static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ul-str"; +static constexpr char UART_SCEX_DEV[] = "/dev/ul-scex"; + static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio0"; static constexpr char UIO_PTME[] = "/dev/uio1"; diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 6f774b6d..e4a1fcbf 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -140,7 +140,7 @@ ReturnValue_t CoreController::initialize() { ReturnValue_t CoreController::initializeAfterTaskCreation() { ReturnValue_t result = returnvalue::OK; auto sdCard = sdcMan->getPreferredSdCard(); - if(not sdCard) { + if (not sdCard) { return returnvalue::FAILED; } sdInfo.pref = sdCard.value(); @@ -342,7 +342,7 @@ ReturnValue_t CoreController::sdStateMachine() { if (not sdInfo.commandExecuted) { result = sdcMan->getSdCardsStatus(sdInfo.currentState); auto sdCard = sdcMan->getPreferredSdCard(); - if(not sdCard) { + if (not sdCard) { return returnvalue::FAILED; } sdInfo.pref = sdCard.value(); diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 6e0fce0c..e3cef398 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -1,6 +1,7 @@ #include "bsp_q7s/core/InitMission.h" #include +#include #include #include @@ -242,6 +243,12 @@ void initmission::initTasks() { initmission::printAddObjectError("PTME_TEST", objects::CCSDS_IP_CORE_BRIDGE); } #endif +#if OBSW_ADD_SCEX_DEVICE == 1 + PeriodicTaskIF* scexDevHandler; + PeriodicTaskIF* scexReaderTask; + scheduling::schedulingScex(*factory, scexDevHandler, scexReaderTask); +#endif + std::vector pusTasks; createPusTasks(*factory, missedDeadlineFunc, pusTasks); @@ -280,8 +287,9 @@ void initmission::initTasks() { taskStarter(pstTasks, "PST task vector"); taskStarter(pusTasks, "PUS task vector"); -#if OBSW_ADD_TEST_CODE == 1 - taskStarter(testTasks, "Test task vector"); +#if OBSW_ADD_SCEX_DEVICE == 1 + scexDevHandler->startTask(); + scexReaderTask->startTask(); #endif #if OBSW_TEST_CCSDS_BRIDGE == 1 @@ -304,6 +312,11 @@ void initmission::initTasks() { #if OBSW_ADD_PLOC_SUPERVISOR == 1 supvHelperTask->startTask(); #endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */ + +#if OBSW_ADD_TEST_CODE == 1 + taskStarter(testTasks, "Test task vector"); +#endif + sif::info << "Tasks started.." << std::endl; } @@ -514,23 +527,23 @@ void initmission::createTestTasks(TaskFactory& factory, } /** - ▄ ▄ - ▌▒█ ▄▀▒▌ - ▌▒▒█ ▄▀▒▒▒▐ - ▐▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒▐ - ▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒▐ - ▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌ - ▐▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒▌ - ▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒▐ - ▐░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄▌ - ▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▌ - ▌▒▀▐▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒▐ - ▐▒▒▐▀▐▀▒░▄▄▒▄▒▒▒▒▒▒░▒░▒░▒▒▒▒▌ - ▐▒▒▒▀▀▄▄▒▒▒▄▒▒▒▒▒▒▒▒░▒░▒░▒▒▐ - ▌▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒░▒░▒░▒░▒▒▒▌ - ▐▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▒▄▒▒▐ - ▀▄▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▄▒▒▒▒▌ - ▀▄▒▒▒▒▒▒▒▒▒▒▄▄▄▀▒▒▒▒▄▀ - ▀▄▄▄▄▄▄▀▀▀▒▒▒▒▒▄▄▀ - ▒▒▒▒▒▒▒▒▒▒▀▀ + â–„ â–„ + ▌▒█ ▄▀▒▌ + ▌▒▒█ ▄▀▒▒▒â–� + â–�▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒â–� + ▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒â–� + ▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌ + â–�▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒▌ + ▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒â–� + â–�░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄▌ + ▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▌ + ▌▒▀â–�▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒â–� + â–�â–’â–’â–�â–€â–�▀▒░▄▄▒▄▒▒▒▒▒▒░▒░▒░▒▒▒▒▌ + â–�▒▒▒▀▀▄▄▒▒▒▄▒▒▒▒▒▒▒▒░▒░▒░▒▒â–� + ▌▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒░▒░▒░▒░▒▒▒▌ + â–�â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–‘â–’â–‘â–’â–‘â–’â–’â–„â–’â–’â–� + ▀▄▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▄▒▒▒▒▌ + ▀▄▒▒▒▒▒▒▒▒▒▒▄▄▄▀▒▒▒▒▄▀ + ▀▄▄▄▄▄▄▀▀▀▒▒▒▒▒▄▄▀ + ▒▒▒▒▒▒▒▒▒▒▀▀ **/ diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index acce5dfb..43b8d255 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -1,3 +1,4 @@ +#include #include "OBSWConfig.h" #include "bsp_q7s/core/CoreController.h" #include "bsp_q7s/core/ObjectFactory.h" @@ -56,6 +57,11 @@ void ObjectFactory::produce(void* args) { #if OBSW_USE_CCSDS_IP_CORE == 1 createCcsdsComponents(gpioComIF); #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ + +#if OBSW_ADD_SCEX_DEVICE == 1 + createScexComponents(q7s::UART_GNSS_DEV, pwrSwitcher, *SdCardManager::instance(), false, + pcdu::Switches::PDU1_CH5_SOLAR_CELL_EXP_5V); +#endif /* Test Task */ #if OBSW_ADD_TEST_CODE == 1 createTestComponents(gpioComIF); diff --git a/bsp_q7s/memory/FileSystemHandler.cpp b/bsp_q7s/memory/FileSystemHandler.cpp index 2c5fb729..a5bd68c6 100644 --- a/bsp_q7s/memory/FileSystemHandler.cpp +++ b/bsp_q7s/memory/FileSystemHandler.cpp @@ -72,7 +72,8 @@ void FileSystemHandler::fileSystemCheckup() { SdCardManager::SdStatePair statusPair; sdcMan->getSdCardsStatus(statusPair); auto preferredSdCard = sdcMan->getPreferredSdCard(); - if (preferredSdCard and (preferredSdCard == sd::SdCard::SLOT_0) and (statusPair.first == sd::SdState::MOUNTED)) { + if (preferredSdCard and (preferredSdCard == sd::SdCard::SLOT_0) and + (statusPair.first == sd::SdState::MOUNTED)) { currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT; } else if ((preferredSdCard == sd::SdCard::SLOT_1) and (statusPair.second == sd::SdState::MOUNTED)) { @@ -109,7 +110,7 @@ ReturnValue_t FileSystemHandler::initialize() { } sdcMan = SdCardManager::instance(); auto sdCard = sdcMan->getPreferredSdCard(); - if(not sdCard) { + if (not sdCard) { return returnvalue::FAILED; } sd::SdCard preferredSdCard = sdCard.value(); diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index e1d80966..861dfb5c 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -6,4 +6,4 @@ add_subdirectory(devices) add_subdirectory(fsfwconfig) add_subdirectory(obc) -target_sources(${OBSW_NAME} PUBLIC ObjectFactory.cpp) +target_sources(${OBSW_NAME} PUBLIC ObjectFactory.cpp InitMission.cpp) diff --git a/linux/InitMission.cpp b/linux/InitMission.cpp new file mode 100644 index 00000000..7388c974 --- /dev/null +++ b/linux/InitMission.cpp @@ -0,0 +1,46 @@ +#include "InitMission.h" + +#include +#include +#include + +#include "OBSWConfig.h" +#include "ObjectFactory.h" + +void scheduling::schedulingScex(TaskFactory& factory, PeriodicTaskIF*& scexDevHandler, PeriodicTaskIF*& scexReaderTask) { + using namespace initmission; + ReturnValue_t result = returnvalue::OK; +#if OBSW_PRINT_MISSED_DEADLINES == 1 + void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline; +#else + void (*missedDeadlineFunc)(void) = nullptr; +#endif + scexDevHandler = factory.createPeriodicTask( + "SCEX_DEV", 35, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.5, missedDeadlineFunc); + + result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::PERFORM_OPERATION); + if (result != returnvalue::OK) { + printAddObjectError("SCEX_DEV", objects::SCEX); + } + result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_WRITE); + if (result != returnvalue::OK) { + printAddObjectError("SCEX_DEV", objects::SCEX); + } + result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_WRITE); + if (result != returnvalue::OK) { + printAddObjectError("SCEX_DEV", objects::SCEX); + } + result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_READ); + if (result != returnvalue::OK) { + printAddObjectError("SCEX_DEV", objects::SCEX); + } + result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_READ); + + result = returnvalue::OK; + scexReaderTask = factory.createPeriodicTask( + "SCEX_UART_READER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); + result = scexReaderTask->addComponent(objects::SCEX_UART_READER); + if (result != returnvalue::OK) { + printAddObjectError("SCEX_UART_READER", objects::SCEX_UART_READER); + } +} diff --git a/linux/InitMission.h b/linux/InitMission.h new file mode 100644 index 00000000..cc507265 --- /dev/null +++ b/linux/InitMission.h @@ -0,0 +1,6 @@ +#pragma once +#include + +namespace scheduling { +void schedulingScex(TaskFactory& factory, PeriodicTaskIF*& scexDevHandler, PeriodicTaskIF*& scexReaderTask); +} diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index 0398bd7e..84d62162 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -323,14 +323,20 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, #endif // OBSW_ADD_RTD_DEVICES == 1 } -void ObjectFactory::createScexComponents(std::string uartDev, PowerSwitchIF* pwrSwitcher) { +void ObjectFactory::createScexComponents(std::string uartDev, PowerSwitchIF* pwrSwitcher, + SdCardMountedIF& mountedIF, bool onImmediately, + std::optional switchId) { // objekte anlegen - SdCardMountedIF* sdcMan = nullptr; auto* cookie = new UartCookie(objects::SCEX, uartDev, uart::SCEX_BAUD, 4096); auto scexUartReader = new ScexUartReader(objects::SCEX_UART_READER); - auto scexHandler = new ScexDeviceHandler(objects::SCEX, *scexUartReader, cookie, sdcMan); - scexHandler->setStartUpImmediately(); + auto scexHandler = new ScexDeviceHandler(objects::SCEX, *scexUartReader, cookie, mountedIF); + if(onImmediately) { + scexHandler->setStartUpImmediately(); + } + if (switchId) { + scexHandler->setPowerSwitcher(*pwrSwitcher, switchId.value()); + } } void ObjectFactory::createThermalController() { diff --git a/linux/ObjectFactory.h b/linux/ObjectFactory.h index 99bef0e7..8142df7e 100644 --- a/linux/ObjectFactory.h +++ b/linux/ObjectFactory.h @@ -1,9 +1,12 @@ #pragma once +#include #include #include +#include #include +#include class GpioIF; class SpiComIF; @@ -16,7 +19,9 @@ void createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, PowerSwitc void createRtdComponents(std::string spiDev, GpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher, SpiComIF* comIF); -void createScexComponents(std::string uartDev, PowerSwitchIF* pwrSwitcher); +void createScexComponents(std::string uartDev, PowerSwitchIF* pwrSwitcher, + SdCardMountedIF& mountedIF, bool onImmediately, + std::optional switchId); void gpioChecker(ReturnValue_t result, std::string output); diff --git a/linux/csp/CspComIF.cpp b/linux/csp/CspComIF.cpp index eb6487ed..5d8c3fd6 100644 --- a/linux/csp/CspComIF.cpp +++ b/linux/csp/CspComIF.cpp @@ -166,6 +166,26 @@ ReturnValue_t CspComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s if (result != 0) { return returnvalue::FAILED; } + } else if(req == GOMSPACE::SpecialRequestTypes::SAVE_TABLE) { + if(sendLen < 2) { + return returnvalue::FAILED; + } + const TableInfo* tableInfo = reinterpret_cast(sendData); + int result = gs_rparam_save(cspAddress, cspCookie->getTimeout(), tableInfo->sourceTable, + tableInfo->targetTable); + if (result != 0) { + return returnvalue::FAILED; + } + } else if(req == GOMSPACE::SpecialRequestTypes::LOAD_TABLE) { + if(sendLen < 2) { + return returnvalue::FAILED; + } + const TableInfo* tableInfo = reinterpret_cast(sendData); + int result = gs_rparam_load(cspAddress, cspCookie->getTimeout(), tableInfo->sourceTable, + tableInfo->targetTable); + if (result != 0) { + return returnvalue::FAILED; + } } } else { /* No CSP fixed port was selected. Send data to the specified port and diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 0a9be3f9..bbd2bb98 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -96,7 +96,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) { PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, apid::EIVE_OBSW, pus::PUS_SERVICE_5), 15, 45); new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, apid::EIVE_OBSW, - pus::PUS_SERVICE_8, 3, 60); + pus::PUS_SERVICE_8, 16, 60); new Service9TimeManagement( PsbParams(objects::PUS_SERVICE_9_TIME_MGMT, apid::EIVE_OBSW, pus::PUS_SERVICE_9)); diff --git a/mission/csp/CspCookie.cpp b/mission/csp/CspCookie.cpp index f6ab1eed..228a8058 100644 --- a/mission/csp/CspCookie.cpp +++ b/mission/csp/CspCookie.cpp @@ -1,10 +1,11 @@ #include "CspCookie.h" +using namespace GOMSPACE; CspCookie::CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_, uint32_t timeoutMs) : maxReplyLength(maxReplyLength_), cspAddress(cspAddress_), timeoutMs(timeoutMs), - reqType(GOMSPACE::DEFAULT_COM_IF) {} + reqType(SpecialRequestTypes::DEFAULT_COM_IF) {} CspCookie::~CspCookie() {} diff --git a/mission/csp/CspCookie.h b/mission/csp/CspCookie.h index 441eb413..9eb0a639 100644 --- a/mission/csp/CspCookie.h +++ b/mission/csp/CspCookie.h @@ -28,7 +28,7 @@ class CspCookie : public CookieIF { uint32_t getTimeout() const; private: - uint8_t cspPort; + uint8_t cspPort = 0; uint16_t maxReplyLength; uint8_t cspAddress; size_t replyLen = 0; diff --git a/mission/devices/GomspaceDeviceHandler.cpp b/mission/devices/GomspaceDeviceHandler.cpp index 5acd209e..ebfcf2a9 100644 --- a/mission/devices/GomspaceDeviceHandler.cpp +++ b/mission/devices/GomspaceDeviceHandler.cpp @@ -44,6 +44,8 @@ ReturnValue_t GomspaceDeviceHandler::buildTransitionDeviceCommand(DeviceCommandI ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, size_t commandDataLen) { + auto* cspCookie = dynamic_cast(comCookie); + cspCookie->setRequest(SpecialRequestTypes::DEFAULT_COM_IF, 0); ReturnValue_t result = childCommandHook(deviceCommand, commandData, commandDataLen); switch (deviceCommand) { case (GOMSPACE::PING): { @@ -84,37 +86,87 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t d break; } case (GOMSPACE::REQUEST_HK_TABLE): { - auto reqType = SpecialRequestTypes::DEFAULT_COM_IF; - if (getObjectId() == objects::PDU1_HANDLER or getObjectId() == objects::PDU2_HANDLER) { - reqType = SpecialRequestTypes::GET_PDU_HK; - } else if (getObjectId() == objects::ACU_HANDLER) { - reqType = SpecialRequestTypes::GET_ACU_HK; - } else if (getObjectId() == objects::P60DOCK_HANDLER) { - reqType = SpecialRequestTypes::GET_P60DOCK_HK; + DeviceType devType; + if(getDevType(devType) != returnvalue::OK) { + return returnvalue::FAILED; } - result = generateRequestFullTableCmd(reqType, GOMSPACE::TableIds::HK, tableCfg.hkTableSize, - deviceCommand); + result = + generateRequestFullHkTableCmd(devType, tableCfg.hkTableSize, deviceCommand, cspCookie); if (result != returnvalue::OK) { return result; } break; } case (GOMSPACE::REQUEST_CONFIG_TABLE): { - auto reqType = SpecialRequestTypes::DEFAULT_COM_IF; - if (getObjectId() == objects::PDU1_HANDLER or getObjectId() == objects::PDU2_HANDLER) { - reqType = SpecialRequestTypes::GET_PDU_CONFIG; - } else if (getObjectId() == objects::ACU_HANDLER) { - reqType = SpecialRequestTypes::GET_ACU_CONFIG; - } else if (getObjectId() == objects::P60DOCK_HANDLER) { - reqType = SpecialRequestTypes::GET_P60DOCK_CONFIG; + DeviceType devType; + if(getDevType(devType) != returnvalue::OK) { + return returnvalue::FAILED; } - result = generateRequestFullTableCmd(reqType, GOMSPACE::TableIds::CONFIG, - tableCfg.cfgTableSize, deviceCommand); + result = generateRequestFullCfgTableCmd(devType, tableCfg.cfgTableSize, + deviceCommand, cspCookie); if (result != returnvalue::OK) { return result; } break; } + case (GOMSPACE::LOAD_TABLE): { + if (commandDataLen != 2) { + return HasActionsIF::INVALID_PARAMETERS; + } + auto* info = reinterpret_cast(cspPacket); + info->sourceTable = commandData[0]; + info->targetTable = commandData[1]; + rawPacket = cspPacket; + rawPacketLen = sizeof(GOMSPACE::TableInfo); + cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM); + cspCookie->setRequest(SpecialRequestTypes::LOAD_TABLE, 0); + rememberCommandId = deviceCommand; + break; + } + case (GOMSPACE::SAVE_TABLE_FILE): { + if (commandDataLen > 2) { + return HasActionsIF::INVALID_PARAMETERS; + } + auto* info = reinterpret_cast(cspPacket); + if (commandData[0] != 0 and commandData[0] != 1 and commandData[0] != 2 and + commandData[0] != 4) { + return HasActionsIF::INVALID_PARAMETERS; + } + info->sourceTable = commandData[0]; + if (info->sourceTable != 4) { + if (commandDataLen == 2) { + info->targetTable = commandData[1]; + } else { + info->targetTable = info->sourceTable; + } + } else { + // Will be ignored, still set the value which is always used + info->targetTable = 4; + } + rawPacket = cspPacket; + rawPacketLen = sizeof(GOMSPACE::TableInfo); + cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM); + cspCookie->setRequest(SpecialRequestTypes::SAVE_TABLE, 0); + rememberCommandId = deviceCommand; + break; + } + case (GOMSPACE::SAVE_TABLE_DEFAULT): { + if (commandDataLen != 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + auto* info = reinterpret_cast(cspPacket); + if (commandData[0] != 0 and commandData[0] != 1 and commandData[0] != 2) { + return HasActionsIF::INVALID_PARAMETERS; + } + info->sourceTable = commandData[0]; + info->targetTable = info->sourceTable + 4; + rawPacket = cspPacket; + rawPacketLen = sizeof(GOMSPACE::TableInfo); + cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM); + cspCookie->setRequest(SpecialRequestTypes::SAVE_TABLE, 0); + rememberCommandId = deviceCommand; + break; + } default: return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; } @@ -131,6 +183,9 @@ void GomspaceDeviceHandler::fillCommandAndReplyMap() { this->insertInCommandMap(GOMSPACE::GNDWDT_RESET); this->insertInCommandMap(GOMSPACE::PRINT_SWITCH_V_I); this->insertInCommandMap(GOMSPACE::PRINT_LATCHUPS); + insertInCommandMap(GOMSPACE::SAVE_TABLE_FILE); + insertInCommandMap(GOMSPACE::SAVE_TABLE_DEFAULT); + insertInCommandMap(GOMSPACE::LOAD_TABLE); } ReturnValue_t GomspaceDeviceHandler::scanForReply(const uint8_t* start, size_t remainingSize, @@ -443,6 +498,19 @@ bool GomspaceDeviceHandler::validTableId(uint8_t id) { return false; } +ReturnValue_t GomspaceDeviceHandler::getDevType(GOMSPACE::DeviceType& type) const { + if (getObjectId() == objects::PDU1_HANDLER or getObjectId() == objects::PDU2_HANDLER) { + type = DeviceType::PDU; + } else if (getObjectId() == objects::ACU_HANDLER) { + type = DeviceType::ACU; + } else if (getObjectId() == objects::P60DOCK_HANDLER) { + type = DeviceType::P60DOCK; + } else { + return returnvalue::FAILED; + } + return returnvalue::OK; +} + ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() { WatchdogResetCommand watchdogResetCommand; size_t cspPacketLen = 0; @@ -462,19 +530,40 @@ ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() { return returnvalue::OK; } -ReturnValue_t GomspaceDeviceHandler::generateRequestFullTableCmd(SpecialRequestTypes reqType, - uint8_t tableId, - uint16_t tableReplySize, - DeviceCommandId_t id) { - uint16_t querySize = tableReplySize; - if (reqType == SpecialRequestTypes::DEFAULT_COM_IF) { - sif::warning << "Default communication for table requests not implemented anymore" << std::endl; - return returnvalue::FAILED; +ReturnValue_t GomspaceDeviceHandler::generateRequestFullHkTableCmd(DeviceType dev, + uint16_t tableReplySize, + DeviceCommandId_t id, + CspCookie* cspCookie) { + if (dev == DeviceType::ACU) { + cspCookie->setRequest(SpecialRequestTypes::GET_ACU_HK, tableReplySize); + } else if (dev == DeviceType::P60DOCK) { + cspCookie->setRequest(SpecialRequestTypes::GET_P60DOCK_HK, tableReplySize); + } else if (dev == DeviceType::PDU) { + cspCookie->setRequest(SpecialRequestTypes::GET_PDU_HK, tableReplySize); } - auto* cspCookie = dynamic_cast(comCookie); - cspCookie->setRequest(reqType, tableReplySize); cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM); - rememberRequestedSize = querySize; + rememberRequestedSize = tableReplySize; + rememberCommandId = id; + return returnvalue::OK; +} + +ReturnValue_t GomspaceDeviceHandler::generateRequestFullCfgTableCmd(DeviceType dev, + uint16_t tableReplySize, + DeviceCommandId_t id, + CspCookie* cspCookie) { + if (dev == DeviceType::ACU) { + cspCookie->setRequest(SpecialRequestTypes::GET_ACU_CONFIG, tableReplySize); + } else if (dev == DeviceType::P60DOCK) { + cspCookie->setRequest(SpecialRequestTypes::GET_P60DOCK_CONFIG, tableReplySize); + } else if (dev == DeviceType::PDU) { + cspCookie->setRequest(SpecialRequestTypes::GET_PDU_CONFIG, tableReplySize); + } + cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM); + // Unfortunately, this does not work.. + // cspPacket[0] = defaultTable; + // rawPacket = cspPacket; + // rawPacketLen = 1; + rememberRequestedSize = tableReplySize; rememberCommandId = id; return returnvalue::OK; } diff --git a/mission/devices/GomspaceDeviceHandler.h b/mission/devices/GomspaceDeviceHandler.h index af847b8a..528cd2dd 100644 --- a/mission/devices/GomspaceDeviceHandler.h +++ b/mission/devices/GomspaceDeviceHandler.h @@ -82,10 +82,21 @@ class GomspaceDeviceHandler : public DeviceHandlerBase { * @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 generateRequestFullTableCmd(GOMSPACE::SpecialRequestTypes reqType, - uint8_t tableId, uint16_t tableSize, - DeviceCommandId_t id); - + ReturnValue_t generateRequestFullHkTableCmd(GOMSPACE::DeviceType devType, uint16_t tableSize, + DeviceCommandId_t id, CspCookie *cspCookie); + /** + * Unfortunately, it was not possible to specify the table ID (e.g. request table from + * default store) + * @param devType + * @param tableSize + * @param id + * @param cspCookie + * @return + */ + ReturnValue_t generateRequestFullCfgTableCmd(GOMSPACE::DeviceType devType, + uint16_t tableSize, DeviceCommandId_t id, + CspCookie *cspCookie); + ReturnValue_t getDevType(GOMSPACE::DeviceType& type) const; /** * This command handles printing the HK table to the console. This is useful for debugging * purposes diff --git a/mission/devices/ScexDeviceHandler.cpp b/mission/devices/ScexDeviceHandler.cpp index 5f3f9aa0..8add8d6b 100644 --- a/mission/devices/ScexDeviceHandler.cpp +++ b/mission/devices/ScexDeviceHandler.cpp @@ -15,14 +15,13 @@ using std::ofstream; using namespace returnvalue; ScexDeviceHandler::ScexDeviceHandler(object_id_t objectId, ScexUartReader& reader, CookieIF* cookie, - SdCardMountedIF* sdcMan) + SdCardMountedIF& sdcMan) : DeviceHandlerBase(objectId, reader.getObjectId(), cookie), sdcMan(sdcMan), reader(reader) {} ScexDeviceHandler::~ScexDeviceHandler() {} void ScexDeviceHandler::doStartUp() { - // mode on - setMode(MODE_ON); + setMode(MODE_ON); } void ScexDeviceHandler::doShutDown() { setMode(_MODE_POWER_DOWN); } @@ -196,9 +195,11 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons ReturnValue_t status = OK; auto oneFileHandler = [&](std::string cmdName) { fileId = date_time_string(); - std::ostringstream oss("/tmp/scex-", std::ostringstream::ate); - oss << cmdName << fileId << ".bin"; + std::ostringstream oss; + auto prefix = sdcMan.getCurrentMountPrefix(); + oss << prefix << "/scex-" << cmdName << fileId << ".bin"; fileName = oss.str(); + sif::info << "ScexDeviceHandler::interpretDeviceReply: FileName: " << fileName << std::endl; ofstream out(fileName, ofstream::binary); if (out.bad()) { sif::error << "ScexDeviceHandler::interpretDeviceReply: Could not open file " << fileName @@ -211,9 +212,12 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons auto multiFileHandler = [&](std::string cmdName) { if ((helper.getPacketCounter() == 1) or (not fileNameSet)) { fileId = date_time_string(); - std::ostringstream oss("/tmp/scex-", std::ostringstream::ate); - oss << cmdName << fileId << ".bin"; + std::ostringstream oss; + auto prefix = sdcMan.getCurrentMountPrefix(); + oss << prefix << "/scex-" << cmdName << fileId << ".bin"; fileName = oss.str(); + sif::info << "ScexDeviceHandler::interpretDeviceReply: FileName: " << fileName + << std::endl; // TODO remove fileNameSet = true; ofstream out(fileName, ofstream::binary); if (out.bad()) { @@ -301,6 +305,10 @@ void ScexDeviceHandler::performOperationHook() { uint32_t ScexDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return OK; } ReturnValue_t ScexDeviceHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) { + if(switchId) { + *numberOfSwitches = 1; + *switches = &switchId.value(); + } return OK; } @@ -314,26 +322,23 @@ std::string ScexDeviceHandler::date_time_string() { string date_time; Clock::TimeOfDay_t tod; Clock::getDateAndTime(&tod); - time_t now = time(0); - tm* ltm = localtime(&now); ostringstream oss(std::ostringstream::ate); - //TODO mit tod ersetzen - if (ltm->tm_hour < 10) { - oss << tod.year << tod.month << ltm->tm_mday << "_0" << ltm->tm_hour; + if (tod.hour < 10) { + oss << tod.year << tod.month << tod.day << "_0" << tod.hour; } else { - oss << 1900 + ltm->tm_year << 1 + ltm->tm_mon << ltm->tm_mday << "_" << ltm->tm_hour; + oss << tod.year << tod.month << tod.day << "_" << tod.hour; } - if (ltm->tm_min < 10) { - oss << 0 << ltm->tm_min; + if (tod.minute < 10) { + oss << 0 << tod.minute; } else { - oss << ltm->tm_min; + oss << tod.minute; } - if (ltm->tm_sec < 10) { - oss << 0 << ltm->tm_sec; + if (tod.second < 10) { + oss << 0 << tod.second; } else { - oss << ltm->tm_sec; + oss << tod.second; } date_time = oss.str(); @@ -342,3 +347,9 @@ std::string ScexDeviceHandler::date_time_string() { } void ScexDeviceHandler::modeChanged() {} + +void ScexDeviceHandler::setPowerSwitcher(PowerSwitchIF& powerSwitcher, power::Switch_t switchId) +{ + DeviceHandlerBase::setPowerSwitcher(&powerSwitcher); + this->switchId = switchId; +} diff --git a/mission/devices/ScexDeviceHandler.h b/mission/devices/ScexDeviceHandler.h index 7fc47858..19ce2e52 100644 --- a/mission/devices/ScexDeviceHandler.h +++ b/mission/devices/ScexDeviceHandler.h @@ -1,18 +1,21 @@ #ifndef MISSION_DEVICES_SCEXDEVICEHANDLER_H_ #define MISSION_DEVICES_SCEXDEVICEHANDLER_H_ +#include #include #include #include #include "commonSubsystemIds.h" + class SdCardMountedIF; class ScexDeviceHandler : public DeviceHandlerBase { public: ScexDeviceHandler(object_id_t objectId, ScexUartReader &reader, CookieIF *cookie, - SdCardMountedIF *sdcMan); + SdCardMountedIF &sdcMan); + void setPowerSwitcher(PowerSwitchIF& powerSwitcher, power::Switch_t switchId); virtual ~ScexDeviceHandler(); private: @@ -20,6 +23,7 @@ class ScexDeviceHandler : public DeviceHandlerBase { static constexpr uint32_t SHORT_CD = 7000; std::array cmdBuf = {}; + std::optional switchId; std::string fileId = ""; std::string fileName = ""; bool fileNameSet = false; @@ -27,7 +31,7 @@ class ScexDeviceHandler : public DeviceHandlerBase { bool debugMode = false; scex::Cmds currCmd = scex::Cmds::PING; - SdCardMountedIF *sdcMan = nullptr; + SdCardMountedIF &sdcMan; Countdown finishCountdown = Countdown(LONG_CD); std::string date_time_string(); diff --git a/mission/devices/devicedefinitions/GomspaceDefinitions.h b/mission/devices/devicedefinitions/GomspaceDefinitions.h index 5447bf42..cab71362 100644 --- a/mission/devices/devicedefinitions/GomspaceDefinitions.h +++ b/mission/devices/devicedefinitions/GomspaceDefinitions.h @@ -18,14 +18,23 @@ namespace GOMSPACE { -enum SpecialRequestTypes { +struct TableInfo { + uint8_t sourceTable; + uint8_t targetTable; +}; + +enum DeviceType { PDU, ACU, P60DOCK }; + +enum class SpecialRequestTypes { DEFAULT_COM_IF, GET_PDU_HK, GET_PDU_CONFIG, GET_ACU_HK, GET_ACU_CONFIG, GET_P60DOCK_HK, - GET_P60DOCK_CONFIG + GET_P60DOCK_CONFIG, + SAVE_TABLE, + LOAD_TABLE }; enum CspPorts : uint8_t { @@ -53,14 +62,18 @@ 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 PARAM_GET = 0; //!< [EXPORT] : [COMMAND] 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] static const DeviceCommandId_t REQUEST_CONFIG_TABLE = 17; //!< [EXPORT] : [COMMAND] +static const DeviceCommandId_t SAVE_TABLE_FILE = 18; +static const DeviceCommandId_t SAVE_TABLE_DEFAULT = 19; +static const DeviceCommandId_t LOAD_TABLE = 20; +static const DeviceCommandId_t PARAM_SET = 255; //!< [EXPORT] : [COMMAND] + // Not implemented yet // static const DeviceCommandId_t REQUEST_CALIB_TABLE = 18; //!< [EXPORT] : [COMMAND] //! [EXPORT] : [COMMAND] Print switch states, voltages and currents to the console diff --git a/mission/memory/SdCardMountedIF.h b/mission/memory/SdCardMountedIF.h index 3dd529d4..57e98919 100644 --- a/mission/memory/SdCardMountedIF.h +++ b/mission/memory/SdCardMountedIF.h @@ -1,8 +1,9 @@ #ifndef MISSION_MEMORY_SDCARDMOUNTERIF_H_ #define MISSION_MEMORY_SDCARDMOUNTERIF_H_ -#include #include +#include + #include "definitions.h" class SdCardMountedIF { diff --git a/mission/utility/InitMission.h b/mission/utility/InitMission.h index dc131981..5529f749 100644 --- a/mission/utility/InitMission.h +++ b/mission/utility/InitMission.h @@ -1,12 +1,11 @@ -#ifndef MISSION_UTILITY_INITMISSION_H_ -#define MISSION_UTILITY_INITMISSION_H_ +#pragma once #include #include namespace initmission { -void printAddObjectError(const char* name, object_id_t objectId) { +static void printAddObjectError(const char* name, object_id_t objectId) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "InitMission::printAddError: Adding object " << name << " with object ID 0x" << std::hex << std::setfill('0') << std::setw(8) << objectId << " failed!" << std::dec @@ -18,5 +17,3 @@ void printAddObjectError(const char* name, object_id_t objectId) { } } // namespace initmission - -#endif /* MISSION_UTILITY_INITMISSION_H_ */ diff --git a/tmtc b/tmtc index e1d84c5b..a7714747 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit e1d84c5b99e99ea9a9687dcd298d815dc4d8d2b6 +Subproject commit a7714747bc45dfa6a9ccb41cc6eb890b21ca0481