Unlock STR second firmware slot

This commit is contained in:
Robin Müller 2024-02-19 17:16:08 +01:00
parent 77527c631c
commit dbb530e27b
Signed by: muellerr
GPG Key ID: A649FB78196E3849
7 changed files with 158 additions and 56 deletions

View File

@ -951,7 +951,7 @@ void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher, SdCardManage
auto cfgGetter = new StrConfigPathGetter(sdcMan); auto cfgGetter = new StrConfigPathGetter(sdcMan);
auto starTracker = auto starTracker =
new StarTrackerHandler(objects::STAR_TRACKER, objects::STR_COM_IF, starTrackerCookie, new StarTrackerHandler(objects::STAR_TRACKER, objects::STR_COM_IF, starTrackerCookie,
strComIF, power::PDU1_CH2_STAR_TRACKER_5V, *cfgGetter); strComIF, power::PDU1_CH2_STAR_TRACKER_5V, *cfgGetter, sdcMan);
starTracker->setPowerSwitcher(pwrSwitcher); starTracker->setPowerSwitcher(pwrSwitcher);
starTracker->connectModeTreeParent(*strAssy); starTracker->connectModeTreeParent(*strAssy);
starTracker->setCustomFdir(strFdir); starTracker->setCustomFdir(strFdir);

View File

