Merge branch 'v2.1.0-dev' into v2.2.0-dev
Some checks are pending
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/-/pipeline/head Build queued...

This commit is contained in:
Robin Müller 2023-05-25 09:10:34 +02:00
commit 351ca1154b
13 changed files with 148 additions and 30 deletions

View File

@ -49,12 +49,20 @@ will consitute of a breaking change warranting a new major release:
- Disable missed deadlines per default. Not useful in orbit, and triggers all the time on the EM
build after a number of subsequent runs, without any apparent reason (deadlines are not actually
missed, thread usage displayed is nominal)
- TM store dumpes will not be cancelled anymore if the transmitter is off. The dump can be cancelled
with an OFF command, and the PTME is perfectly capable of dumping without the transmitter being
on.
- Transmitter state is not taken into account anymore for writing into the PTME. The PTME should
be perfectly capable of generating a valid CADU, even when the transmitter is not ON for any
reason.
## Added
- Add the remaining system modes.
- PLOC MPSoC flash read command working.
- BPX battery handler is added for EM by default.
- ACU dummy HK sets
- IMTQ HK sets
## Fixed
@ -74,6 +82,10 @@ will consitute of a breaking change warranting a new major release:
- PLOC MPSoC special communication is now scheduled, which allows flash read and flash write
commands to work.
- Fixed the MPSoC flash write command.
- Added missing ACS parameter.
- HK TM store: The HK store dump success event was triggered for cancelled HK dumps.
- When a PUS parsing error occured while parsing a TM store file, the dump completion procedure
was always executed.
# [v2.0.5] 2023-05-11

View File

@ -62,6 +62,10 @@ void ObjectFactory::produce(void* args) {
StorageManagerIF* tmStore;
StorageManagerIF* ipcStore;
PersistentTmStores persistentStores;
bool enableHkSets = false;
#if OBSW_ENABLE_PERIODIC_HK == 1
enableHkSets = true;
#endif
auto sdcMan = new DummySdCardManager("/tmp");
ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan, &ipcStore,
&tmStore, persistentStores, 120);
@ -101,7 +105,7 @@ void ObjectFactory::produce(void* args) {
#endif
dummy::DummyCfg cfg;
dummy::createDummies(cfg, *dummySwitcher, dummyGpioIF);
dummy::createDummies(cfg, *dummySwitcher, dummyGpioIF, enableHkSets);
HeaterHandler* heaterHandler = nullptr;
// new ThermalController(objects::THERMAL_CONTROLLER);

View File

@ -805,7 +805,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
// Core task which handles the HK store and takes care of dumping it as TM using a VC directly
auto* hkStore = new PersistentSingleTmStoreTask(
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_CANCELLED, *SdCardManager::instance(),
PTME_LOCKED);
hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);

View File

@ -79,7 +79,7 @@ void ObjectFactory::produce(void* args) {
#endif
satsystem::EIVE_SYSTEM.setI2cRecoveryParams(pwrSwitcher);
dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF);
dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF, enableHkSets);
new CoreController(objects::CORE_CONTROLLER, enableHkSets);

View File

