diff --git a/mission/devices/PlocSupervisorHandler.cpp b/mission/devices/PlocSupervisorHandler.cpp index 17ef9a5f..9c4dc73e 100644 --- a/mission/devices/PlocSupervisorHandler.cpp +++ b/mission/devices/PlocSupervisorHandler.cpp @@ -197,6 +197,49 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand( case(PLOC_SPV::DUMP_MRAM): { result = prepareDumpMramCmd(commandData); break; + } + case(PLOC_SPV::PRINT_CPU_STATS): { + preparePrintCpuStatsCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::SET_DBG_VERBOSITY): { + prepareSetDbgVerbosityCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::SET_GPIO): { + prepareSetGpioCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::READ_GPIO): { + prepareReadGpioCmd(commandData); + result = RETURN_OK; + break; + } + case(PLOC_SPV::RESTART_SUPERVISOR): { + prepareEmptyCmd(PLOC_SPV::APID_RESTART_SUPERVISOR); + result = RETURN_OK; + break; + } + case(PLOC_SPV::FACTORY_RESET_CLEAR_ALL): { + PLOC_SPV::FactoryReset packet(PLOC_SPV::FactoryReset::Op::CLEAR_ALL); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + result = RETURN_OK; + break; + } + case(PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR): { + PLOC_SPV::FactoryReset packet(PLOC_SPV::FactoryReset::Op::MIRROR_ENTRIES); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + result = RETURN_OK; + break; + } + case(PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR): { + PLOC_SPV::FactoryReset packet(PLOC_SPV::FactoryReset::Op::CIRCULAR_ENTRIES); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); + result = RETURN_OK; + break; } default: sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" @@ -245,6 +288,14 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() { this->insertInCommandMap(PLOC_SPV::SELECT_NVM); this->insertInCommandMap(PLOC_SPV::RUN_AUTO_EM_TESTS); this->insertInCommandMap(PLOC_SPV::WIPE_MRAM); + this->insertInCommandMap(PLOC_SPV::PRINT_CPU_STATS); + this->insertInCommandMap(PLOC_SPV::SET_DBG_VERBOSITY); + this->insertInCommandMap(PLOC_SPV::SET_GPIO); + this->insertInCommandMap(PLOC_SPV::READ_GPIO); + this->insertInCommandMap(PLOC_SPV::RESTART_SUPERVISOR); + this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_ALL); + this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR); + this->insertInCommandMap(PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR); this->insertInCommandAndReplyMap(PLOC_SPV::DUMP_MRAM, 3); this->insertInReplyMap(PLOC_SPV::ACK_REPORT, 3, nullptr, PLOC_SPV::SIZE_ACK_REPORT); this->insertInReplyMap(PLOC_SPV::EXE_REPORT, 3, nullptr, PLOC_SPV::SIZE_EXE_REPORT); @@ -477,7 +528,9 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite case PLOC_SPV::SET_GPIO: case PLOC_SPV::READ_GPIO: case PLOC_SPV::RESTART_SUPERVISOR: - case PLOC_SPV::FACTORY_RESET: + case PLOC_SPV::FACTORY_RESET_CLEAR_ALL: + case PLOC_SPV::FACTORY_RESET_CLEAR_MIRROR: + case PLOC_SPV::FACTORY_RESET_CLEAR_CIRCULAR: case PLOC_SPV::REQUEST_LOGGING_DATA: enabledReplies = 2; break; @@ -1156,6 +1209,33 @@ ReturnValue_t PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandDa return RETURN_OK; } +void PlocSupervisorHandler::preparePrintCpuStatsCmd(const uint8_t* commandData) { + uint8_t en = *commandData; + PLOC_SPV::PrintCpuStats packet(en); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + +void PlocSupervisorHandler::prepareSetDbgVerbosityCmd(const uint8_t* commandData) { + uint8_t vb = *commandData; + PLOC_SPV::SetDbgVerbosity packet(vb); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + +void PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandData) { + uint8_t port = *commandData; + uint8_t pin = *(commandData + 1); + uint8_t val = *(commandData + 2); + PLOC_SPV::SetGpio packet(port, pin, val); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + +void PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandData) { + uint8_t port = *commandData; + uint8_t pin = *(commandData + 1); + PLOC_SPV::ReadGpio packet(port, pin); + packetToOutBuffer(packet.getWholeData(), packet.getFullSize()); +} + void PlocSupervisorHandler::packetToOutBuffer(uint8_t* packetData, size_t fullSize) { memcpy(commandBuffer, packetData, fullSize); rawPacket = commandBuffer; diff --git a/mission/devices/PlocSupervisorHandler.h b/mission/devices/PlocSupervisorHandler.h index f316544f..edc46c85 100644 --- a/mission/devices/PlocSupervisorHandler.h +++ b/mission/devices/PlocSupervisorHandler.h @@ -243,6 +243,10 @@ private: ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData); ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData); ReturnValue_t prepareDumpMramCmd(const uint8_t* commandData); + void preparePrintCpuStatsCmd(const uint8_t* commandData); + void prepareSetDbgVerbosityCmd(const uint8_t* commandData); + void prepareSetGpioCmd(const uint8_t* commandData); + void prepareReadGpioCmd(const uint8_t* commandData); /** diff --git a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h index dc7c792f..cc7be993 100644 --- a/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/mission/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -47,9 +47,11 @@ static const DeviceCommandId_t PRINT_CPU_STATS = 33; static const DeviceCommandId_t SET_GPIO = 34; static const DeviceCommandId_t READ_GPIO = 35; static const DeviceCommandId_t RESTART_SUPERVISOR = 36; -static const DeviceCommandId_t FACTORY_RESET = 37; +static const DeviceCommandId_t FACTORY_RESET_CLEAR_ALL = 37; static const DeviceCommandId_t REQUEST_LOGGING_DATA = 38; static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39; +static const DeviceCommandId_t FACTORY_RESET_CLEAR_MIRROR = 40; +static const DeviceCommandId_t FACTORY_RESET_CLEAR_CIRCULAR = 41; /** Reply IDs */ static const DeviceCommandId_t ACK_REPORT = 50; @@ -1095,6 +1097,89 @@ private: } }; +/** + * @brief This class packages the space packet causing the supervisor to print the CPU load to + * the debug output. + */ +class PrintCpuStats: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param en Print is enabled if en != 0 + */ + PrintCpuStats(uint8_t en) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_PRINT_CPU_STATS, + DEFAULT_SEQUENCE_COUNT), en(en) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 3; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t en = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&en, &data_field_ptr, &serializedSize, + sizeof(en), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet to set the print verbosity in the supervisor + * software. + */ +class SetDbgVerbosity: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param vb 0: None, 1: Error, 2: Warn, 3: Info + */ + SetDbgVerbosity(uint8_t vb) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_DBG_VERBOSITY, + DEFAULT_SEQUENCE_COUNT), vb(vb) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 3; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t vb = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&vb, &data_field_ptr, &serializedSize, + sizeof(vb), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + + /** * @brief This class packages the space packet to wipe or dump parts of the MRAM. */ @@ -1159,6 +1244,168 @@ private: } }; +/** + * @brief This class packages the space packet change the state of a GPIO. This command is only + * required for ground testing. + */ +class SetGpio: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param port + * @param pin + * @param val + */ + SetGpio(uint8_t port, uint8_t pin, uint8_t val) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_GPIO, + DEFAULT_SEQUENCE_COUNT), port(port), pin(pin), val(val) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 5; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t port = 0; + uint8_t pin = 0; + uint8_t val = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&port, &data_field_ptr, &serializedSize, + sizeof(port), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&pin, &data_field_ptr, &serializedSize, + sizeof(pin), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&val, &data_field_ptr, &serializedSize, + sizeof(val), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet causing the supervisor print the state of a GPIO + * to the debug output. + */ +class ReadGpio: public SpacePacket { +public: + + /** + * @brief Constructor + * + * @param port + * @param pin + */ + ReadGpio(uint8_t port, uint8_t pin) : + SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_READ_GPIO, + DEFAULT_SEQUENCE_COUNT), port(port), pin(pin) { + initPacket(); + } + +private: + + static const uint16_t DATA_FIELD_LENGTH = 4; + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + static const uint16_t CRC_OFFSET = DATA_FIELD_LENGTH - 2; + + uint8_t port = 0; + uint8_t pin = 0; + + void initPacket() { + size_t serializedSize = 0; + uint8_t* data_field_ptr = this->localData.fields.buffer; + SerializeAdapter::serialize(&port, &data_field_ptr, &serializedSize, + sizeof(port), SerializeIF::Endianness::BIG); + serializedSize = 0; + SerializeAdapter::serialize(&pin, &data_field_ptr, &serializedSize, + sizeof(pin), SerializeIF::Endianness::BIG); + serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + +/** + * @brief This class packages the space packet to perform the factory reset. The op parameter is + * optional. + * + * @details: Without OP: All MRAM entries will be cleared. + * OP = 0x01: Only the mirror entries will be wiped. + * OP = 0x02: Only the circular entries will be wiped. + */ +class FactoryReset: public SpacePacket { +public: + + enum class Op { + CLEAR_ALL, + MIRROR_ENTRIES, + CIRCULAR_ENTRIES + }; + + /** + * @brief Constructor + * + * @param op + */ + FactoryReset(Op op) : + SpacePacket(0, true, APID_FACTORY_RESET, + DEFAULT_SEQUENCE_COUNT), op(op) { + initPacket(); + } + +private: + + uint16_t packetLen = 1; // only CRC in data field + static const uint16_t DEFAULT_SEQUENCE_COUNT = 1; + + uint8_t crcOffset = 0; + + Op op = Op::CLEAR_ALL; + + void initPacket() { + + uint8_t* data_field_ptr = this->localData.fields.buffer; + + switch(op) { + case Op::MIRROR_ENTRIES: + *data_field_ptr = 1; + packetLen = 2; + crcOffset = 1; + break; + case Op::CIRCULAR_ENTRIES: + *data_field_ptr = 2; + packetLen = 2; + crcOffset = 1; + break; + default: + break; + } + this->setPacketDataLength(packetLen); + size_t serializedSize = 0; + uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, + sizeof(CCSDSPrimaryHeader) + packetLen - 1); + uint8_t* crcPos = this->localData.fields.buffer + crcOffset; + SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeIF::Endianness::BIG); + } +}; + /** * @brief This dataset stores the boot status report of the supervisor. */ diff --git a/tmtc b/tmtc index 6fcd52da..4aebf4c0 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6fcd52daa693040099cac85367863ad24e477f9a +Subproject commit 4aebf4c0d9a4a094e1a18753bca77d6a3b993378