Moved PLOC components to q7s folder
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
This commit is contained in:
@ -13,4 +13,5 @@ else()
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(memory)
|
||||
add_subdirectory(spiCallbacks)
|
||||
add_subdirectory(devices)
|
||||
endif()
|
||||
|
@ -782,10 +782,10 @@ void CoreController::initPrint() {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
||||
sif::info << "Created UDP server for TMTC commanding with listener port " <<
|
||||
UdpTmTcBridge::DEFAULT_SERVER_PORT << std::endl;
|
||||
UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT << std::endl;
|
||||
#else
|
||||
sif::info << "Created TCP server for TMTC commanding with listener port " <<
|
||||
TcpTmTcBridge::DEFAULT_SERVER_PORT << std::endl;
|
||||
TcpTmTcBridge::DEFAULT_TCP_SERVER_PORT << std::endl;
|
||||
#endif
|
||||
|
||||
if(watchdogFifoFd > 0) {
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "bsp_q7s/spiCallbacks/rwSpiCallback.h"
|
||||
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
||||
#include "bsp_q7s/memory/FileSystemHandler.h"
|
||||
#include "bsp_q7s/devices/PlocSupervisorHandler.h"
|
||||
#include "bsp_q7s/devices/PlocUpdater.h"
|
||||
|
||||
#include "linux/devices/HeaterHandler.h"
|
||||
#include "linux/devices/SolarArrayDeploymentHandler.h"
|
||||
@ -33,7 +35,6 @@
|
||||
#include "mission/devices/MGMHandlerLIS3MDL.h"
|
||||
#include "mission/devices/MGMHandlerRM3100.h"
|
||||
#include "mission/devices/PlocMPSoCHandler.h"
|
||||
#include "mission/devices/PlocSupervisorHandler.h"
|
||||
#include "mission/devices/RadiationSensorHandler.h"
|
||||
#include "mission/devices/RwHandler.h"
|
||||
#include "mission/devices/StarTrackerHandler.h"
|
||||
|
4
bsp_q7s/devices/CMakeLists.txt
Normal file
4
bsp_q7s/devices/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
target_sources(${TARGET_NAME} PRIVATE
|
||||
PlocSupervisorHandler.cpp
|
||||
PlocUpdater.cpp
|
||||
)
|
1418
bsp_q7s/devices/PlocSupervisorHandler.cpp
Normal file
1418
bsp_q7s/devices/PlocSupervisorHandler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
304
bsp_q7s/devices/PlocSupervisorHandler.h
Normal file
304
bsp_q7s/devices/PlocSupervisorHandler.h
Normal file
@ -0,0 +1,304 @@
|
||||
#ifndef MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_
|
||||
#define MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/devices/devicedefinitions/PlocSupervisorDefinitions.h>
|
||||
#include <cstring>
|
||||
#include <fsfw_hal/linux/uart/UartComIF.h>
|
||||
|
||||
/**
|
||||
* @brief This is the device handler for the supervisor of the PLOC which is programmed by
|
||||
* Thales.
|
||||
*
|
||||
* @details The PLOC uses the space packet protocol for communication. To each command the PLOC
|
||||
* answers with at least one acknowledgment and one execution report.
|
||||
* Flight manual:
|
||||
* https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/PLOC_Commands
|
||||
* ILH ICD: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/
|
||||
* Arbeitsdaten/08_Used%20Components/PLOC&fileid=940960
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PlocSupervisorHandler: public DeviceHandlerBase {
|
||||
public:
|
||||
|
||||
PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF * comCookie);
|
||||
virtual ~PlocSupervisorHandler();
|
||||
|
||||
virtual ReturnValue_t initialize() override;
|
||||
|
||||
protected:
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
|
||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override;
|
||||
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, size_t *foundLen) override;
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) override;
|
||||
void setNormalDatapoolEntriesInvalid() override;
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command,
|
||||
uint8_t expectedReplies = 1, bool useAlternateId = false,
|
||||
DeviceCommandId_t alternateReplyID = 0) override;
|
||||
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
||||
|
||||
private:
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_SUPERVISOR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Space Packet received from PLOC supervisor has invalid CRC
|
||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0);
|
||||
//! [EXPORT] : [COMMENT] Received ACK failure reply from PLOC supervisor
|
||||
static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1);
|
||||
//! [EXPORT] : [COMMENT] Received execution failure reply from PLOC supervisor
|
||||
static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||
//! [EXPORT] : [COMMENT] Received space packet with invalid APID from PLOC supervisor
|
||||
static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3);
|
||||
//! [EXPORT] : [COMMENT] Failed to read current system time
|
||||
static const ReturnValue_t GET_TIME_FAILURE = MAKE_RETURN_CODE(0xA4);
|
||||
//! [EXPORT] : [COMMENT] Invalid communication interface specified
|
||||
static const ReturnValue_t INVALID_UART_COM_IF = MAKE_RETURN_CODE(0xA5);
|
||||
//! [EXPORT] : [COMMENT] Received command with invalid watchdog parameter. Valid watchdogs are 0 for PS, 1 for PL and 2 for INT
|
||||
static const ReturnValue_t INVALID_WATCHDOG = MAKE_RETURN_CODE(0xA6);
|
||||
//! [EXPORT] : [COMMENT] Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms.
|
||||
static const ReturnValue_t INVALID_WATCHDOG_TIMEOUT = MAKE_RETURN_CODE(0xA7);
|
||||
//! [EXPORT] : [COMMENT] Received latchup config command with invalid latchup ID
|
||||
static const ReturnValue_t INVALID_LATCHUP_ID = MAKE_RETURN_CODE(0xA8);
|
||||
//! [EXPORT] : [COMMENT] Received set adc sweep period command with invalid sweep period. Must be larger than 21.
|
||||
static const ReturnValue_t SWEEP_PERIOD_TOO_SMALL = MAKE_RETURN_CODE(0xA9);
|
||||
//! [EXPORT] : [COMMENT] Receive auto EM test command with invalid test param. Valid params are 1 and 2.
|
||||
static const ReturnValue_t INVALID_TEST_PARAM = MAKE_RETURN_CODE(0xAA);
|
||||
//! [EXPORT] : [COMMENT] Returned when scanning for MRAM dump packets failed.
|
||||
static const ReturnValue_t MRAM_PACKET_PARSING_FAILURE = MAKE_RETURN_CODE(0xAB);
|
||||
//! [EXPORT] : [COMMENT] Returned when the start and stop addresses of the MRAM dump or MRAM wipe commands are invalid (e.g. start address bigger than stop address)
|
||||
static const ReturnValue_t INVALID_MRAM_ADDRESSES = MAKE_RETURN_CODE(0xAC);
|
||||
//! [EXPORT] : [COMMENT] Expect reception of an MRAM dump packet but received space packet with other apid.
|
||||
static const ReturnValue_t NO_MRAM_PACKET = MAKE_RETURN_CODE(0xAD);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] PLOC supervrisor crc failure in telemetry packet
|
||||
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
|
||||
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(2, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC received execution failure report
|
||||
static const Event SUPV_EXE_FAILURE = MAKE_EVENT(3, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc
|
||||
static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(4, severity::LOW);
|
||||
|
||||
static const uint16_t APID_MASK = 0x7FF;
|
||||
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
|
||||
|
||||
uint8_t commandBuffer[PLOC_SPV::MAX_COMMAND_SIZE];
|
||||
|
||||
/**
|
||||
* This variable is used to store the id of the next reply to receive. This is necessary
|
||||
* because the PLOC sends as reply to each command at least one acknowledgment and execution
|
||||
* report.
|
||||
*/
|
||||
DeviceCommandId_t nextReplyId = PLOC_SPV::NONE;
|
||||
|
||||
UartComIF* uartComIf = nullptr;
|
||||
|
||||
PLOC_SPV::HkSet hkset;
|
||||
PLOC_SPV::BootStatusReport bootStatusReport;
|
||||
PLOC_SPV::LatchupStatusReport latchupStatusReport;
|
||||
|
||||
/** Number of expected replies following the MRAM dump command */
|
||||
uint32_t expectedMramDumpPackets = 0;
|
||||
uint32_t receivedMramDumpPackets = 0;
|
||||
/** Set to true as soon as a complete space packet is present in the spacePacketBuffer */
|
||||
bool packetInBuffer = false;
|
||||
/** Points to the next free position in the space packet buffer */
|
||||
uint16_t bufferTop = 0;
|
||||
|
||||
/** This buffer is used to concatenate space packets received in two different read steps */
|
||||
uint8_t spacePacketBuffer[PLOC_SPV::MAX_PACKET_SIZE];
|
||||
|
||||
/**
|
||||
* @brief This function checks the crc of the received PLOC reply.
|
||||
*
|
||||
* @param start Pointer to the first byte of the reply.
|
||||
* @param foundLen Pointer to the length of the whole packet.
|
||||
*
|
||||
* @return RETURN_OK if CRC is ok, otherwise CRC_FAILURE.
|
||||
*/
|
||||
ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen);
|
||||
|
||||
/**
|
||||
* @brief This function handles the acknowledgment report.
|
||||
*
|
||||
* @param data Pointer to the data holding the acknowledgment report.
|
||||
*
|
||||
* @return RETURN_OK if successful, otherwise an error code.
|
||||
*/
|
||||
ReturnValue_t handleAckReport(const uint8_t* data);
|
||||
|
||||
/**
|
||||
* @brief This function handles the data of a execution report.
|
||||
*
|
||||
* @param data Pointer to the received data packet.
|
||||
*
|
||||
* @return RETURN_OK if successful, otherwise an error code.
|
||||
*/
|
||||
ReturnValue_t handleExecutionReport(const uint8_t* data);
|
||||
|
||||
/**
|
||||
* @brief This function handles the housekeeping report. This means verifying the CRC of the
|
||||
* reply and filling the appropriate dataset.
|
||||
*
|
||||
* @param data Pointer to the data buffer holding the housekeeping read report.
|
||||
*
|
||||
* @return RETURN_OK if successful, otherwise an error code.
|
||||
*/
|
||||
ReturnValue_t handleHkReport(const uint8_t* data);
|
||||
|
||||
/**
|
||||
* @brief This function calls the function to check the CRC of the received boot status report
|
||||
* and fills the associated dataset with the boot status information.
|
||||
*/
|
||||
ReturnValue_t handleBootStatusReport(const uint8_t* data);
|
||||
|
||||
ReturnValue_t handleLatchupStatusReport(const uint8_t* data);
|
||||
|
||||
/**
|
||||
* @brief Depending on the current active command, this function sets the reply id of the
|
||||
* next reply after a successful acknowledgment report has been received. This is
|
||||
* required by the function getNextReplyLength() to identify the length of the next
|
||||
* reply to read.
|
||||
*/
|
||||
void setNextReplyId();
|
||||
|
||||
/**
|
||||
* @brief This function handles action message replies in case the telemetry has been
|
||||
* requested by another object.
|
||||
*
|
||||
* @param data Pointer to the telemetry data.
|
||||
* @param dataSize Size of telemetry in bytes.
|
||||
* @param replyId Id of the reply. This will be added to the ActionMessage.
|
||||
*/
|
||||
void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId);
|
||||
|
||||
/**
|
||||
* @brief This function prepares a space packet which does not transport any data in the
|
||||
* packet data field apart from the crc.
|
||||
*/
|
||||
void prepareEmptyCmd(uint16_t apid);
|
||||
|
||||
/**
|
||||
* @brief This function initializes the space packet to select the boot image of the MPSoC.
|
||||
*/
|
||||
void prepareSelBootImageCmd(const uint8_t * commandData);
|
||||
|
||||
void prepareDisableHk();
|
||||
|
||||
/**
|
||||
* @brief This function fills the commandBuffer with the data to update the time of the
|
||||
* PLOC supervisor.
|
||||
*/
|
||||
ReturnValue_t prepareSetTimeRefCmd();
|
||||
|
||||
/**
|
||||
* @brief This function fills the commandBuffer with the data to change the boot timeout
|
||||
* value in the PLOC supervisor.
|
||||
*/
|
||||
void prepareSetBootTimeoutCmd(const uint8_t * commandData);
|
||||
|
||||
void prepareRestartTriesCmd(const uint8_t * commandData);
|
||||
|
||||
/**
|
||||
* @brief This function fills the command buffer with the packet to notify the supervisor
|
||||
* about the availability of an update for the MPSoC
|
||||
*/
|
||||
void prepareUpdateAvailableCmd(const uint8_t * commandData);
|
||||
|
||||
/**
|
||||
* @brief This function fills the command buffer with the packet to enable or disable the
|
||||
* watchdogs on the PLOC.
|
||||
*/
|
||||
void prepareWatchdogsEnableCmd(const uint8_t * commandData);
|
||||
|
||||
/**
|
||||
* @brief This function fills the command buffer with the packet to set the watchdog timer
|
||||
* of one of the three watchdogs (PS, PL, INT).
|
||||
*/
|
||||
ReturnValue_t prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData);
|
||||
|
||||
ReturnValue_t prepareLatchupConfigCmd(const uint8_t* commandData,
|
||||
DeviceCommandId_t deviceCommand);
|
||||
ReturnValue_t prepareAutoCalibrateAlertCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareSetAlertLimitCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareSetAlertIrqFilterCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareSetAdcSweetPeriodCmd(const uint8_t* commandData);
|
||||
void prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData);
|
||||
void prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData);
|
||||
void prepareSetAdcThresholdCmd(const uint8_t* commandData);
|
||||
void prepareEnableNvmsCmd(const uint8_t* commandData);
|
||||
void prepareSelectNvmCmd(const uint8_t* commandData);
|
||||
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);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Copies the content of a space packet to the command buffer.
|
||||
*/
|
||||
void packetToOutBuffer(uint8_t* packetData, size_t fullSize);
|
||||
|
||||
/**
|
||||
* @brief In case an acknowledgment failure reply has been received this function disables
|
||||
* all previously enabled commands and resets the exepected replies variable of an
|
||||
* active command.
|
||||
*/
|
||||
void disableAllReplies();
|
||||
|
||||
/**
|
||||
* @brief This function sends a failure report if the active action was commanded by an other
|
||||
* object.
|
||||
*
|
||||
* @param replyId The id of the reply which signals a failure.
|
||||
* @param status A status byte which gives information about the failure type.
|
||||
*/
|
||||
void sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status);
|
||||
|
||||
/**
|
||||
* @brief This function disables the execution report reply. Within this function also the
|
||||
* the variable expectedReplies of an active command will be set to 0.
|
||||
*/
|
||||
void disableExeReportReply();
|
||||
|
||||
/**
|
||||
* @brief Function is called in scanForReply and fills the spacePacketBuffer with the read
|
||||
* data until a full packet has been received.
|
||||
*/
|
||||
ReturnValue_t parseMramPackets(const uint8_t *packet, size_t remainingSize, size_t* foundlen);
|
||||
|
||||
/**
|
||||
* @brief This function generates the Service 8 packets for the MRAM dump data.
|
||||
*/
|
||||
ReturnValue_t handleMramDumpPacket();
|
||||
|
||||
/**
|
||||
* @brief With this function the number of expected replies following an MRAM dump command
|
||||
* will be increased. This is necessary to release the command in case not all replies
|
||||
* have been received.
|
||||
*/
|
||||
void increaseExpectedMramReplies();
|
||||
|
||||
/**
|
||||
* @brief Function checks if the packet written to the space packet buffer is really a
|
||||
* MRAM dump packet.
|
||||
*/
|
||||
ReturnValue_t checkMramPacketApid();
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */
|
397
bsp_q7s/devices/PlocUpdater.cpp
Normal file
397
bsp_q7s/devices/PlocUpdater.cpp
Normal file
@ -0,0 +1,397 @@
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "PlocUpdater.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
PlocUpdater::PlocUpdater(object_id_t objectId) :
|
||||
SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||
}
|
||||
|
||||
PlocUpdater::~PlocUpdater() {
|
||||
}
|
||||
|
||||
ReturnValue_t PlocUpdater::initialize() {
|
||||
sdcMan = SdCardManager::instance();
|
||||
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = commandActionHelper.initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = actionHelper.initialize(commandQueue);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocUpdater::performOperation(uint8_t operationCode) {
|
||||
readCommandQueue();
|
||||
doStateMachine();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
|
||||
if (state != State::IDLE) {
|
||||
return IS_BUSY;
|
||||
}
|
||||
|
||||
if (size > MAX_PLOC_UPDATE_PATH) {
|
||||
return NAME_TOO_LONG;
|
||||
}
|
||||
|
||||
switch (actionId) {
|
||||
case UPDATE_NVM0_A:
|
||||
updatePartition = Partition::A;
|
||||
updateMemory = Memory::NVM0;
|
||||
break;
|
||||
case UPDATE_NVM0_B:
|
||||
updatePartition = Partition::B;
|
||||
updateMemory = Memory::NVM0;
|
||||
break;
|
||||
case UPDATE_NVM1_A:
|
||||
updatePartition = Partition::A;
|
||||
updateMemory = Memory::NVM1;
|
||||
break;
|
||||
case UPDATE_NVM1_B:
|
||||
updatePartition = Partition::B;
|
||||
updateMemory = Memory::NVM1;
|
||||
break;
|
||||
default:
|
||||
return INVALID_ACTION_ID;
|
||||
}
|
||||
|
||||
result = getImageLocation(data, size);
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
state = State::UPDATE_AVAILABLE;
|
||||
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
|
||||
MessageQueueId_t PlocUpdater::getCommandQueue() const {
|
||||
return commandQueue->getId();
|
||||
}
|
||||
|
||||
MessageQueueIF* PlocUpdater::getCommandQueuePtr() {
|
||||
return commandQueue;
|
||||
}
|
||||
|
||||
void PlocUpdater::readCommandQueue() {
|
||||
CommandMessage message;
|
||||
ReturnValue_t result;
|
||||
|
||||
for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK;
|
||||
result = commandQueue->receiveMessage(&message)) {
|
||||
if (result != RETURN_OK) {
|
||||
continue;
|
||||
}
|
||||
result = actionHelper.handleActionMessage(&message);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result = commandActionHelper.handleReply(&message);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sif::debug << "PlocUpdater::readCommandQueue: Received message with invalid format"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void PlocUpdater::doStateMachine() {
|
||||
switch (state) {
|
||||
case State::IDLE:
|
||||
break;
|
||||
case State::UPDATE_AVAILABLE:
|
||||
commandUpdateAvailable();
|
||||
break;
|
||||
case State::UPDATE_TRANSFER:
|
||||
commandUpdatePacket();
|
||||
break;
|
||||
case State::UPDATE_VERIFY:
|
||||
commandUpdateVerify();
|
||||
break;
|
||||
case State::COMMAND_EXECUTING:
|
||||
break;
|
||||
default:
|
||||
sif::debug << "PlocUpdater::doStateMachine: Invalid state" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PlocUpdater::checkNameLength(size_t size) {
|
||||
if (size > MAX_PLOC_UPDATE_PATH) {
|
||||
return NAME_TOO_LONG;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result = checkNameLength(size);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if file is stored on SD card and if associated SD card is mounted
|
||||
if (std::string(reinterpret_cast<const char*>(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) {
|
||||
if (!isSdCardMounted(sd::SLOT_0)) {
|
||||
sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 0 not mounted" << std::endl;
|
||||
return SD_NOT_MOUNTED;
|
||||
}
|
||||
}
|
||||
else if (std::string(reinterpret_cast<const char*>(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) {
|
||||
if (!isSdCardMounted(sd::SLOT_0)) {
|
||||
sif::warning << "PlocUpdater::prepareNvm0AUpdate: SD card 1 not mounted" << std::endl;
|
||||
return SD_NOT_MOUNTED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//update image not stored on SD card
|
||||
}
|
||||
|
||||
updateFile = std::string(reinterpret_cast<const char*>(data), size);
|
||||
|
||||
// Check if file exists
|
||||
if(not std::filesystem::exists(updateFile)) {
|
||||
return FILE_NOT_EXISTS;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
bool PlocUpdater::isSdCardMounted(sd::SdCard sdCard) {
|
||||
SdCardManager::SdStatePair active;
|
||||
ReturnValue_t result = sdcMan->getSdCardActiveStatus(active);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocUpdater::isSdCardMounted: Failed to get SD card active state";
|
||||
return false;
|
||||
}
|
||||
if (sdCard == sd::SLOT_0) {
|
||||
if (active.first == sd::MOUNTED) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (sdCard == sd::SLOT_1) {
|
||||
if (active.second == sd::MOUNTED) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
sif::debug << "PlocUpdater::isSdCardMounted: Unknown SD card specified" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId,
|
||||
uint8_t step) {
|
||||
}
|
||||
|
||||
void PlocUpdater::stepFailedReceived(ActionId_t actionId, uint8_t step,
|
||||
ReturnValue_t returnCode) {
|
||||
}
|
||||
|
||||
void PlocUpdater::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {
|
||||
|
||||
}
|
||||
|
||||
void PlocUpdater::completionSuccessfulReceived(ActionId_t actionId) {
|
||||
switch (pendingCommand) {
|
||||
case (PLOC_SPV::UPDATE_AVAILABLE):
|
||||
state = State::UPDATE_TRANSFER;
|
||||
break;
|
||||
case (PLOC_SPV::UPDATE_IMAGE_DATA):
|
||||
if (remainingPackets == 0) {
|
||||
packetsSent = 0; // Reset packets sent variable for next update sequence
|
||||
state = State::UPDATE_VERIFY;
|
||||
}
|
||||
else {
|
||||
state = State::UPDATE_TRANSFER;
|
||||
}
|
||||
break;
|
||||
case (PLOC_SPV::UPDATE_VERIFY):
|
||||
triggerEvent(UPDATE_FINISHED);
|
||||
state = State::IDLE;
|
||||
pendingCommand = PLOC_SPV::NONE;
|
||||
break;
|
||||
default:
|
||||
sif::debug << "PlocUpdater::completionSuccessfulReceived: Invalid pending command"
|
||||
<< std::endl;
|
||||
state = State::IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PlocUpdater::completionFailedReceived(ActionId_t actionId,
|
||||
ReturnValue_t returnCode) {
|
||||
switch(pendingCommand) {
|
||||
case(PLOC_SPV::UPDATE_AVAILABLE): {
|
||||
triggerEvent(UPDATE_AVAILABLE_FAILED);
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::UPDATE_IMAGE_DATA): {
|
||||
triggerEvent(UPDATE_TRANSFER_FAILED, packetsSent);
|
||||
break;
|
||||
}
|
||||
case(PLOC_SPV::UPDATE_VERIFY): {
|
||||
triggerEvent(UPDATE_VERIFY_FAILED);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sif::debug << "PlocUpdater::completionFailedReceived: Invalid pending command "
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
state = State::IDLE;
|
||||
}
|
||||
|
||||
void PlocUpdater::commandUpdateAvailable() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
if (not std::filesystem::exists(updateFile)) {
|
||||
triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast<uint8_t>(state));
|
||||
state = State::IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
std::ifstream file(updateFile, std::ifstream::binary);
|
||||
file.seekg(0, file.end);
|
||||
imageSize = static_cast<size_t>(file.tellg());
|
||||
file.close();
|
||||
|
||||
numOfUpdatePackets = imageSize / MAX_SP_DATA ;
|
||||
if (imageSize % MAX_SP_DATA) {
|
||||
numOfUpdatePackets++;
|
||||
}
|
||||
|
||||
remainingPackets = numOfUpdatePackets;
|
||||
packetsSent = 0;
|
||||
|
||||
uint32_t imageCrc = makeCrc();
|
||||
|
||||
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast<uint8_t>(updateMemory),
|
||||
static_cast<uint8_t>(updatePartition), imageSize, imageCrc, numOfUpdatePackets);
|
||||
|
||||
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
|
||||
PLOC_SPV::UPDATE_AVAILABLE, packet.getWholeData(), packet.getFullSize());
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available"
|
||||
<< " packet to supervisor handler" << std::endl;
|
||||
triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_AVAILABLE);
|
||||
state = State::IDLE;
|
||||
pendingCommand = PLOC_SPV::NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
pendingCommand = PLOC_SPV::UPDATE_AVAILABLE;
|
||||
state = State::COMMAND_EXECUTING;
|
||||
return;
|
||||
}
|
||||
|
||||
void PlocUpdater::commandUpdatePacket() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
uint16_t payloadLength = 0;
|
||||
|
||||
if (not std::filesystem::exists(updateFile)) {
|
||||
triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast<uint8_t>(state), packetsSent);
|
||||
state = State::IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
std::ifstream file(updateFile, std::ifstream::binary);
|
||||
file.seekg(packetsSent * MAX_SP_DATA, file.beg);
|
||||
|
||||
if (remainingPackets == 1) {
|
||||
payloadLength = imageSize - static_cast<uint16_t>(file.tellg());
|
||||
}
|
||||
else {
|
||||
payloadLength = MAX_SP_DATA;
|
||||
}
|
||||
|
||||
PLOC_SPV::UpdatePacket packet(payloadLength);
|
||||
file.read(reinterpret_cast<char*>(packet.getDataFieldPointer()), payloadLength);
|
||||
file.close();
|
||||
// sequence count of first packet is 1
|
||||
packet.setPacketSequenceCount((packetsSent + 1) & PLOC_SPV::SEQUENCE_COUNT_MASK);
|
||||
if (numOfUpdatePackets > 0) {
|
||||
adjustSequenceFlags(packet);
|
||||
}
|
||||
packet.makeCrc();
|
||||
|
||||
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
|
||||
PLOC_SPV::UPDATE_IMAGE_DATA, packet.getWholeData(), packet.getFullSize());
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update"
|
||||
<< " packet to supervisor handler" << std::endl;
|
||||
triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_IMAGE_DATA);
|
||||
state = State::IDLE;
|
||||
pendingCommand = PLOC_SPV::NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
remainingPackets--;
|
||||
packetsSent++;
|
||||
|
||||
pendingCommand = PLOC_SPV::UPDATE_IMAGE_DATA;
|
||||
state = State::COMMAND_EXECUTING;
|
||||
}
|
||||
|
||||
void PlocUpdater::commandUpdateVerify() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast<uint8_t>(updateMemory),
|
||||
static_cast<uint8_t>(updatePartition), imageSize, imageCrc, numOfUpdatePackets);
|
||||
|
||||
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
|
||||
PLOC_SPV::UPDATE_VERIFY, packet.getWholeData(), packet.getFullSize());
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available"
|
||||
<< " packet to supervisor handler" << std::endl;
|
||||
triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_VERIFY);
|
||||
state = State::IDLE;
|
||||
pendingCommand = PLOC_SPV::NONE;
|
||||
return;
|
||||
}
|
||||
state = State::COMMAND_EXECUTING;
|
||||
pendingCommand = PLOC_SPV::UPDATE_VERIFY;
|
||||
return;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocUpdater::makeCrc() {
|
||||
//TODO: Waiting on input from TAS about the CRC to use
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PlocUpdater::adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet) {
|
||||
if (packetsSent == 0) {
|
||||
packet.setSequenceFlags(static_cast<uint8_t>(PLOC_SPV::SequenceFlags::FIRST_PKT));
|
||||
}
|
||||
else if (remainingPackets == 1) {
|
||||
packet.setSequenceFlags(static_cast<uint8_t>(PLOC_SPV::SequenceFlags::LAST_PKT));
|
||||
}
|
||||
else {
|
||||
packet.setSequenceFlags(static_cast<uint8_t>(PLOC_SPV::SequenceFlags::CONTINUED_PKT));
|
||||
}
|
||||
}
|
||||
|
171
bsp_q7s/devices/PlocUpdater.h
Normal file
171
bsp_q7s/devices/PlocUpdater.h
Normal file
@ -0,0 +1,171 @@
|
||||
#ifndef MISSION_DEVICES_PLOCUPDATER_H_
|
||||
#define MISSION_DEVICES_PLOCUPDATER_H_
|
||||
|
||||
#include "fsfw/action/CommandActionHelper.h"
|
||||
#include "fsfw/action/ActionHelper.h"
|
||||
#include "fsfw/action/HasActionsIF.h"
|
||||
#include "fsfw/action/CommandsActionsIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "bsp_q7s/memory/SdCardManager.h"
|
||||
#include "linux/fsfwconfig/objects/systemObjectList.h"
|
||||
#include "fsfw/tmtcpacket/SpacePacket.h"
|
||||
#include "OBSWConfig.h"
|
||||
#include <mission/devices/devicedefinitions/PlocSupervisorDefinitions.h>
|
||||
|
||||
/**
|
||||
* @brief An object of this class can be used to perform the software updates of the PLOC. The
|
||||
* software update will be read from one of the SD cards, split into multiple space
|
||||
* packets and sent to the PlocSupervisorHandler.
|
||||
*
|
||||
* @details The MPSoC has two boot memories (NVM0 and NVM1) where each stores two images (Partition A
|
||||
* and Partition B)
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PlocUpdater : public SystemObject,
|
||||
public HasActionsIF,
|
||||
public ExecutableObjectIF,
|
||||
public HasReturnvaluesIF,
|
||||
public CommandsActionsIF {
|
||||
public:
|
||||
|
||||
static const ActionId_t UPDATE_NVM0_A = 0;
|
||||
static const ActionId_t UPDATE_NVM0_B = 1;
|
||||
static const ActionId_t UPDATE_NVM1_A = 2;
|
||||
static const ActionId_t UPDATE_NVM1_B = 3;
|
||||
|
||||
PlocUpdater(object_id_t objectId);
|
||||
virtual ~PlocUpdater();
|
||||
|
||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size);
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
ReturnValue_t initialize() override;
|
||||
MessageQueueIF* getCommandQueuePtr() override;
|
||||
void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override;
|
||||
void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override;
|
||||
void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override;
|
||||
void completionSuccessfulReceived(ActionId_t actionId) override;
|
||||
void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override;
|
||||
|
||||
private:
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_UPDATER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Updater is already performing an update
|
||||
static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0);
|
||||
//! [EXPORT] : [COMMENT] Received update command with invalid path string (too long).
|
||||
static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA1);
|
||||
//! [EXPORT] : [COMMENT] Received command to initiate update but SD card with update image not mounted.
|
||||
static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA2);
|
||||
//! [EXPORT] : [COMMENT] Update file received with update command does not exist.
|
||||
static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA3);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_UPDATER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Try to read update file but the file does not exist.
|
||||
//! P1: Indicates in which state the file read fails
|
||||
//! P2: During the update transfer the second parameter gives information about the number of already sent packets
|
||||
static const Event UPDATE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Failed to send command to supervisor handler
|
||||
//! P1: Return value of CommandActionHelper::commandAction
|
||||
//! P2: Action ID of command to send
|
||||
static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Supervisor handler replied action message indicating a command execution failure of the update available command
|
||||
static const Event UPDATE_AVAILABLE_FAILED = MAKE_EVENT(2, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Supervisor handler failed to transfer an update space packet.
|
||||
//! P1: Parameter holds the number of update packets already sent (inclusive the failed packet)
|
||||
static const Event UPDATE_TRANSFER_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Supervisor failed to execute the update verify command.
|
||||
static const Event UPDATE_VERIFY_FAILED = MAKE_EVENT(4, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] MPSoC update successful completed
|
||||
static const Event UPDATE_FINISHED = MAKE_EVENT(5, severity::INFO);
|
||||
|
||||
static const uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE;
|
||||
static const size_t MAX_PLOC_UPDATE_PATH = 50;
|
||||
static const size_t SD_PREFIX_LENGTH = 8;
|
||||
// Maximum size of update payload data per space packet (max size of space packet is 1024 bytes)
|
||||
static const size_t MAX_SP_DATA = 1016;
|
||||
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
|
||||
SdCardManager* sdcMan = nullptr;
|
||||
|
||||
CommandActionHelper commandActionHelper;
|
||||
|
||||
ActionHelper actionHelper;
|
||||
|
||||
enum class State: uint8_t {
|
||||
IDLE,
|
||||
UPDATE_AVAILABLE,
|
||||
UPDATE_TRANSFER,
|
||||
UPDATE_VERIFY,
|
||||
COMMAND_EXECUTING
|
||||
};
|
||||
|
||||
State state = State::IDLE;
|
||||
|
||||
ActionId_t pendingCommand = PLOC_SPV::NONE;
|
||||
|
||||
enum class Memory: uint8_t {
|
||||
NVM0,
|
||||
NVM1
|
||||
};
|
||||
|
||||
Memory updateMemory = Memory::NVM0;
|
||||
|
||||
enum class Partition: uint8_t {
|
||||
A,
|
||||
B
|
||||
};
|
||||
|
||||
Partition updatePartition = Partition::A;
|
||||
|
||||
uint32_t packetsSent = 0;
|
||||
uint32_t remainingPackets = 0;
|
||||
// Number of packets required to transfer the update image
|
||||
uint32_t numOfUpdatePackets = 0;
|
||||
|
||||
std::string updateFile;
|
||||
uint32_t imageSize = 0;
|
||||
uint32_t imageCrc = 0;
|
||||
|
||||
void readCommandQueue();
|
||||
void doStateMachine();
|
||||
|
||||
/**
|
||||
* @brief Extracts the path and name of the update image from the service 8 command data.
|
||||
*/
|
||||
ReturnValue_t getImageLocation(const uint8_t* data, size_t size);
|
||||
|
||||
ReturnValue_t checkNameLength(size_t size);
|
||||
|
||||
/**
|
||||
* @brief Prepares and sends update available command to PLOC supervisor handler.
|
||||
*/
|
||||
void commandUpdateAvailable();
|
||||
|
||||
/**
|
||||
* @brief Prepares and sends and update packet to the PLOC supervisor handler.
|
||||
*/
|
||||
void commandUpdatePacket();
|
||||
|
||||
/**
|
||||
* @brief Prepares and sends the update verification packet to the PLOC supervisor handler.
|
||||
*/
|
||||
void commandUpdateVerify();
|
||||
|
||||
/**
|
||||
* @brief Checks whether the SD card to read from is mounted or not.
|
||||
*/
|
||||
bool isSdCardMounted(sd::SdCard sdCard);
|
||||
|
||||
ReturnValue_t makeCrc();
|
||||
|
||||
void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet);
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_PLOCUPDATER_H_ */
|
Reference in New Issue
Block a user