@ -2,8 +2,11 @@
#include <mission/power/gsDefs.h>
AcuDummy::AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
: DeviceHandlerBase(objectId, comif, comCookie) {}
AcuDummy::AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, bool enableHkSets)
: DeviceHandlerBase(objectId, comif, comCookie),
coreHk(this),
auxHk(this),
enableHkSets(enableHkSets) {}
AcuDummy::~AcuDummy() {}
@ -37,7 +40,49 @@ uint32_t AcuDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
ReturnValue_t AcuDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
using namespace ACU;
localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNELS, new PoolEntry<int16_t>(6));
localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNELS, new PoolEntry<uint16_t>(6));
localDataPoolMap.emplace(pool::ACU_VCC, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(pool::ACU_VBAT, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(ACU::pool::ACU_TEMPERATURES,
new PoolEntry<float>({10.0, 10.0, 10.0}, true));
localDataPoolMap.emplace(pool::ACU_MPPT_MODE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(pool::ACU_VBOOST_IN_CHANNELS, new PoolEntry<uint16_t>(6));
localDataPoolMap.emplace(pool::ACU_POWER_IN_CHANNELS, new PoolEntry<uint16_t>(6));
localDataPoolMap.emplace(pool::ACU_DAC_ENABLES, new PoolEntry<uint8_t>(3));
localDataPoolMap.emplace(pool::ACU_DAC_RAW_CHANNELS, new PoolEntry<uint16_t>(6));
localDataPoolMap.emplace(pool::ACU_BOOTCAUSE, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::ACU_BOOTCNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::ACU_UPTIME, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::ACU_RESET_CAUSE, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(pool::ACU_MPPT_TIME, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(pool::ACU_MPPT_PERIOD, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(pool::ACU_DEVICES, new PoolEntry<uint8_t>(8));
localDataPoolMap.emplace(pool::ACU_DEVICES_STATUS, new PoolEntry<uint8_t>(8));
localDataPoolMap.emplace(pool::ACU_WDT_CNT_GND, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::ACU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0));
poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0));
return returnvalue::OK;
}
LocalPoolDataSetBase *AcuDummy::getDataSetHandle(sid_t sid) {
if (sid == coreHk.getSid()) {
return &coreHk;
} else if (sid == auxHk.getSid()) {
return &auxHk;
}
return nullptr;
}

View File

@ -2,6 +2,7 @@
#define DUMMIES_ACUDUMMY_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/power/gsDefs.h>
class AcuDummy : public DeviceHandlerBase {
public:
@ -11,10 +12,14 @@ class AcuDummy : public DeviceHandlerBase {
static const uint8_t SIMPLE_COMMAND_DATA = 1;
static const uint8_t PERIODIC_REPLY_DATA = 2;
AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, bool enableHkSets);
virtual ~AcuDummy();
protected:
ACU::CoreHk coreHk;
ACU::AuxHk auxHk;
bool enableHkSets;
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
@ -28,6 +33,7 @@ class AcuDummy : public DeviceHandlerBase {
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
};
#endif /* DUMMIES_ACUDUMMY_H_ */

View File

@ -2,8 +2,12 @@
#include <mission/acs/imtqHelpers.h>
ImtqDummy::ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
: DeviceHandlerBase(objectId, comif, comCookie) {}
ImtqDummy::ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie,
bool enableHkSets)
: DeviceHandlerBase(objectId, comif, comCookie),
setNoTorque(this),
setWithTorque(this),
enableHkSets(enableHkSets) {}
ImtqDummy::~ImtqDummy() = default;
@ -45,5 +49,37 @@ ReturnValue_t ImtqDummy::initializeLocalDataPool(localpool::DataPool &localDataP
localDataPoolMap.emplace(imtq::ACTUATION_RAW_STATUS, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(imtq::DIPOLES_ID, new PoolEntry<int16_t>({0, 0, 0}));
localDataPoolMap.emplace(imtq::CURRENT_TORQUE_DURATION, new PoolEntry<uint16_t>({0}));
// ENG HK No Torque
localDataPoolMap.emplace(imtq::DIGITAL_VOLTAGE_MV, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(imtq::ANALOG_VOLTAGE_MV, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(imtq::DIGITAL_CURRENT, new PoolEntry<float>({0}));
localDataPoolMap.emplace(imtq::ANALOG_CURRENT, new PoolEntry<float>({0}));
localDataPoolMap.emplace(imtq::COIL_CURRENTS, &coilCurrentsMilliampsNoTorque);
localDataPoolMap.emplace(imtq::COIL_TEMPERATURES, &coilTempsNoTorque);
localDataPoolMap.emplace(imtq::MCU_TEMPERATURE, new PoolEntry<int16_t>({0}));
// ENG HK With Torque
localDataPoolMap.emplace(imtq::DIGITAL_VOLTAGE_MV_WT, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(imtq::ANALOG_VOLTAGE_MV_WT, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(imtq::DIGITAL_CURRENT_WT, new PoolEntry<float>({0}));
localDataPoolMap.emplace(imtq::ANALOG_CURRENT_WT, new PoolEntry<float>({0}));
localDataPoolMap.emplace(imtq::COIL_CURRENTS_WT, &coilCurrentsMilliampsWithTorque);
localDataPoolMap.emplace(imtq::COIL_TEMPERATURES_WT, &coilTempsWithTorque);
localDataPoolMap.emplace(imtq::MCU_TEMPERATURE_WT, new PoolEntry<int16_t>({0}));
poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(setNoTorque.getSid(), enableHkSets, 30.0));
poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(setWithTorque.getSid(), enableHkSets, 30.0));
return DeviceHandlerBase::initializeLocalDataPool(localDataPoolMap, poolManager);
}
LocalPoolDataSetBase *ImtqDummy::getDataSetHandle(sid_t sid) {
if (sid == setNoTorque.getSid()) {
return &setNoTorque;
} else if (sid == setWithTorque.getSid()) {
return &setWithTorque;
}
return nullptr;
}

View File

@ -3,6 +3,8 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include "mission/acs/imtqHelpers.h"
class ImtqDummy : public DeviceHandlerBase {
public:
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
@ -11,10 +13,31 @@ class ImtqDummy : public DeviceHandlerBase {
static const uint8_t SIMPLE_COMMAND_DATA = 1;
static const uint8_t PERIODIC_REPLY_DATA = 2;
ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, bool enableHkSets);
~ImtqDummy() override;
protected:
imtq::HkDatasetNoTorque setNoTorque;
imtq::HkDatasetWithTorque setWithTorque;
bool enableHkSets;
PoolEntry<uint8_t> statusMode = PoolEntry<uint8_t>({0});
PoolEntry<uint8_t> statusError = PoolEntry<uint8_t>({0});
PoolEntry<uint8_t> statusConfig = PoolEntry<uint8_t>({0});
PoolEntry<uint32_t> statusUptime = PoolEntry<uint32_t>({0});
PoolEntry<int32_t> mgmCalEntry = PoolEntry<int32_t>(3);
PoolEntry<int16_t> dipolesPoolEntry = PoolEntry<int16_t>({0, 0, 0}, false);
PoolEntry<uint16_t> torqueDurationEntry = PoolEntry<uint16_t>({0}, false);
PoolEntry<float> coilCurrentsMilliampsNoTorque = PoolEntry<float>(3);
PoolEntry<float> coilCurrentsMilliampsWithTorque = PoolEntry<float>(3);
PoolEntry<int16_t> coilTempsNoTorque = PoolEntry<int16_t>(3);
PoolEntry<int16_t> coilTempsWithTorque = PoolEntry<int16_t>(3);
PoolEntry<float> mtmRawNoTorque = PoolEntry<float>(3);
PoolEntry<uint8_t> actStatusNoTorque = PoolEntry<uint8_t>(1);
PoolEntry<float> mtmRawWithTorque = PoolEntry<float>(3);
PoolEntry<uint8_t> actStatusWithTorque = PoolEntry<uint8_t>(1);
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
@ -28,6 +51,7 @@ class ImtqDummy : public DeviceHandlerBase {
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
};
#endif /* DUMMIES_IMTQDUMMY_H_ */

View File

@ -42,7 +42,8 @@
#include "mission/system/tree/payloadModeTree.h"
#include "mission/tcs/defs.h"
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF) {
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF,
bool enableHkSets) {
new ComIFDummy(objects::DUMMY_COM_IF);
auto* comCookieDummy = new ComCookieDummy();
if (cfg.addBpxBattDummy) {
@ -74,13 +75,14 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
}
auto* imtqAssy = new ImtqAssembly(objects::IMTQ_ASSY);
imtqAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
auto* imtqDummy = new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
auto* imtqDummy =
new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy, enableHkSets);
imtqDummy->enableThermalModule(ThermalStateCfg());
imtqDummy->connectModeTreeParent(*imtqAssy);
if (cfg.addOnlyAcuDummy) {
new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy, enableHkSets);
} else if (cfg.addPowerDummies) {
new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy, enableHkSets);
new PduDummy(objects::PDU1_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
new PduDummy(objects::PDU2_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
new P60DockDummy(objects::P60DOCK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);

View File

@ -22,6 +22,6 @@ struct DummyCfg {
bool addCamSwitcherDummy = true;
};
void createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch, GpioIF* gpioIF);
void createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch, GpioIF* gpioIF, bool enableHkSets);
} // namespace dummy

View File

@ -94,13 +94,6 @@ void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, boo
ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store,
DumpContext& dumpContext, bool& dumpPerformed) {
ReturnValue_t result = returnvalue::OK;
// The PTME might have been reset an transmitter state change, so there is no point in continuing
// the dump.
// TODO: Will be solved in a cleaner way, this is kind of a hack.
if (not channel.isTxOn()) {
cancelDump(dumpContext, store, false);
return returnvalue::FAILED;
}
// 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);
@ -140,7 +133,7 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped);
if (result != returnvalue::OK) {
sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl;
} else if (fileHasSwapped or result == PersistentTmStore::DUMP_DONE) {
} else if (fileHasSwapped and result == PersistentTmStore::DUMP_DONE) {
// This can happen if a file is corrupted and the next file swap completes the dump.
dumpDoneHandler();
return returnvalue::OK;

View File

@ -11,10 +11,7 @@ ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) {
}
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) {
if (txOn) {
return ptme.writeToVc(vcId, data, size);
}
return returnvalue::OK;
return ptme.writeToVc(vcId, data, size);
}
uint8_t VirtualChannel::getVcid() const { return vcId; }
@ -22,10 +19,6 @@ uint8_t VirtualChannel::getVcid() const { return vcId; }
const char* VirtualChannel::getName() const { return vcName.c_str(); }
bool VirtualChannel::isBusy() const {
// Data is discarded, so channel is not busy.
if (not txOn) {
return false;
}
return ptme.isBusy(vcId);
}

View File

@ -539,6 +539,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0xA:
parameterWrapper->setVector(nadirModeControllerParameters.quatRef);
break;
case 0xB:
parameterWrapper->setVector(nadirModeControllerParameters.refRotRate);
break;
case 0xC:
parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax);
break;