PTME_LOCK atomic boolean and related handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
This commit is contained in:
parent
caa7c20adf
commit
55a22c840c
@ -23,6 +23,9 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
used to disable ongoing dumps or to prevent writes to the PTME VC. This allows cleaner reset
|
used to disable ongoing dumps or to prevent writes to the PTME VC. This allows cleaner reset
|
||||||
handling of the PTME. All 4 VC/store tasks were attached to the COM mode tree and are commanded
|
handling of the PTME. All 4 VC/store tasks were attached to the COM mode tree and are commanded
|
||||||
as part of the COM sequence as well to ensure consistent state with the CCSDS IP core handler.
|
as part of the COM sequence as well to ensure consistent state with the CCSDS IP core handler.
|
||||||
|
- Added `PTME_LOCKED` boolean lock which is used to lock the PTME so it is not used by the VC tasks
|
||||||
|
anymore. This lock will be controlled by the CCSDS IP core handler and is locked when the PTME
|
||||||
|
needs to be reset. Examples for this are datarate changes.
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
@ -125,6 +125,7 @@ using gpio::Levels;
|
|||||||
|
|
||||||
ResetArgs RESET_ARGS_GNSS;
|
ResetArgs RESET_ARGS_GNSS;
|
||||||
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
|
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
|
||||||
|
std::atomic_bool PTME_LOCKED = false;
|
||||||
std::atomic_uint16_t I2C_FATAL_ERRORS = 0;
|
std::atomic_uint16_t I2C_FATAL_ERRORS = 0;
|
||||||
|
|
||||||
void Factory::setStaticFrameworkObjectIds() {
|
void Factory::setStaticFrameworkObjectIds() {
|
||||||
@ -789,14 +790,14 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
|||||||
|
|
||||||
*args.ipCoreHandler =
|
*args.ipCoreHandler =
|
||||||
new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, *ptmeConfig,
|
new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, *ptmeConfig,
|
||||||
LINK_STATE, &args.gpioComIF, gpios);
|
LINK_STATE, &args.gpioComIF, gpios, PTME_LOCKED);
|
||||||
// This VC will receive all live TM
|
// This VC will receive all live TM
|
||||||
auto* vcWithQueue =
|
auto* vcWithQueue =
|
||||||
new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme,
|
new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme,
|
||||||
LINK_STATE, args.tmStore, 500);
|
LINK_STATE, args.tmStore, 500);
|
||||||
args.liveDestination = vcWithQueue;
|
args.liveDestination = vcWithQueue;
|
||||||
auto* liveTask =
|
auto* liveTask = new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel,
|
||||||
new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel, *vcWithQueue);
|
*vcWithQueue, PTME_LOCKED);
|
||||||
liveTask->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
liveTask->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
||||||
|
|
||||||
// Set up log store.
|
// Set up log store.
|
||||||
@ -804,15 +805,17 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
|||||||
LINK_STATE);
|
LINK_STATE);
|
||||||
LogStores logStores(args.stores);
|
LogStores logStores(args.stores);
|
||||||
// Core task which handles the LOG store and takes care of dumping it as TM using a VC directly
|
// Core task which handles the LOG store and takes care of dumping it as TM using a VC directly
|
||||||
auto* logStore = new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore,
|
auto* logStore =
|
||||||
logStores, *vc, *SdCardManager::instance());
|
new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, logStores, *vc,
|
||||||
|
*SdCardManager::instance(), PTME_LOCKED);
|
||||||
logStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
logStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
||||||
|
|
||||||
vc = new VirtualChannel(objects::PTME_VC2_HK_TM, ccsds::VC2, "PTME VC2 HK TM", *ptme, LINK_STATE);
|
vc = new VirtualChannel(objects::PTME_VC2_HK_TM, ccsds::VC2, "PTME VC2 HK TM", *ptme, LINK_STATE);
|
||||||
// Core task which handles the HK store and takes care of dumping it as TM using a VC directly
|
// Core task which handles the HK store and takes care of dumping it as TM using a VC directly
|
||||||
auto* hkStore = new PersistentSingleTmStoreTask(
|
auto* hkStore = new PersistentSingleTmStoreTask(
|
||||||
objects::HK_STORE_AND_TM_TASK, args.ipcStore, *args.stores.hkStore, *vc,
|
objects::HK_STORE_AND_TM_TASK, args.ipcStore, *args.stores.hkStore, *vc,
|
||||||
persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance());
|
persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance(),
|
||||||
|
PTME_LOCKED);
|
||||||
hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
||||||
|
|
||||||
vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme,
|
vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme,
|
||||||
@ -821,7 +824,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
|||||||
auto* cfdpTask = new PersistentSingleTmStoreTask(
|
auto* cfdpTask = new PersistentSingleTmStoreTask(
|
||||||
objects::CFDP_STORE_AND_TM_TASK, args.ipcStore, *args.stores.cfdpStore, *vc,
|
objects::CFDP_STORE_AND_TM_TASK, args.ipcStore, *args.stores.cfdpStore, *vc,
|
||||||
persTmStore::DUMP_CFDP_STORE_DONE, persTmStore::DUMP_CFDP_CANCELLED,
|
persTmStore::DUMP_CFDP_STORE_DONE, persTmStore::DUMP_CFDP_CANCELLED,
|
||||||
*SdCardManager::instance());
|
*SdCardManager::instance(), PTME_LOCKED);
|
||||||
cfdpTask->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
cfdpTask->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
||||||
|
|
||||||
ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
||||||
|
@ -24,6 +24,7 @@ class AcsBoardAssembly;
|
|||||||
class GpioIF;
|
class GpioIF;
|
||||||
|
|
||||||
extern std::atomic_uint16_t I2C_FATAL_ERRORS;
|
extern std::atomic_uint16_t I2C_FATAL_ERRORS;
|
||||||
|
extern std::atomic_bool PTME_LOCKED;
|
||||||
|
|
||||||
namespace ObjectFactory {
|
namespace ObjectFactory {
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries,
|
|||||||
if (not busy) {
|
if (not busy) {
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
if(checkReadyState and not ready) {
|
if (checkReadyState and not ready) {
|
||||||
return PAPB_BUSY;
|
return PAPB_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
|
|
||||||
CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination,
|
CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination,
|
||||||
PtmeConfig& ptmeConfig, std::atomic_bool& linkState,
|
PtmeConfig& ptmeConfig, std::atomic_bool& linkState,
|
||||||
GpioIF* gpioIF, PtmeGpios gpioIds)
|
GpioIF* gpioIF, PtmeGpios gpioIds,
|
||||||
|
std::atomic_bool& ptmeLocked)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
linkState(linkState),
|
linkState(linkState),
|
||||||
|
ptmeLocked(ptmeLocked),
|
||||||
tcDestination(tcDestination),
|
tcDestination(tcDestination),
|
||||||
parameterHelper(this),
|
parameterHelper(this),
|
||||||
actionHelper(this, nullptr),
|
actionHelper(this, nullptr),
|
||||||
@ -35,6 +37,7 @@ CcsdsIpCoreHandler::~CcsdsIpCoreHandler() = default;
|
|||||||
|
|
||||||
ReturnValue_t CcsdsIpCoreHandler::performOperation(uint8_t operationCode) {
|
ReturnValue_t CcsdsIpCoreHandler::performOperation(uint8_t operationCode) {
|
||||||
readCommandQueue();
|
readCommandQueue();
|
||||||
|
performPtmeUpdateWhenApplicable();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,10 +130,15 @@ ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueI
|
|||||||
return HasParametersIF::INVALID_VALUE;
|
return HasParametersIF::INVALID_VALUE;
|
||||||
}
|
}
|
||||||
parameterWrapper->set(batPriorityParam);
|
parameterWrapper->set(batPriorityParam);
|
||||||
if (mode == MODE_ON) {
|
if (newVal != batPriorityParam) {
|
||||||
updateBatPriorityOnTxOff = true;
|
// This ensures that the BAT priority is updated at some point when an update of the PTME is
|
||||||
} else if (mode == MODE_OFF) {
|
// allowed
|
||||||
updateBatPriorityFromParam();
|
updateContext.updateBatPrio = true;
|
||||||
|
// If we are off, we can do the update after X cycles. Otherwise, wait until the transmitter
|
||||||
|
// goes off.
|
||||||
|
if (mode == MODE_OFF) {
|
||||||
|
initPtmeUpdateAfterXCycles();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
@ -148,36 +156,12 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
|
|||||||
const uint8_t* data, size_t size) {
|
const uint8_t* data, size_t size) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
switch (actionId) {
|
switch (actionId) {
|
||||||
case SET_LOW_RATE: {
|
|
||||||
submode = static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW);
|
|
||||||
result = ptmeConfig.setRate(RATE_100KBPS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SET_HIGH_RATE: {
|
|
||||||
submode = static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH);
|
|
||||||
result = ptmeConfig.setRate(RATE_500KBPS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ARBITRARY_RATE: {
|
case ARBITRARY_RATE: {
|
||||||
uint32_t bitrate = 0;
|
uint32_t bitrate = 0;
|
||||||
SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG);
|
SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG);
|
||||||
result = ptmeConfig.setRate(bitrate);
|
result = ptmeConfig.setRate(bitrate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EN_TRANSMITTER: {
|
|
||||||
enableTransmit();
|
|
||||||
if (mode == HasModesIF::MODE_OFF) {
|
|
||||||
mode = HasModesIF::MODE_ON;
|
|
||||||
}
|
|
||||||
return EXECUTION_FINISHED;
|
|
||||||
}
|
|
||||||
case DISABLE_TRANSMITTER: {
|
|
||||||
disableTransmit();
|
|
||||||
if (mode == HasModesIF::MODE_ON) {
|
|
||||||
mode = HasModesIF::MODE_OFF;
|
|
||||||
}
|
|
||||||
return EXECUTION_FINISHED;
|
|
||||||
}
|
|
||||||
case ENABLE_TX_CLK_MANIPULATOR: {
|
case ENABLE_TX_CLK_MANIPULATOR: {
|
||||||
result = ptmeConfig.configTxManipulator(true);
|
result = ptmeConfig.configTxManipulator(true);
|
||||||
break;
|
break;
|
||||||
@ -206,12 +190,8 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
|
|||||||
void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; }
|
void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; }
|
||||||
|
|
||||||
void CcsdsIpCoreHandler::enableTransmit() {
|
void CcsdsIpCoreHandler::enableTransmit() {
|
||||||
// Reset PTME on each transmit enable.
|
|
||||||
updateBatPriorityFromParam();
|
|
||||||
#ifndef TE0720_1CFA
|
|
||||||
gpioIF->pullHigh(ptmeGpios.enableTxClock);
|
gpioIF->pullHigh(ptmeGpios.enableTxClock);
|
||||||
gpioIF->pullHigh(ptmeGpios.enableTxData);
|
gpioIF->pullHigh(ptmeGpios.enableTxData);
|
||||||
#endif
|
|
||||||
linkState = LINK_UP;
|
linkState = LINK_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,34 +216,23 @@ ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submod
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
|
void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
|
||||||
auto rateSet = [&](uint32_t rate) {
|
triggerEvent(CHANGING_MODE, mode, submode);
|
||||||
ReturnValue_t result = ptmeConfig.setRate(rate);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
this->mode = HasModesIF::MODE_ON;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (mode == HasModesIF::MODE_ON) {
|
if (mode == HasModesIF::MODE_ON) {
|
||||||
|
if (this->submode != submode) {
|
||||||
|
initPtmeUpdateAfterXCycles();
|
||||||
|
updateContext.enableTransmitAfterPtmeUpdate = true;
|
||||||
|
updateContext.updateClockRate = true;
|
||||||
|
this->submode = submode;
|
||||||
|
this->mode = mode;
|
||||||
|
updateContext.setModeAfterUpdate = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// No rate change, so enable transmitter right away.
|
||||||
enableTransmit();
|
enableTransmit();
|
||||||
if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_DEFAULT)) {
|
|
||||||
com::Datarate currentDatarate = com::getCurrentDatarate();
|
|
||||||
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
|
|
||||||
rateSet(RATE_100KBPS);
|
|
||||||
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
|
|
||||||
rateSet(RATE_500KBPS);
|
|
||||||
}
|
|
||||||
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH)) {
|
|
||||||
rateSet(RATE_500KBPS);
|
|
||||||
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW)) {
|
|
||||||
rateSet(RATE_100KBPS);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (mode == HasModesIF::MODE_OFF) {
|
} else if (mode == HasModesIF::MODE_OFF) {
|
||||||
disableTransmit();
|
disableTransmit();
|
||||||
this->mode = HasModesIF::MODE_OFF;
|
|
||||||
}
|
}
|
||||||
this->submode = submode;
|
setMode(mode, submode);
|
||||||
modeHelper.modeChanged(mode, submode);
|
|
||||||
announceMode(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
|
void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
|
||||||
@ -274,9 +243,9 @@ void CcsdsIpCoreHandler::disableTransmit() {
|
|||||||
gpioIF->pullLow(ptmeGpios.enableTxData);
|
gpioIF->pullLow(ptmeGpios.enableTxData);
|
||||||
#endif
|
#endif
|
||||||
linkState = LINK_DOWN;
|
linkState = LINK_DOWN;
|
||||||
if (updateBatPriorityOnTxOff) {
|
// Some parameters need update and transmitter is off now.
|
||||||
updateBatPriorityFromParam();
|
if (updateContext.updateBatPrio or updateContext.updateClockRate) {
|
||||||
updateBatPriorityOnTxOff = false;
|
initPtmeUpdateAfterXCycles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,21 +263,9 @@ ModeTreeChildIF& CcsdsIpCoreHandler::getModeTreeChildIF() { return *this; }
|
|||||||
|
|
||||||
object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); }
|
object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); }
|
||||||
|
|
||||||
void CcsdsIpCoreHandler::enablePrioritySelectMode() {
|
void CcsdsIpCoreHandler::enablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(true); }
|
||||||
ptmeConfig.enableBatPriorityBit(true);
|
|
||||||
// Reset the PTME
|
|
||||||
gpioIF->pullLow(ptmeGpios.ptmeResetn);
|
|
||||||
usleep(10);
|
|
||||||
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CcsdsIpCoreHandler::disablePrioritySelectMode() {
|
void CcsdsIpCoreHandler::disablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(false); }
|
||||||
ptmeConfig.enableBatPriorityBit(false);
|
|
||||||
// Reset the PTME
|
|
||||||
gpioIF->pullLow(ptmeGpios.ptmeResetn);
|
|
||||||
usleep(10);
|
|
||||||
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CcsdsIpCoreHandler::updateBatPriorityFromParam() {
|
void CcsdsIpCoreHandler::updateBatPriorityFromParam() {
|
||||||
if (batPriorityParam == 0) {
|
if (batPriorityParam == 0) {
|
||||||
@ -317,3 +274,78 @@ void CcsdsIpCoreHandler::updateBatPriorityFromParam() {
|
|||||||
enablePrioritySelectMode();
|
enablePrioritySelectMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CcsdsIpCoreHandler::setMode(Mode_t mode, Submode_t submode) {
|
||||||
|
this->submode = submode;
|
||||||
|
this->mode = mode;
|
||||||
|
modeHelper.modeChanged(mode, submode);
|
||||||
|
announceMode(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CcsdsIpCoreHandler::performPtmeUpdateWhenApplicable() {
|
||||||
|
if (not updateContext.performPtmeUpdateAfterXCycles) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (updateContext.ptmeUpdateCycleCount >= 2) {
|
||||||
|
if (updateContext.updateBatPrio) {
|
||||||
|
updateBatPriorityFromParam();
|
||||||
|
updateContext.updateBatPrio = false;
|
||||||
|
}
|
||||||
|
ReturnValue_t result;
|
||||||
|
if (updateContext.updateClockRate) {
|
||||||
|
if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_DEFAULT)) {
|
||||||
|
com::Datarate currentDatarate = com::getCurrentDatarate();
|
||||||
|
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
|
||||||
|
result = ptmeConfig.setRate(RATE_100KBPS);
|
||||||
|
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
|
||||||
|
result = ptmeConfig.setRate(RATE_500KBPS);
|
||||||
|
}
|
||||||
|
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH)) {
|
||||||
|
result = ptmeConfig.setRate(RATE_500KBPS);
|
||||||
|
} else if (submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW)) {
|
||||||
|
result = ptmeConfig.setRate(RATE_100KBPS);
|
||||||
|
}
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
sif::error << "CcsdsIpCoreHandler: Setting datarate failed" << std::endl;
|
||||||
|
}
|
||||||
|
updateContext.updateClockRate = false;
|
||||||
|
}
|
||||||
|
bool doResetPtme = true;
|
||||||
|
if (not updateContext.updateBatPrio and not updateContext.updateClockRate) {
|
||||||
|
doResetPtme = false;
|
||||||
|
}
|
||||||
|
finishPtmeUpdateAfterXCycles(doResetPtme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateContext.ptmeUpdateCycleCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CcsdsIpCoreHandler::resetPtme() {
|
||||||
|
gpioIF->pullLow(ptmeGpios.ptmeResetn);
|
||||||
|
usleep(10);
|
||||||
|
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CcsdsIpCoreHandler::initPtmeUpdateAfterXCycles() {
|
||||||
|
if (not updateContext.performPtmeUpdateAfterXCycles) {
|
||||||
|
updateContext.performPtmeUpdateAfterXCycles = true;
|
||||||
|
updateContext.ptmeUpdateCycleCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CcsdsIpCoreHandler::finishPtmeUpdateAfterXCycles(bool doResetPtme) {
|
||||||
|
if (doResetPtme) {
|
||||||
|
resetPtme();
|
||||||
|
}
|
||||||
|
ptmeLocked = false;
|
||||||
|
updateContext.performPtmeUpdateAfterXCycles = false;
|
||||||
|
updateContext.ptmeUpdateCycleCount = 0;
|
||||||
|
if (updateContext.enableTransmitAfterPtmeUpdate) {
|
||||||
|
enableTransmit();
|
||||||
|
updateContext.enableTransmitAfterPtmeUpdate = false;
|
||||||
|
}
|
||||||
|
if (updateContext.setModeAfterUpdate) {
|
||||||
|
setMode(mode, submode);
|
||||||
|
updateContext.setModeAfterUpdate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -79,7 +79,8 @@ class CcsdsIpCoreHandler : public SystemObject,
|
|||||||
* @param enTxData GPIO ID of RS485 tx data enable
|
* @param enTxData GPIO ID of RS485 tx data enable
|
||||||
*/
|
*/
|
||||||
CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, PtmeConfig& ptmeConfig,
|
CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination, PtmeConfig& ptmeConfig,
|
||||||
std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds);
|
std::atomic_bool& linkState, GpioIF* gpioIF, PtmeGpios gpioIds,
|
||||||
|
std::atomic_bool& ptmeLocked);
|
||||||
|
|
||||||
~CcsdsIpCoreHandler();
|
~CcsdsIpCoreHandler();
|
||||||
|
|
||||||
@ -137,9 +138,8 @@ class CcsdsIpCoreHandler : public SystemObject,
|
|||||||
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0);
|
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xA0);
|
||||||
|
|
||||||
// using VirtualChannelMap = std::unordered_map<VcId_t, VirtualChannelWithQueue*>;
|
|
||||||
// VirtualChannelMap virtualChannelMap;
|
|
||||||
std::atomic_bool& linkState;
|
std::atomic_bool& linkState;
|
||||||
|
std::atomic_bool& ptmeLocked;
|
||||||
|
|
||||||
object_id_t tcDestination;
|
object_id_t tcDestination;
|
||||||
|
|
||||||
@ -158,7 +158,15 @@ class CcsdsIpCoreHandler : public SystemObject,
|
|||||||
PtmeGpios ptmeGpios;
|
PtmeGpios ptmeGpios;
|
||||||
// BAT priority bit on by default to enable priority selection mode for the PTME.
|
// BAT priority bit on by default to enable priority selection mode for the PTME.
|
||||||
uint8_t batPriorityParam = 0;
|
uint8_t batPriorityParam = 0;
|
||||||
bool updateBatPriorityOnTxOff = false;
|
|
||||||
|
struct UpdateContext {
|
||||||
|
bool updateBatPrio = false;
|
||||||
|
bool updateClockRate = false;
|
||||||
|
bool enableTransmitAfterPtmeUpdate = false;
|
||||||
|
uint8_t ptmeUpdateCycleCount = 0;
|
||||||
|
bool performPtmeUpdateAfterXCycles = false;
|
||||||
|
bool setModeAfterUpdate = false;
|
||||||
|
} updateContext{};
|
||||||
|
|
||||||
GpioIF* gpioIF = nullptr;
|
GpioIF* gpioIF = nullptr;
|
||||||
|
|
||||||
@ -180,6 +188,8 @@ class CcsdsIpCoreHandler : public SystemObject,
|
|||||||
*/
|
*/
|
||||||
void disableTransmit();
|
void disableTransmit();
|
||||||
|
|
||||||
|
void performPtmeUpdateWhenApplicable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The following set of functions configure the mode of the PTME bandwith allocation table (BAT)
|
* The following set of functions configure the mode of the PTME bandwith allocation table (BAT)
|
||||||
* module. This consists of the following 2 steps:
|
* module. This consists of the following 2 steps:
|
||||||
@ -189,6 +199,11 @@ class CcsdsIpCoreHandler : public SystemObject,
|
|||||||
void enablePrioritySelectMode();
|
void enablePrioritySelectMode();
|
||||||
void disablePrioritySelectMode();
|
void disablePrioritySelectMode();
|
||||||
void updateBatPriorityFromParam();
|
void updateBatPriorityFromParam();
|
||||||
|
|
||||||
|
void setMode(Mode_t mode, Submode_t submode);
|
||||||
|
void resetPtme();
|
||||||
|
void initPtmeUpdateAfterXCycles();
|
||||||
|
void finishPtmeUpdateAfterXCycles(bool doResetPtme);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CCSDSHANDLER_H_ */
|
#endif /* CCSDSHANDLER_H_ */
|
||||||
|
@ -6,12 +6,13 @@
|
|||||||
#include <fsfw/timemanager/Stopwatch.h>
|
#include <fsfw/timemanager/Stopwatch.h>
|
||||||
|
|
||||||
LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
|
LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
|
||||||
VirtualChannelWithQueue& channel)
|
VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
pusFunnel(pusFunnel),
|
pusFunnel(pusFunnel),
|
||||||
cfdpFunnel(cfdpFunnel),
|
cfdpFunnel(cfdpFunnel),
|
||||||
channel(channel) {
|
channel(channel),
|
||||||
|
ptmeLocked(ptmeLocked) {
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue();
|
requestQueue = QueueFactory::instance()->createMessageQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
|
|||||||
readCommandQueue();
|
readCommandQueue();
|
||||||
while (true) {
|
while (true) {
|
||||||
bool performWriteOp = true;
|
bool performWriteOp = true;
|
||||||
if (mode == MODE_OFF) {
|
if (mode == MODE_OFF or ptmeLocked) {
|
||||||
performWriteOp = false;
|
performWriteOp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class LiveTmTask : public SystemObject,
|
|||||||
public ModeTreeConnectionIF {
|
public ModeTreeConnectionIF {
|
||||||
public:
|
public:
|
||||||
LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
|
LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
|
||||||
VirtualChannelWithQueue& channel);
|
VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked);
|
||||||
|
|
||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
@ -33,6 +33,7 @@ class LiveTmTask : public SystemObject,
|
|||||||
CfdpTmFunnel& cfdpFunnel;
|
CfdpTmFunnel& cfdpFunnel;
|
||||||
VirtualChannelWithQueue& channel;
|
VirtualChannelWithQueue& channel;
|
||||||
uint32_t packetCounter = 0;
|
uint32_t packetCounter = 0;
|
||||||
|
const std::atomic_bool& ptmeLocked;
|
||||||
|
|
||||||
void readCommandQueue(void);
|
void readCommandQueue(void);
|
||||||
|
|
||||||
|
@ -5,8 +5,9 @@
|
|||||||
|
|
||||||
PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
|
PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||||
LogStores stores, VirtualChannel& channel,
|
LogStores stores, VirtualChannel& channel,
|
||||||
SdCardMountedIF& sdcMan)
|
SdCardMountedIF& sdcMan,
|
||||||
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan),
|
const std::atomic_bool& ptmeLocked)
|
||||||
|
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked),
|
||||||
stores(stores),
|
stores(stores),
|
||||||
okStoreContext(persTmStore::DUMP_OK_STORE_DONE, persTmStore::DUMP_OK_CANCELLED),
|
okStoreContext(persTmStore::DUMP_OK_STORE_DONE, persTmStore::DUMP_OK_CANCELLED),
|
||||||
notOkStoreContext(persTmStore::DUMP_NOK_STORE_DONE, persTmStore::DUMP_NOK_CANCELLED),
|
notOkStoreContext(persTmStore::DUMP_NOK_STORE_DONE, persTmStore::DUMP_NOK_CANCELLED),
|
||||||
|
@ -22,7 +22,8 @@ struct LogStores {
|
|||||||
class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
|
class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, LogStores tmStore,
|
PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore, LogStores tmStore,
|
||||||
VirtualChannel& channel, SdCardMountedIF& sdcMan);
|
VirtualChannel& channel, SdCardMountedIF& sdcMan,
|
||||||
|
const std::atomic_bool& ptmeLocked);
|
||||||
|
|
||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
|
|
||||||
PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(
|
PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(
|
||||||
object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore,
|
object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore,
|
||||||
VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan)
|
VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan,
|
||||||
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan),
|
const std::atomic_bool& ptmeLocked)
|
||||||
|
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked),
|
||||||
storeWithQueue(tmStore),
|
storeWithQueue(tmStore),
|
||||||
dumpContext(eventIfDumpDone, eventIfCancelled) {}
|
dumpContext(eventIfDumpDone, eventIfCancelled) {}
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
|
|||||||
TaskFactory::delayTask(10);
|
TaskFactory::delayTask(10);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
|
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
|
||||||
TaskFactory::delayTask(2);
|
TaskFactory::delayTask(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj
|
|||||||
PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
|
PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||||
PersistentTmStoreWithTmQueue& storeWithQueue, VirtualChannel& channel,
|
PersistentTmStoreWithTmQueue& storeWithQueue, VirtualChannel& channel,
|
||||||
Event eventIfDumpDone, Event eventIfCancelled,
|
Event eventIfDumpDone, Event eventIfCancelled,
|
||||||
SdCardMountedIF& sdcMan);
|
SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked);
|
||||||
|
|
||||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
|
|
||||||
|
@ -10,13 +10,15 @@
|
|||||||
#include "mission/persistentTmStoreDefs.h"
|
#include "mission/persistentTmStoreDefs.h"
|
||||||
|
|
||||||
TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore,
|
TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore,
|
||||||
VirtualChannel& channel, SdCardMountedIF& sdcMan)
|
VirtualChannel& channel, SdCardMountedIF& sdcMan,
|
||||||
|
const std::atomic_bool& ptmeLocked)
|
||||||
: SystemObject(objectId),
|
: SystemObject(objectId),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
ipcStore(ipcStore),
|
ipcStore(ipcStore),
|
||||||
tmReader(&timeReader),
|
tmReader(&timeReader),
|
||||||
channel(channel),
|
channel(channel),
|
||||||
sdcMan(sdcMan) {
|
sdcMan(sdcMan),
|
||||||
|
ptmeLocked(ptmeLocked) {
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(10);
|
requestQueue = QueueFactory::instance()->createMessageQueue(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +101,8 @@ ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store
|
|||||||
cancelDump(dumpContext, store, false);
|
cancelDump(dumpContext, store, false);
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
if (not channel.isBusy()) {
|
// It is assumed that the PTME will only be locked for a short period (e.g. to change datarate).
|
||||||
|
if (not channel.isBusy() and not ptmeLocked) {
|
||||||
performDump(store, dumpContext, dumpPerformed);
|
performDump(store, dumpContext, dumpPerformed);
|
||||||
} else {
|
} else {
|
||||||
// The PTME might be at full load, so it might sense to delay for a bit to let it do
|
// The PTME might be at full load, so it might sense to delay for a bit to let it do
|
||||||
|
@ -40,7 +40,7 @@ class TmStoreTaskBase : public SystemObject,
|
|||||||
};
|
};
|
||||||
|
|
||||||
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel,
|
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel,
|
||||||
SdCardMountedIF& sdcMan);
|
SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked);
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
|
||||||
@ -52,6 +52,8 @@ class TmStoreTaskBase : public SystemObject,
|
|||||||
PusTmReader tmReader;
|
PusTmReader tmReader;
|
||||||
CdsShortTimeStamper timeReader;
|
CdsShortTimeStamper timeReader;
|
||||||
VirtualChannel& channel;
|
VirtualChannel& channel;
|
||||||
|
SdCardMountedIF& sdcMan;
|
||||||
|
const std::atomic_bool& ptmeLocked;
|
||||||
|
|
||||||
Mode_t mode = HasModesIF::MODE_OFF;
|
Mode_t mode = HasModesIF::MODE_OFF;
|
||||||
Countdown sdCardCheckCd = Countdown(800);
|
Countdown sdCardCheckCd = Countdown(800);
|
||||||
@ -62,7 +64,6 @@ class TmStoreTaskBase : public SystemObject,
|
|||||||
|
|
||||||
bool storesInitialized = false;
|
bool storesInitialized = false;
|
||||||
bool fileHasSwapped = false;
|
bool fileHasSwapped = false;
|
||||||
SdCardMountedIF& sdcMan;
|
|
||||||
|
|
||||||
void readCommandQueue(void);
|
void readCommandQueue(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user