@ -175,7 +175,8 @@ void StrComHandler::setDownloadImageName(std::string filename) {
void StrComHandler::setFlashReadFilename(std::string filename) { flashRead.filename = filename; } void StrComHandler::setFlashReadFilename(std::string filename) { flashRead.filename = filename; }
ReturnValue_t StrComHandler::startFirmwareUpdate(std::string fullname) { ReturnValue_t StrComHandler::startFirmwareUpdate(std::string fullname,
startracker::FirmwareTarget target) {
{ {
MutexGuard mg(lock); MutexGuard mg(lock);
if (state != InternalState::SLEEPING) { if (state != InternalState::SLEEPING) {
@ -192,8 +193,13 @@ ReturnValue_t StrComHandler::startFirmwareUpdate(std::string fullname) {
if (not std::filesystem::exists(flashWrite.fullname)) { if (not std::filesystem::exists(flashWrite.fullname)) {
return FILE_NOT_EXISTS; return FILE_NOT_EXISTS;
} }
flashWrite.firstRegion = static_cast<uint8_t>(startracker::FirmwareRegions::FIRST); if (target == startracker::FirmwareTarget::MAIN) {
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST); flashWrite.firstRegion = static_cast<uint8_t>(startracker::FirmwareRegions::FIRST_MAIN);
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST_MAIN);
} else if (target == startracker::FirmwareTarget::BACKUP) {
flashWrite.firstRegion = static_cast<uint8_t>(startracker::FirmwareRegions::FIRST_BACKUP);
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST_BACKUP);
}
{ {
MutexGuard mg(lock); MutexGuard mg(lock);
replyWasReceived = false; replyWasReceived = false;
@ -275,7 +281,7 @@ ReturnValue_t StrComHandler::performImageDownload() {
file.close(); file.close();
return result; return result;
} }
result = checkActionReply(replySize); result = checkActionReply(replySize, "downloading image");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
serial::flushRxBuf(serialPort); serial::flushRxBuf(serialPort);
@ -348,7 +354,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "sky image upload");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -374,7 +380,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "sky image upload");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -388,8 +394,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
ReturnValue_t StrComHandler::performFirmwareUpdate() { ReturnValue_t StrComHandler::performFirmwareUpdate() {
using namespace startracker; using namespace startracker;
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = unlockAndEraseRegions(static_cast<uint32_t>(startracker::FirmwareRegions::FIRST), result = unlockAndEraseRegions(flashWrite.firstRegion, flashWrite.lastRegion);
static_cast<uint32_t>(startracker::FirmwareRegions::LAST));
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -421,6 +426,8 @@ ReturnValue_t StrComHandler::performFlashWrite() {
file.seekg(0, file.end); file.seekg(0, file.end);
fileSize = file.tellg(); fileSize = file.tellg();
if (fileSize > FLASH_REGION_SIZE * (flashWrite.lastRegion - flashWrite.firstRegion)) { if (fileSize > FLASH_REGION_SIZE * (flashWrite.lastRegion - flashWrite.firstRegion)) {
sif::debug << "Last region: " << (int)flashWrite.lastRegion
<< " first region: " << (int)flashWrite.firstRegion << std::endl;
sif::warning << "StrHelper::performFlashWrite: Invalid file" << std::endl; sif::warning << "StrHelper::performFlashWrite: Invalid file" << std::endl;
return returnvalue::FAILED; return returnvalue::FAILED;
} }
@ -445,7 +452,7 @@ ReturnValue_t StrComHandler::performFlashWrite() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "firmware image upload");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -488,7 +495,7 @@ ReturnValue_t StrComHandler::performFlashWrite() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "flash write");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -542,7 +549,7 @@ ReturnValue_t StrComHandler::performFlashRead() {
file.close(); file.close();
return result; return result;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "flash read");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
serial::flushRxBuf(serialPort); serial::flushRxBuf(serialPort);
@ -584,7 +591,7 @@ ReturnValue_t StrComHandler::sendAndRead(size_t size, uint32_t failParameter) {
return readOneReply(failParameter); return readOneReply(failParameter);
} }
ReturnValue_t StrComHandler::checkActionReply(size_t replySize) { ReturnValue_t StrComHandler::checkActionReply(size_t replySize, const char* context) {
uint8_t type = startracker::getReplyFrameType(replyPtr); uint8_t type = startracker::getReplyFrameType(replyPtr);
if (type != TMTC_ACTIONREPLY) { if (type != TMTC_ACTIONREPLY) {
sif::warning << "StrHelper::checkActionReply: Received reply with invalid type ID" << std::endl; sif::warning << "StrHelper::checkActionReply: Received reply with invalid type ID" << std::endl;
@ -592,7 +599,7 @@ ReturnValue_t StrComHandler::checkActionReply(size_t replySize) {
} }
uint8_t status = startracker::getStatusField(replyPtr); uint8_t status = startracker::getStatusField(replyPtr);
if (status != ArcsecDatalinkLayer::STATUS_OK) { if (status != ArcsecDatalinkLayer::STATUS_OK) {
sif::warning << "StrHelper::checkActionReply: Status failure: " sif::warning << "StrHelper::checkActionReply: Status failure for " << context << ": "
<< static_cast<unsigned int>(status) << std::endl; << static_cast<unsigned int>(status) << std::endl;
return STATUS_ERROR; return STATUS_ERROR;
} }
@ -744,15 +751,15 @@ ReturnValue_t StrComHandler::unlockAndEraseRegions(uint32_t from, uint32_t to) {
struct UnlockActionRequest unlockReq; struct UnlockActionRequest unlockReq;
struct EraseActionRequest eraseReq; struct EraseActionRequest eraseReq;
uint32_t size = 0; uint32_t size = 0;
for (uint32_t idx = from; idx <= to; idx++) { for (uint32_t idx = from; idx < to; idx++) {
unlockReq.region = idx; unlockReq.region = idx;
unlockReq.code = startracker::region_secrets::secret[idx]; unlockReq.code = startracker::region_secrets::SECRETS[idx];
arc_pack_unlock_action_req(&unlockReq, cmdBuf.data(), &size); arc_pack_unlock_action_req(&unlockReq, cmdBuf.data(), &size);
result = sendAndRead(size, unlockReq.region); result = sendAndRead(size, unlockReq.region);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "unlocking region");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "StrHelper::unlockAndEraseRegions: Failed to unlock region with id " sif::warning << "StrHelper::unlockAndEraseRegions: Failed to unlock region with id "
<< static_cast<unsigned int>(unlockReq.region) << std::endl; << static_cast<unsigned int>(unlockReq.region) << std::endl;
@ -761,6 +768,9 @@ ReturnValue_t StrComHandler::unlockAndEraseRegions(uint32_t from, uint32_t to) {
eraseReq.region = idx; eraseReq.region = idx;
arc_pack_erase_action_req(&eraseReq, cmdBuf.data(), &size); arc_pack_erase_action_req(&eraseReq, cmdBuf.data(), &size);
result = sendAndRead(size, eraseReq.region); result = sendAndRead(size, eraseReq.region);
if (result != returnvalue::OK) {
}
result = checkActionReply(replyLen, "erasing region");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "StrHelper::unlockAndEraseRegions: Failed to erase region with id " sif::warning << "StrHelper::unlockAndEraseRegions: Failed to erase region with id "
<< static_cast<unsigned int>(eraseReq.region) << std::endl; << static_cast<unsigned int>(eraseReq.region) << std::endl;

View File

@ -6,6 +6,7 @@
#include <string> #include <string>
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "mission/acs/str/strHelpers.h"
#ifdef XIPHOS_Q7S #ifdef XIPHOS_Q7S
#include "bsp_q7s/fs/SdCardManager.h" #include "bsp_q7s/fs/SdCardManager.h"
@ -127,7 +128,7 @@ class StrComHandler : public SystemObject, public DeviceCommunicationIF, public
* @param fullname Full name including absolute path of file containing firmware * @param fullname Full name including absolute path of file containing firmware
* update. * update.
*/ */
ReturnValue_t startFirmwareUpdate(std::string fullname); ReturnValue_t startFirmwareUpdate(std::string fullname, startracker::FirmwareTarget target);
/** /**
* @brief Starts the flash read procedure * @brief Starts the flash read procedure
@ -334,7 +335,7 @@ class StrComHandler : public SystemObject, public DeviceCommunicationIF, public
* *
* @return returnvalue::OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED * @return returnvalue::OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED
*/ */
ReturnValue_t checkActionReply(size_t replySize); ReturnValue_t checkActionReply(size_t replySize, const char *context);
/** /**
* @brief Checks the position field in a star tracker upload/download reply. * @brief Checks the position field in a star tracker upload/download reply.

View File

@ -5,7 +5,11 @@
#include <mission/acs/str/strHelpers.h> #include <mission/acs/str/strHelpers.h>
#include <mission/acs/str/strJsonCommands.h> #include <mission/acs/str/strJsonCommands.h>
#include <string>
#include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "mission/memory/SdCardMountedIF.h"
extern "C" { extern "C" {
#include <sagitta/client/actionreq.h> #include <sagitta/client/actionreq.h>
@ -16,7 +20,6 @@ extern "C" {
} }
#include <atomic> #include <atomic>
#include <fstream>
#include <thread> #include <thread>
#include "OBSWConfig.h" #include "OBSWConfig.h"
@ -27,7 +30,8 @@ std::atomic_bool JCFG_DONE(false);
StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
StrComHandler* strHelper, power::Switch_t powerSwitch, StrComHandler* strHelper, power::Switch_t powerSwitch,
startracker::SdCardConfigPathGetter& cfgPathGetter) startracker::SdCardConfigPathGetter& cfgPathGetter,
SdCardMountedIF& sdCardIF)
: DeviceHandlerBase(objectId, comIF, comCookie), : DeviceHandlerBase(objectId, comIF, comCookie),
temperatureSet(this), temperatureSet(this),
versionSet(this), versionSet(this),
@ -60,6 +64,7 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
contrastSet(this), contrastSet(this),
strHelper(strHelper), strHelper(strHelper),
powerSwitch(powerSwitch), powerSwitch(powerSwitch),
sdCardIF(sdCardIF),
cfgPathGetter(cfgPathGetter) { cfgPathGetter(cfgPathGetter) {
if (comCookie == nullptr) { if (comCookie == nullptr) {
sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl;
@ -138,6 +143,9 @@ ReturnValue_t StarTrackerHandler::initialize() {
// delay whole satellite boot process. // delay whole satellite boot process.
reloadJsonCfgFile(); reloadJsonCfgFile();
// Default firmware target is always initialized from persistent file.
loadTargetFirmwareFromPersistentCfg();
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER); EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) { if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
@ -165,6 +173,19 @@ ReturnValue_t StarTrackerHandler::initialize() {
return returnvalue::OK; return returnvalue::OK;
} }
void StarTrackerHandler::loadTargetFirmwareFromPersistentCfg() {
const char* prefix = sdCardIF.getCurrentMountPrefix();
std::filesystem::path path = std::filesystem::path(prefix) / startracker::FW_TARGET_CFG_PATH;
std::ifstream ifile(path);
if (ifile.is_open()) {
std::string targetStr;
std::getline(ifile, targetStr);
if (targetStr == "backup\n") {
firmwareTargetRaw = static_cast<uint8_t>(startracker::FirmwareTarget::BACKUP);
}
}
}
bool StarTrackerHandler::reloadJsonCfgFile() { bool StarTrackerHandler::reloadJsonCfgFile() {
jcfgCountdown.resetTimer(); jcfgCountdown.resetTimer();
auto strCfgPath = cfgPathGetter.getCfgPath(); auto strCfgPath = cfgPathGetter.getCfgPath();
@ -307,21 +328,11 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
strHelper->setFlashReadFilename(std::string(reinterpret_cast<const char*>(data), size)); strHelper->setFlashReadFilename(std::string(reinterpret_cast<const char*>(data), size));
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
case (startracker::FIRMWARE_UPDATE): { case (startracker::FIRMWARE_UPDATE_MAIN): {
result = DeviceHandlerBase::acceptExternalDeviceCommands(); return handleFirmwareUpdateCommand(data, size, startracker::FirmwareTarget::MAIN);
if (result != returnvalue::OK) {
return result;
} }
if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) { case (startracker::FIRMWARE_UPDATE_BACKUP): {
return FILE_PATH_TOO_LONG; return handleFirmwareUpdateCommand(data, size, startracker::FirmwareTarget::BACKUP);
}
result =
strHelper->startFirmwareUpdate(std::string(reinterpret_cast<const char*>(data), size));
if (result != returnvalue::OK) {
return result;
}
strHelperHandlingSpecialRequest = true;
return EXECUTION_FINISHED;
} }
default: default:
break; break;
@ -330,6 +341,23 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
reinitNextSetParam = true; reinitNextSetParam = true;
return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size);
} }
ReturnValue_t StarTrackerHandler::handleFirmwareUpdateCommand(const uint8_t* data, size_t size,
startracker::FirmwareTarget target) {
ReturnValue_t result = DeviceHandlerBase::acceptExternalDeviceCommands();
if (result != returnvalue::OK) {
return result;
}
if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) {
return FILE_PATH_TOO_LONG;
}
result = strHelper->startFirmwareUpdate(std::string(reinterpret_cast<const char*>(data), size),
target);
if (result != returnvalue::OK) {
return result;
}
strHelperHandlingSpecialRequest = true;
return EXECUTION_FINISHED;
}
void StarTrackerHandler::performOperationHook() { void StarTrackerHandler::performOperationHook() {
EventMessage event; EventMessage event;
@ -569,7 +597,7 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
return returnvalue::OK; return returnvalue::OK;
} }
case (startracker::BOOT): { case (startracker::BOOT): {
prepareBootCommand(); prepareBootCommand(static_cast<startracker::FirmwareTarget>(firmwareTargetRaw));
return returnvalue::OK; return returnvalue::OK;
} }
case (startracker::REQ_VERSION): { case (startracker::REQ_VERSION): {
@ -1659,7 +1687,8 @@ ReturnValue_t StarTrackerHandler::checkMode(ActionId_t actionId) {
case startracker::UPLOAD_IMAGE: case startracker::UPLOAD_IMAGE:
case startracker::DOWNLOAD_IMAGE: case startracker::DOWNLOAD_IMAGE:
case startracker::FLASH_READ: case startracker::FLASH_READ:
case startracker::FIRMWARE_UPDATE: { case startracker::FIRMWARE_UPDATE_BACKUP:
case startracker::FIRMWARE_UPDATE_MAIN: {
return DeviceHandlerBase::acceptExternalDeviceCommands(); return DeviceHandlerBase::acceptExternalDeviceCommands();
default: default:
break; break;
@ -1956,9 +1985,9 @@ ReturnValue_t StarTrackerHandler::executeFlashReadCommand(const uint8_t* command
return result; return result;
} }
void StarTrackerHandler::prepareBootCommand() { void StarTrackerHandler::prepareBootCommand(startracker::FirmwareTarget target) {
uint32_t length = 0; uint32_t length = 0;
struct BootActionRequest bootRequest = {BOOT_REGION_ID}; struct BootActionRequest bootRequest = {static_cast<uint8_t>(target)};
arc_pack_boot_action_req(&bootRequest, commandBuffer, &length); arc_pack_boot_action_req(&bootRequest, commandBuffer, &length);
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = length; rawPacketLen = length;
@ -2389,7 +2418,8 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
internalState = InternalState::DONE; internalState = InternalState::DONE;
} }
break; break;
case startracker::Program::FIRMWARE: case startracker::Program::FIRMWARE_BACKUP:
case startracker::Program::FIRMWARE_MAIN: {
if (startupState == StartupState::WAIT_CHECK_PROGRAM) { if (startupState == StartupState::WAIT_CHECK_PROGRAM) {
startupState = StartupState::BOOT_BOOTLOADER; startupState = StartupState::BOOT_BOOTLOADER;
} }
@ -2400,9 +2430,10 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
internalState = InternalState::FAILED_BOOTLOADER_BOOT; internalState = InternalState::FAILED_BOOTLOADER_BOOT;
} }
break; break;
}
default: default:
sif::warning << "StarTrackerHandler::checkProgram: Version set has invalid program ID" sif::warning << "StarTrackerHandler::checkProgram: Version set has invalid program ID "
<< std::endl; << (int)versionSet.program.value << std::endl;
return INVALID_PROGRAM; return INVALID_PROGRAM;
} }
return returnvalue::OK; return returnvalue::OK;
@ -2865,12 +2896,13 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) {
case startracker::REQ_CENTROID: case startracker::REQ_CENTROID:
case startracker::REQ_CENTROIDS: case startracker::REQ_CENTROIDS:
case startracker::REQ_CONTRAST: { case startracker::REQ_CONTRAST: {
if (getMode() == MODE_ON and getSubmode() != startracker::Program::FIRMWARE) { if (getMode() == MODE_ON and getSubmode() != startracker::Program::FIRMWARE_MAIN) {
return STARTRACKER_NOT_RUNNING_FIRMWARE; return STARTRACKER_NOT_RUNNING_FIRMWARE;
} }
break; break;
} }
case startracker::FIRMWARE_UPDATE: case startracker::FIRMWARE_UPDATE_MAIN:
case startracker::FIRMWARE_UPDATE_BACKUP:
case startracker::FLASH_READ: case startracker::FLASH_READ:
if (getMode() != MODE_ON or getSubmode() != startracker::Program::BOOTLOADER) { if (getMode() != MODE_ON or getSubmode() != startracker::Program::BOOTLOADER) {
return STARTRACKER_NOT_RUNNING_BOOTLOADER; return STARTRACKER_NOT_RUNNING_BOOTLOADER;
@ -2883,3 +2915,43 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) {
} }
ReturnValue_t StarTrackerHandler::acceptExternalDeviceCommands() { return returnvalue::OK; } ReturnValue_t StarTrackerHandler::acceptExternalDeviceCommands() { return returnvalue::OK; }
ReturnValue_t StarTrackerHandler::getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues,
uint16_t startAtIndex) {
auto firmwareTargetUpdate = [&](bool persistent) {
uint8_t value = 0;
newValues->getElement(&value);
if (value != static_cast<uint8_t>(startracker::FirmwareTarget::MAIN) &&
value != static_cast<uint8_t>(startracker::FirmwareTarget::BACKUP)) {
return HasParametersIF::INVALID_VALUE;
}
parameterWrapper->set(firmwareTargetRaw);
if (persistent) {
if (sdCardIF.isSdCardUsable(std::nullopt)) {
const char* prefix = sdCardIF.getCurrentMountPrefix();
std::filesystem::path path =
std::filesystem::path(prefix) / startracker::FW_TARGET_CFG_PATH;
std::ofstream of(path, std::ofstream::out | std::ofstream::trunc);
if (value == static_cast<uint8_t>(startracker::FirmwareTarget::MAIN)) {
of << "main\n";
} else {
of << "backup\n";
}
} else {
sif::warning << "SD card not usable" << std::endl;
return returnvalue::FAILED;
}
};
return returnvalue::OK;
};
if (uniqueId == startracker::ParamId::FIRMWARE_TARGET) {
return firmwareTargetUpdate(false);
}
if (uniqueId == startracker::ParamId::FIRMWARE_TARGET_PERSISTENT) {
return firmwareTargetUpdate(true);
}
return DeviceHandlerBase::getParameter(domainId, uniqueId, parameterWrapper, newValues,
startAtIndex);
}

View File

@ -11,10 +11,7 @@
#include <set> #include <set>
#include <thread> #include <thread>
#include "OBSWConfig.h"
#include "devices/powerSwitcherList.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "fsfw/src/fsfw/serialize/SerializeAdapter.h"
#include "fsfw/timemanager/Countdown.h" #include "fsfw/timemanager/Countdown.h"
extern "C" { extern "C" {
@ -45,7 +42,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
*/ */
StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
StrComHandler* strHelper, power::Switch_t powerSwitch, StrComHandler* strHelper, power::Switch_t powerSwitch,
startracker::SdCardConfigPathGetter& cfgPathGetter); startracker::SdCardConfigPathGetter& cfgPathGetter, SdCardMountedIF& sdCardIF);
virtual ~StarTrackerHandler(); virtual ~StarTrackerHandler();
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
@ -61,6 +58,9 @@ class StarTrackerHandler : public DeviceHandlerBase {
Submode_t getInitialSubmode() override; Submode_t getInitialSubmode() override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
protected: protected:
void doStartUp() override; void doStartUp() override;
void doShutDown() override; void doShutDown() override;
@ -161,7 +161,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
// Ping request will reply ping with this ID (data field) // Ping request will reply ping with this ID (data field)
static const uint32_t PING_ID = 0x55; static const uint32_t PING_ID = 0x55;
static const uint32_t BOOT_REGION_ID = 1; uint8_t firmwareTargetRaw = static_cast<uint8_t>(startracker::FirmwareTarget::MAIN);
static const MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING; static const MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING;
static const uint32_t MUTEX_TIMEOUT = 20; static const uint32_t MUTEX_TIMEOUT = 20;
static const uint32_t BOOT_TIMEOUT = 1000; static const uint32_t BOOT_TIMEOUT = 1000;
@ -314,12 +315,14 @@ class StarTrackerHandler : public DeviceHandlerBase {
std::set<DeviceCommandId_t> additionalRequestedTm{}; std::set<DeviceCommandId_t> additionalRequestedTm{};
std::set<DeviceCommandId_t>::iterator currentSecondaryTmIter; std::set<DeviceCommandId_t>::iterator currentSecondaryTmIter;
SdCardMountedIF& sdCardIF;
startracker::SdCardConfigPathGetter& cfgPathGetter; startracker::SdCardConfigPathGetter& cfgPathGetter;
/** /**
* @brief Handles internal state * @brief Handles internal state
*/ */
void handleInternalState(); void handleInternalState();
void loadTargetFirmwareFromPersistentCfg();
/** /**
* @brief Checks mode for commands requiring MODE_ON of MODE_NORMAL for execution. * @brief Checks mode for commands requiring MODE_ON of MODE_NORMAL for execution.
@ -380,7 +383,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
* @brief Fills command buffer with data to boot image (works only when star tracker is * @brief Fills command buffer with data to boot image (works only when star tracker is
* in bootloader mode). * in bootloader mode).
*/ */
void prepareBootCommand(); void prepareBootCommand(startracker::FirmwareTarget target);
/** /**
* @brief Fills command buffer with command to get the checksum of a flash part * @brief Fills command buffer with command to get the checksum of a flash part
@ -550,6 +553,9 @@ class StarTrackerHandler : public DeviceHandlerBase {
void bootBootloader(); void bootBootloader();
bool reloadJsonCfgFile(); bool reloadJsonCfgFile();
ReturnValue_t acceptExternalDeviceCommands() override; ReturnValue_t acceptExternalDeviceCommands() override;
ReturnValue_t handleFirmwareUpdateCommand(const uint8_t* data, size_t size,
startracker::FirmwareTarget target);
}; };
#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ #endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */

View File

@ -14,6 +14,12 @@ namespace startracker {
static const Submode_t SUBMODE_BOOTLOADER = 1; static const Submode_t SUBMODE_BOOTLOADER = 1;
static const Submode_t SUBMODE_FIRMWARE = 2; static const Submode_t SUBMODE_FIRMWARE = 2;
enum class FirmwareTarget : uint8_t { MAIN = 1, BACKUP = 10 };
static constexpr char FW_TARGET_CFG_PATH[] = "startracker/fw-target.txt";
enum ParamId : uint32_t { FIRMWARE_TARGET = 1, FIRMWARE_TARGET_PERSISTENT = 2 };
class SdCardConfigPathGetter { class SdCardConfigPathGetter {
public: public:
virtual ~SdCardConfigPathGetter() = default; virtual ~SdCardConfigPathGetter() = default;
@ -373,7 +379,7 @@ static const DeviceCommandId_t REQ_DEBUG_CAMERA = 80;
static const DeviceCommandId_t LOGLEVEL = 81; static const DeviceCommandId_t LOGLEVEL = 81;
static const DeviceCommandId_t LOGSUBSCRIPTION = 82; static const DeviceCommandId_t LOGSUBSCRIPTION = 82;
static const DeviceCommandId_t DEBUG_CAMERA = 83; static const DeviceCommandId_t DEBUG_CAMERA = 83;
static const DeviceCommandId_t FIRMWARE_UPDATE = 84; static const DeviceCommandId_t FIRMWARE_UPDATE_MAIN = 84;
static const DeviceCommandId_t DISABLE_TIMESTAMP_GENERATION = 85; static const DeviceCommandId_t DISABLE_TIMESTAMP_GENERATION = 85;
static const DeviceCommandId_t ENABLE_TIMESTAMP_GENERATION = 86; static const DeviceCommandId_t ENABLE_TIMESTAMP_GENERATION = 86;
static constexpr DeviceCommandId_t SET_TIME_FROM_SYS_TIME = 87; static constexpr DeviceCommandId_t SET_TIME_FROM_SYS_TIME = 87;
@ -388,6 +394,7 @@ static constexpr DeviceCommandId_t ADD_SECONDARY_TM_TO_NORMAL_MODE = 95;
static constexpr DeviceCommandId_t RESET_SECONDARY_TM_SET = 96; static constexpr DeviceCommandId_t RESET_SECONDARY_TM_SET = 96;
static constexpr DeviceCommandId_t READ_SECONDARY_TM_SET = 97; static constexpr DeviceCommandId_t READ_SECONDARY_TM_SET = 97;
static constexpr DeviceCommandId_t RELOAD_JSON_CFG_FILE = 100; static constexpr DeviceCommandId_t RELOAD_JSON_CFG_FILE = 100;
static const DeviceCommandId_t FIRMWARE_UPDATE_BACKUP = 101;
static const DeviceCommandId_t NONE = 0xFFFFFFFF; static const DeviceCommandId_t NONE = 0xFFFFFFFF;
static const uint32_t VERSION_SET_ID = REQ_VERSION; static const uint32_t VERSION_SET_ID = REQ_VERSION;
@ -489,7 +496,8 @@ static constexpr uint8_t MATCHED_CENTROIDS = 40;
namespace Program { namespace Program {
static const uint8_t BOOTLOADER = 1; static const uint8_t BOOTLOADER = 1;
static const uint8_t FIRMWARE = 2; static const uint8_t FIRMWARE_MAIN = 2;
static const uint8_t FIRMWARE_BACKUP = 3;
} // namespace Program } // namespace Program
namespace region_secrets { namespace region_secrets {
@ -509,7 +517,7 @@ static const uint32_t REGION_12_SECRET = 0x42fedef6;
static const uint32_t REGION_13_SECRET = 0xe53cf10d; static const uint32_t REGION_13_SECRET = 0xe53cf10d;
static const uint32_t REGION_14_SECRET = 0xe862b70b; static const uint32_t REGION_14_SECRET = 0xe862b70b;
static const uint32_t REGION_15_SECRET = 0x79b537ca; static const uint32_t REGION_15_SECRET = 0x79b537ca;
static const uint32_t secret[16]{ static const uint32_t SECRETS[16]{
REGION_0_SECRET, REGION_1_SECRET, REGION_2_SECRET, REGION_3_SECRET, REGION_0_SECRET, REGION_1_SECRET, REGION_2_SECRET, REGION_3_SECRET,
REGION_4_SECRET, REGION_5_SECRET, REGION_6_SECRET, REGION_7_SECRET, REGION_4_SECRET, REGION_5_SECRET, REGION_6_SECRET, REGION_7_SECRET,
REGION_8_SECRET, REGION_9_SECRET, REGION_10_SECRET, REGION_11_SECRET, REGION_8_SECRET, REGION_9_SECRET, REGION_10_SECRET, REGION_11_SECRET,
@ -538,7 +546,12 @@ enum class FlashSections : uint8_t {
}; };
// Flash region IDs of firmware partition // Flash region IDs of firmware partition
enum class FirmwareRegions : uint32_t { FIRST = 1, LAST = 8 }; enum class FirmwareRegions : uint32_t {
FIRST_MAIN = 1,
LAST_MAIN = 8,
FIRST_BACKUP = 10,
LAST_BACKUP = 16
};
static const uint32_t FLASH_REGION_SIZE = 0x20000; static const uint32_t FLASH_REGION_SIZE = 0x20000;

2
tmtc

@ -1 +1 @@
Subproject commit a5ebac626682e86b45f991c919a3ce9a9b7fcfcc Subproject commit 85fc106a9b0e6d4256e6243200b9c0a3b910f67c