meier/plocUpdater #76
@ -17,6 +17,7 @@ enum: uint8_t {
|
|||||||
STR_HANDLER = 114,
|
STR_HANDLER = 114,
|
||||||
PLOC_SUPERVISOR_HANDLER = 115,
|
PLOC_SUPERVISOR_HANDLER = 115,
|
||||||
FILE_SYSTEM = 116,
|
FILE_SYSTEM = 116,
|
||||||
|
PLOC_UPDATER = 117,
|
||||||
COMMON_SUBSYSTEM_ID_END
|
COMMON_SUBSYSTEM_ID_END
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -241,6 +241,12 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(
|
|||||||
result = RETURN_OK;
|
result = RETURN_OK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case(PLOC_SPV::UPDATE_AVAILABLE):
|
||||||
|
case(PLOC_SPV::UPDATE_AVAILABLE):
|
||||||
|
case(PLOC_SPV::UPDATE_AVAILABLE):
|
||||||
|
// Simply forward data from PLOC Updater to supervisor
|
||||||
|
std::memcpy(rawPacket, commandData, commandDataLen);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented"
|
sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
@ -82,7 +82,7 @@ private:
|
|||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] PLOC supervrisor crc failure in telemetry packet
|
//! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet
|
||||||
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
|
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||||
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
|
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
|
||||||
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(2, severity::LOW);
|
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(2, severity::LOW);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <mission/devices/PlocUpdater.h>
|
#include <mission/devices/PlocUpdater.h>
|
||||||
|
#include <mission/devices/devicedefinitions/PlocSupervisorDefinitions.h>
|
||||||
|
|
||||||
PlocUpdater::PlocUpdater() : commandActionHelper(this) {
|
PlocUpdater::PlocUpdater() : commandActionHelper(this) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||||
@ -7,11 +8,16 @@ PlocUpdater::PlocUpdater() : commandActionHelper(this) {
|
|||||||
PlocUpdater::~PlocUpdater() {
|
PlocUpdater::~PlocUpdater() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t SystemObject::initialize() {
|
||||||
|
sdcMan = SdCardManager::instance();
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId,
|
ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId,
|
||||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||||
ReturnValue_t result = RETURN_FAILED;
|
ReturnValue_t result = RETURN_FAILED;
|
||||||
|
|
||||||
if (state == BUSY) {
|
if (state != IDLE) {
|
||||||
return IS_BUSY;
|
return IS_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,20 +27,27 @@ ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId,
|
|||||||
|
|
||||||
switch (actionId) {
|
switch (actionId) {
|
||||||
case UPDATE_NVM0_A:
|
case UPDATE_NVM0_A:
|
||||||
result = prepareNvm0AUpdate(std::string(data, size));
|
updateImage = Image::A;
|
||||||
|
updateMemory = Memory::NVM0;
|
||||||
break;
|
break;
|
||||||
case UPDATE_NVM0_B:
|
case UPDATE_NVM0_B:
|
||||||
result = prepareNvm0BUpdate();
|
updateImage = Image::B;
|
||||||
|
updateMemory = Memory::NVM0;
|
||||||
break;
|
break;
|
||||||
case UPDATE_NVM1_A:
|
case UPDATE_NVM1_A:
|
||||||
result = prepareNvm1AUpdate();
|
updateImage = Image::A;
|
||||||
|
updateMemory = Memory::NVM1;
|
||||||
break;
|
break;
|
||||||
case UPDATE_NVM1_B:
|
case UPDATE_NVM1_B:
|
||||||
result = prepareNvm1BUpdate();
|
updateImage = Image::B;
|
||||||
|
updateMemory = Memory::NVM1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_ACTION_ID;
|
return INVALID_ACTION_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = getImageLocation(data, size);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,13 +55,265 @@ MessageQueueId_t PlocUpdater::getCommandQueue() const {
|
|||||||
return commandQueue.getId();
|
return commandQueue.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PlocUpdater::checkPath(size_t size) {
|
void PlocUpdater::readCommandQueue() {
|
||||||
|
CommandMessage message;
|
||||||
|
ReturnValue_t result = commandQueue->receiveMessage(&message);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
result = actionHelper.handleActionMessage(&message);
|
||||||
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = commandActionHelper.handleReply(&message);
|
||||||
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result = parameterHelper.handleParameterMessage(&message);
|
||||||
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
message.setToUnknownCommand();
|
||||||
|
commandQueue.reply(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::debug << "PlocUpdater::doStateMachine: Invalid state" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocUpdater::checkNameLength(size_t size) {
|
||||||
if (size > MAX_PLOC_UPDATE_PATH) {
|
if (size > MAX_PLOC_UPDATE_PATH) {
|
||||||
return PATH_TOO_LONG;
|
return NAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlocUpdater::prepare
|
ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) {
|
||||||
getCurrentMountPrefix
|
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(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(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<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) {
|
||||||
|
SdStatusPair 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::completionSuccessfulReceived(ActionId_t actionId) {
|
||||||
|
switch (actionId) {
|
||||||
|
case UPDATE_AVAILABLE:
|
||||||
|
state = State::UPDATE_TRANSFER;
|
||||||
|
break;
|
||||||
|
case UPDATE_IMAGE_DATA:
|
||||||
|
if (remainingPackets == 0) {
|
||||||
|
packetsSent = 0; // Reset packets sent variable for next update sequence
|
||||||
|
state = State::UPDATE_VERIFY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UPDATE_VERIFY:
|
||||||
|
triggerEvent(UPDATE_FINISHED);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::debug << "PlocUpdater::completionSuccessfulReceived: Action message with has unknown "
|
||||||
|
<< "action id" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlocUpdater::completionFailedReceived(ActionId_t actionId,
|
||||||
|
ReturnValue_t returnCode) {
|
||||||
|
state = State::IDLE;
|
||||||
|
switch(state) {
|
||||||
|
case(State::UPDATE_AVAILABLE): {
|
||||||
|
triggerEvent(UPDATE_AVAILABLE_FAILED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(State::UPDATE_TRANSFER): {
|
||||||
|
triggerEvent(UPDATE_TRANSFER_FAILED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case(State::UPDATE_VERIFY): {
|
||||||
|
triggerEvent(UPDATE_VERIFY_FAILED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
sif::debug << "PlocUpdater::completionFailedReceived: Action message with has unknown "
|
||||||
|
<< "action id" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlocUpdater::commandUpdateAvailable() {
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
|
||||||
|
if (not std::filesystem::exists(updateFile)) {
|
||||||
|
triggerEvent(UPDATE_FILE_NOT_EXISTS, 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, UPDATE_AVAILABLE,
|
||||||
|
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, UPDATE_AVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlocUpdater::commandUpdatePacket() {
|
||||||
|
uint16_t payloadLength = 0;
|
||||||
|
|
||||||
|
if (not std::filesystem::exists(updateFile)) {
|
||||||
|
triggerEvent(UPDATE_FILE_NOT_EXISTS, 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 = static_cast<uint16_t>(file.tellg());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
payloadLength = MAX_SP_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLOC_SPV::UpdatePacket packet(payloadLength);
|
||||||
|
file.read(static_cast<char*>(packet.getDataFieldPointer()), payloadLength);
|
||||||
|
file.close();
|
||||||
|
packet.updateCrc();
|
||||||
|
|
||||||
|
commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, UPDATE_IMAGE_DATA,
|
||||||
|
packet.getDataFieldPointer(), packet.getFullSize());
|
||||||
|
remainingPackets--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlocUpdater::commandUpdateVerify() {
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
|
||||||
|
if (not std::filesystem::exists(updateFile)) {
|
||||||
|
triggerEvent(UPDATE_FILE_NOT_EXISTS, state);
|
||||||
|
state = State::IDLE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
remainingPackets = imageSize / MAX_SP_DATA ;
|
||||||
|
if (! imageSize % MAX_SP_DATA) {
|
||||||
|
remainingPackets++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t imageCrc = makeCrc();
|
||||||
|
|
||||||
|
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, UPDATE_AVAILABLE,
|
||||||
|
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, UPDATE_AVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PlocUpdater::makeCrc() {
|
||||||
|
//TODO: Waiting on input from TAS about the CRC to use
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -3,13 +3,16 @@
|
|||||||
|
|
||||||
#include "fsfw/action/CommandActionHelper.h"
|
#include "fsfw/action/CommandActionHelper.h"
|
||||||
#include "fsfw/returnvalues/HasReturnValuesIF.h"
|
#include "fsfw/returnvalues/HasReturnValuesIF.h"
|
||||||
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
|
#include "linux/fsfwconfig/objects/systemObjectList.h"
|
||||||
|
#include "fsfw/tmtcpacket/SpacePacket.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief An object of this class can be used to perform the software updates of the PLOC. The
|
* @brief An object of this class can be used to perform the software updates of the PLOC. The
|
||||||
* software update will be fetched via file system messages from the SD card handler,
|
* software update will be fetched via file system messages from the SD card handler,
|
||||||
* split into multiple space packets and sent to the PlocSupervisorHandler.
|
* split into multiple space packets and sent to the PlocSupervisorHandler.
|
||||||
*
|
*
|
||||||
* @details The MPSoC has to boot memories (NVM0 and NVM1) where each stores two images (Partition A
|
* @details The MPSoC has two boot memories (NVM0 and NVM1) where each stores two images (Partition A
|
||||||
* and Partition B)
|
* and Partition B)
|
||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
@ -17,7 +20,8 @@
|
|||||||
class PlocUpdater : public SystemObject,
|
class PlocUpdater : public SystemObject,
|
||||||
public HasActionsIF,
|
public HasActionsIF,
|
||||||
public ExecutableObjectIF,
|
public ExecutableObjectIF,
|
||||||
public HasReturnvaluesIF {
|
public HasReturnvaluesIF,
|
||||||
|
public CommandsActionsIF {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static const ActionId_t UPDATE_NVM0_A = 0;
|
static const ActionId_t UPDATE_NVM0_A = 0;
|
||||||
@ -31,6 +35,12 @@ public:
|
|||||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size);
|
const uint8_t* data, size_t size);
|
||||||
MessageQueueId_t getCommandQueue() const;
|
MessageQueueId_t getCommandQueue() const;
|
||||||
|
ReturnValue_t initialize() 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:
|
private:
|
||||||
|
|
||||||
@ -39,14 +49,88 @@ private:
|
|||||||
//! [EXPORT] : [COMMENT] Updater is already performing an update
|
//! [EXPORT] : [COMMENT] Updater is already performing an update
|
||||||
static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0);
|
static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0);
|
||||||
//! [EXPORT] : [COMMENT] Received update command with invalid path string (too long).
|
//! [EXPORT] : [COMMENT] Received update command with invalid path string (too long).
|
||||||
static const ReturnValue_t PATH_TOO_LONG = MAKE_RETURN_CODE(0xA0);
|
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.
|
||||||
|
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 uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE;
|
||||||
static const size_t MAX_PLOC_UPDATE_PATH = 20;
|
static const size_t MAX_PLOC_UPDATE_PATH = 20;
|
||||||
|
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;
|
||||||
|
|
||||||
|
static const ActionId_t UPDATE_AVAILABLE = 12;
|
||||||
|
static const ActionId_t UPDATE_IMAGE_DATA = 39;
|
||||||
|
static const ActionId_t UPDATE_VERIFY = 42;
|
||||||
|
|
||||||
|
SdCardManager* sdcMan = nullptr;
|
||||||
|
|
||||||
CommandActionHelper commandActionHelper;
|
CommandActionHelper commandActionHelper;
|
||||||
|
|
||||||
ReturnValue_t checkPath(size_t size);
|
enum class State: uint8_t {
|
||||||
|
IDLE,
|
||||||
|
UPDATE_AVAILABLE,
|
||||||
|
UPDATE_TRANSFER,
|
||||||
|
UPDATE_VERIFY
|
||||||
|
};
|
||||||
|
|
||||||
|
State state = State::IDLE;
|
||||||
|
|
||||||
|
enum class Memory: uint8_t {
|
||||||
|
NVM0,
|
||||||
|
NVM1
|
||||||
|
};
|
||||||
|
|
||||||
|
Memory updateMemory = Memory::NVM0;
|
||||||
|
|
||||||
|
enum class Partition: uint8_t {
|
||||||
|
A,
|
||||||
|
B
|
||||||
|
};
|
||||||
|
|
||||||
|
Partition updatePartition = Partition::A;
|
||||||
|
|
||||||
|
State state = State::IDLE;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
ReturnValue_t checkNameLength(size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether the SD card to read from is mounted or not.
|
||||||
|
*/
|
||||||
|
bool isSdCardMounted(sd::SdCard sdCard);
|
||||||
|
|
||||||
|
ReturnValue_t makeCrc();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_PLOCUPDATER_H_ */
|
#endif /* MISSION_DEVICES_PLOCUPDATER_H_ */
|
||||||
|
@ -52,6 +52,7 @@ static const DeviceCommandId_t REQUEST_LOGGING_DATA = 38;
|
|||||||
static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39;
|
static const DeviceCommandId_t UPDATE_IMAGE_DATA = 39;
|
||||||
static const DeviceCommandId_t FACTORY_RESET_CLEAR_MIRROR = 40;
|
static const DeviceCommandId_t FACTORY_RESET_CLEAR_MIRROR = 40;
|
||||||
static const DeviceCommandId_t FACTORY_RESET_CLEAR_CIRCULAR = 41;
|
static const DeviceCommandId_t FACTORY_RESET_CLEAR_CIRCULAR = 41;
|
||||||
|
static const DeviceCommandId_t UPDATE_VERIFY = 42;
|
||||||
|
|
||||||
/** Reply IDs */
|
/** Reply IDs */
|
||||||
static const DeviceCommandId_t ACK_REPORT = 50;
|
static const DeviceCommandId_t ACK_REPORT = 50;
|
||||||
@ -1406,6 +1407,119 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SupvTcSpacePacket : public SpacePacket {
|
||||||
|
public:
|
||||||
|
SupvTcSpacePacket(size_t payloadDataLen, uint16_t apid) :
|
||||||
|
SpacePacket(payloadLen + 1, true, apid,
|
||||||
|
DEFAULT_SEQUENCE_COUNT), payloadDataLen(payloadDataLen) {
|
||||||
|
initPacket();
|
||||||
|
makeCrc();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void makeCrc() {
|
||||||
|
serializedSize = 0;
|
||||||
|
uint16_t crc = CRC::crc16ccitt(this->localData.byteStream,
|
||||||
|
sizeof(CCSDSPrimaryHeader) + payloadDataLen);
|
||||||
|
uint8_t* crcPos = this->localData.fields.buffer + payloadDataLen;
|
||||||
|
SerializeAdapter::serialize<uint16_t>(&crc, &crcPos, &serializedSize, sizeof(crc),
|
||||||
|
SerializeIF::Endianness::BIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The sequence count of most of the TC packets for the supervisor is 1.
|
||||||
|
static const uint16_t DEFAULT_SEQUENCE_COUNT = 1;
|
||||||
|
|
||||||
|
// The size of the payload data (data field without crc size)
|
||||||
|
size_t payloadDataLen = 0;
|
||||||
|
|
||||||
|
void virtual initPacket() {
|
||||||
|
// Perform stuff to fill packet data field
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class packages the update available space packet. This is the first packet sent
|
||||||
|
* to the supervisor in an update procedure.
|
||||||
|
*/
|
||||||
|
class UpdateInfo: public SupvTcSpacePacket {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* @param apid Packet can be used to generate the update available and the update verify
|
||||||
|
* packet. Thus the APID must be specified here.
|
||||||
|
* @param memory The memory to apply the update (NVM0 - 0, NVM1 - 1)
|
||||||
|
* @param partition The partition to update (A - 0, B - 1)
|
||||||
|
* @param imageSize The size of the update image
|
||||||
|
* param numPackets The number of space packets required to transfer all data.
|
||||||
|
*/
|
||||||
|
UpdateInfo(uint16_t apid, uint8_t memory, uint8_t partition, uint32_t imageSize,
|
||||||
|
uint32_t imageCrc, uint32_t numPackets) :
|
||||||
|
SupvTcSpacePacket(PAYLOAD_LENGTH, apid), memory(memory), partition(partition), imageSize(
|
||||||
|
imageSize), numPackets(numPackets) {
|
||||||
|
initPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static const uint16_t PAYLOAD_LENGTH = 14; // length without CRC field
|
||||||
|
|
||||||
|
uint8_t memory = 0;
|
||||||
|
uint8_t partition = 0;
|
||||||
|
uint32_t imageSize = 0;
|
||||||
|
uint32_t imageCrc = 0;
|
||||||
|
uint32_t numPackets = 0;
|
||||||
|
|
||||||
|
void initPacket() {
|
||||||
|
size_t serializedSize = 0;
|
||||||
|
uint8_t* data_field_ptr = this->localData.fields.buffer;
|
||||||
|
SerializeAdapter::serialize<uint8_t>(memory, &data_field_ptr, &serializedSize,
|
||||||
|
sizeof(memory), SerializeIF::Endianness::BIG);
|
||||||
|
serializedSize = 0;
|
||||||
|
SerializeAdapter::serialize<uint8_t>(&partition, &data_field_ptr, &serializedSize,
|
||||||
|
sizeof(partition), SerializeIF::Endianness::BIG);
|
||||||
|
serializedSize = 0;
|
||||||
|
SerializeAdapter::serialize<uint8_t>(&imageSize, &data_field_ptr, &serializedSize,
|
||||||
|
sizeof(imageSize), SerializeIF::Endianness::BIG);
|
||||||
|
serializedSize = 0;
|
||||||
|
SerializeAdapter::serialize<uint8_t>(&imageCrc, &data_field_ptr, &serializedSize,
|
||||||
|
sizeof(imageCrc), SerializeIF::Endianness::BIG);
|
||||||
|
serializedSize = 0;
|
||||||
|
SerializeAdapter::serialize<uint8_t>(&numPackets, &data_field_ptr, &serializedSize,
|
||||||
|
sizeof(numPackets), SerializeIF::Endianness::BIG);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class packages the space packet transporting a part of an MPSoC update.
|
||||||
|
*/
|
||||||
|
class UpdatePacket: public SupvTcSpacePacket {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* @param payloadLength Update data length (data field length without CRC)
|
||||||
|
*/
|
||||||
|
UpdatePacket(uint16_t payloadLength) :
|
||||||
|
SupvTcSpacePacket(payloadLength, APID_UPDATE_IMAGE_DATA) {
|
||||||
|
initPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the pointer to the beginning of the data field.
|
||||||
|
*/
|
||||||
|
uint8_t* getDataFieldPointer() {
|
||||||
|
return this->localData.fields.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateCrc() {
|
||||||
|
this->makeCrc();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This dataset stores the boot status report of the supervisor.
|
* @brief This dataset stores the boot status report of the supervisor.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user