Merge remote-tracking branch 'origin/develop' into thermal_controller
EIVE/eive-obsw/pipeline/pr-develop This commit looks good Details

This commit is contained in:
Robin Müller 2023-03-31 19:18:05 +02:00
commit d1775a52aa
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
71 changed files with 1337 additions and 655 deletions

View File

@ -16,11 +16,45 @@ will consitute of a breaking change warranting a new major release:
# [unreleased]
## Changed
- SCEX filename updates. Also use T as the file ID / date separator between date and time.
- COM TM store and dump handling: Introduce modes for all 4 TM VC/store tasks. The OFF mode can be
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
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
- Bugfix for side lane transitions of the dual lane assemblies, which only worked when the
assembly was directly commanded
- Syrlinks Handler: Bugfix so transition command is only sent once.
## Added
- Added GPS0 and GPS1 health device which are used by the ACS board assembly when deciding whether
to change to the other side or to go to dual side directly. Setting the health devices to faulty
should also trigger a side switch or a switch to dual mode.
# [v1.41.0] 2023-03-28
eive-tmtc: v2.20.0
q7s-package: v2.2.0
## Fixed
- Proper Faulty/External Control handling for the dual lane assemblies.
- ACS board devices: Go to ON mode instead of going to NORMAL mode directly.
- SUS device handlers: Go to ON mode on startup instead of NORMAL mode.
- Tweaks for the delay handling for the persistent TM stores. This allows pushing the full
high datarate when dumping telemetry. The most important and interesting fix is that
there needs to be a small delay between the polling of the GPIO. Polling the GPIO
without any delay consecutively can lead to scheduling issues.
- Bump FSFW for fix of `ControllerBase` class `startTransition` implementation.
- Bump FSFW for possible fix of `PowerSwitcherComponent`: Initial mode `MODE_UNDEFINED`.
## Changed

View File

@ -10,7 +10,7 @@
cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 1)
set(OBSW_VERSION_MINOR 40)
set(OBSW_VERSION_MINOR 41)
set(OBSW_VERSION_REVISION 0)
# set(CMAKE_VERBOSE TRUE)
@ -486,7 +486,8 @@ endif()
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_FSFW_NAME}
${LIB_OS_NAME})
target_link_libraries(${LIB_DUMMIES} PUBLIC ${LIB_FSFW_NAME} ${LIB_JSON_NAME})
target_link_libraries(${LIB_DUMMIES} PUBLIC ${LIB_EIVE_MISSION}
${LIB_FSFW_NAME} ${LIB_JSON_NAME})
target_link_libraries(${OBSW_NAME} PRIVATE ${LIB_EIVE_MISSION} ${LIB_DUMMIES})

View File

@ -30,7 +30,7 @@
#include <dummies/AcuDummy.h>
#include <dummies/CoreControllerDummy.h>
#include "dummies/helpers.h"
#include "dummies/helperFactory.h"
#ifdef PLATFORM_UNIX
#include <fsfw_hal/linux/serial/SerialComIF.h>

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 278 translations.
* @brief Auto-generated event translation file. Contains 284 translations.
* @details
* Generated on: 2023-03-26 16:47:32
* Generated on: 2023-03-31 19:17:49
*/
#include "translateEvents.h"
@ -209,11 +209,11 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED"
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE";
const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED";
const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY";
const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900";
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901";
const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING =
"SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903";
const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE";
const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE";
const char *CANT_GET_FIX_STRING = "CANT_GET_FIX";
@ -273,17 +273,22 @@ const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE";
const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT";
const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED";
const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE";
const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE";
const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE";
const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE";
const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE";
const char *DUMP_OK_CANCELLED_STRING = "DUMP_OK_CANCELLED";
const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED";
const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED";
const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED";
const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED";
const char *translateEvents(Event event) {
switch ((event & 0xFFFF)) {
@ -695,6 +700,8 @@ const char *translateEvents(Event event) {
return POWER_STATE_MACHINE_TIMEOUT_STRING;
case (12803):
return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING;
case (12804):
return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING;
case (12900):
return TRANSITION_OTHER_SIDE_FAILED_12900_STRING;
case (12901):
@ -821,6 +828,8 @@ const char *translateEvents(Event event) {
return CAMERA_OVERHEATING_STRING;
case (14106):
return PCDU_SYSTEM_OVERHEATING_STRING;
case (14107):
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
case (14201):
return TX_TIMER_EXPIRED_STRING;
case (14202):
@ -831,8 +840,6 @@ const char *translateEvents(Event event) {
return FILE_TOO_LARGE_STRING;
case (14302):
return BUSY_DUMPING_EVENT_STRING;
case (14303):
return DUMP_WAS_CANCELLED_STRING;
case (14305):
return DUMP_OK_STORE_DONE_STRING;
case (14306):
@ -843,6 +850,16 @@ const char *translateEvents(Event event) {
return DUMP_HK_STORE_DONE_STRING;
case (14309):
return DUMP_CFDP_STORE_DONE_STRING;
case (14310):
return DUMP_OK_CANCELLED_STRING;
case (14311):
return DUMP_NOK_CANCELLED_STRING;
case (14312):
return DUMP_MISC_CANCELLED_STRING;
case (14313):
return DUMP_HK_CANCELLED_STRING;
case (14314):
return DUMP_CFDP_CANCELLED_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 169 translations.
* Generated on: 2023-03-26 16:47:32
* Contains 171 translations.
* Generated on: 2023-03-31 19:17:49
*/
#include "translateObjects.h"
@ -38,6 +38,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
const char *RW4_STRING = "RW4";
const char *STAR_TRACKER_STRING = "STAR_TRACKER";
const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER";
const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV";
const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV";
const char *IMTQ_POLLING_STRING = "IMTQ_POLLING";
const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER";
const char *PCDU_HANDLER_STRING = "PCDU_HANDLER";
@ -242,6 +244,10 @@ const char *translateObject(object_id_t object) {
return STAR_TRACKER_STRING;
case 0x44130045:
return GPS_CONTROLLER_STRING;
case 0x44130046:
return GPS_0_HEALTH_DEV_STRING;
case 0x44130047:
return GPS_1_HEALTH_DEV_STRING;
case 0x44140013:
return IMTQ_POLLING_STRING;
case 0x44140014:

View File

@ -1,5 +1,6 @@
#include "ObjectFactory.h"
#include <fsfw/devicehandlers/HealthDevice.h>
#include <fsfw/subsystem/Subsystem.h>
#include <linux/acs/AcsBoardPolling.h>
#include <linux/acs/GpsHyperionLinuxController.h>
@ -19,15 +20,15 @@
#include <mission/acs/MgmRm3100CustomHandler.h>
#include <mission/acs/str/StarTrackerHandler.h>
#include <mission/acs/str/strHelpers.h>
#include <mission/com/LiveTmTask.h>
#include <mission/com/PersistentLogTmStoreTask.h>
#include <mission/com/PersistentSingleTmStoreTask.h>
#include <mission/power/CspCookie.h>
#include <mission/system/acs/ImtqAssembly.h>
#include <mission/system/acs/StrAssembly.h>
#include <mission/system/fdir/StrFdir.h>
#include <mission/system/objects/CamSwitcher.h>
#include <mission/system/objects/StrAssembly.h>
#include <mission/system/objects/SyrlinksAssembly.h>
#include <mission/tmtc/LiveTmTask.h>
#include <mission/tmtc/PersistentLogTmStoreTask.h>
#include <mission/tmtc/PersistentSingleTmStoreTask.h>
#include "OBSWConfig.h"
#include "bsp_q7s/boardtest/Q7STestTask.h"
@ -80,6 +81,7 @@ using gpio::Levels;
#include <mission/acs/ImtqHandler.h>
#include <mission/acs/rwHelpers.h>
#include <mission/com/SyrlinksHandler.h>
#include <mission/com/VirtualChannelWithQueue.h>
#include <mission/payload/PayloadPcduHandler.h>
#include <mission/payload/RadiationSensorHandler.h>
#include <mission/payload/payloadPcduDefinitions.h>
@ -95,7 +97,6 @@ using gpio::Levels;
#include <mission/tcs/Max31865Definitions.h>
#include <mission/tcs/Max31865PT1000Handler.h>
#include <mission/tcs/Tmp1075Handler.h>
#include <mission/tmtc/VirtualChannelWithQueue.h>
#include <sstream>
@ -124,6 +125,7 @@ using gpio::Levels;
ResetArgs RESET_ARGS_GNSS;
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
std::atomic_bool PTME_LOCKED = false;
std::atomic_uint16_t I2C_FATAL_ERRORS = 0;
void Factory::setStaticFrameworkObjectIds() {
@ -516,6 +518,8 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF*
new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps);
gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS);
new HealthDevice(objects::GPS_0_HEALTH_DEV, objects::ACS_BOARD_ASS);
new HealthDevice(objects::GPS_1_HEALTH_DEV, objects::ACS_BOARD_ASS);
ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyChildren, gpsCtrl, gpioComIF);
#endif /* OBSW_ADD_ACS_HANDLERS == 1 */
}
@ -751,10 +755,8 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, "PAPB VC3");
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio);
// Initialise to low and then pull high to do a PTME reset, which puts the PTME in reset
// state. It will be put out of reset in the CCSDS handler initialize function.
gpio = new GpiodRegularByLineName(q7s::gpioNames::PTME_RESETN, "PTME RESETN",
gpio::Direction::OUT, gpio::Levels::LOW);
gpio::Direction::OUT, gpio::Levels::HIGH);
gpioCookiePtmeIp->addGpio(gpioIds::PTME_RESETN, gpio);
gpioChecker(args.gpioComIF.addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
@ -788,34 +790,42 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
*args.ipCoreHandler =
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
auto* vcWithQueue =
new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme,
LINK_STATE, args.tmStore, 500);
args.liveDestination = vcWithQueue;
new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel, *vcWithQueue);
auto* liveTask = new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel,
*vcWithQueue, PTME_LOCKED);
liveTask->connectModeTreeParent(satsystem::com::SUBSYSTEM);
// Set up log store.
auto* vc = new VirtualChannel(objects::PTME_VC1_LOG_TM, ccsds::VC1, "PTME VC1 LOG TM", *ptme,
LINK_STATE);
LogStores logStores(args.stores);
// Core task which handles the LOG store and takes care of dumping it as TM using a VC directly
new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, logStores, *vc,
*SdCardManager::instance());
auto* logStore =
new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, logStores, *vc,
*SdCardManager::instance(), PTME_LOCKED);
logStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
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
new PersistentSingleTmStoreTask(objects::HK_STORE_AND_TM_TASK, args.ipcStore,
*args.stores.hkStore, *vc, persTmStore::DUMP_HK_STORE_DONE,
*SdCardManager::instance());
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(),
PTME_LOCKED);
hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM);
vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme,
LINK_STATE);
// Core task which handles the CFDP store and takes care of dumping it as TM using a VC directly
new PersistentSingleTmStoreTask(objects::CFDP_STORE_AND_TM_TASK, args.ipcStore,
*args.stores.cfdpStore, *vc, persTmStore::DUMP_CFDP_STORE_DONE,
*SdCardManager::instance());
auto* cfdpTask = new PersistentSingleTmStoreTask(
objects::CFDP_STORE_AND_TM_TASK, args.ipcStore, *args.stores.cfdpStore, *vc,
persTmStore::DUMP_CFDP_STORE_DONE, persTmStore::DUMP_CFDP_CANCELLED,
*SdCardManager::instance(), PTME_LOCKED);
cfdpTask->connectModeTreeParent(satsystem::com::SUBSYSTEM);
ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
if (result != returnvalue::OK) {

View File

@ -4,11 +4,11 @@
#include <fsfw/returnvalues/returnvalue.h>
#include <fsfw_hal/linux/spi/SpiComIF.h>
#include <mission/com/CcsdsIpCoreHandler.h>
#include <mission/com/PersistentLogTmStoreTask.h>
#include <mission/genericFactory.h>
#include <mission/system/objects/Stack5VHandler.h>
#include <mission/tcs/HeaterHandler.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PersistentLogTmStoreTask.h>
#include <mission/tmtc/PusTmFunnel.h>
#include <atomic>
@ -24,6 +24,7 @@ class AcsBoardAssembly;
class GpioIF;
extern std::atomic_uint16_t I2C_FATAL_ERRORS;
extern std::atomic_bool PTME_LOCKED;
namespace ObjectFactory {

View File

@ -291,6 +291,14 @@ void scheduling::initTasks() {
if (result != returnvalue::OK) {
scheduling::printAddObjectError("STR_ASSY", objects::STR_ASSY);
}
result = acsSysTask->addComponent(objects::GPS_0_HEALTH_DEV);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("GPS_0_HEALTH_DEV", objects::GPS_0_HEALTH_DEV);
}
result = acsSysTask->addComponent(objects::GPS_1_HEALTH_DEV);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("GPS_1_HEALTH_DEV", objects::GPS_1_HEALTH_DEV);
}
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
"TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);

View File

@ -13,7 +13,7 @@
#include "bsp_q7s/core/ObjectFactory.h"
#include "busConf.h"
#include "devConf.h"
#include "dummies/helpers.h"
#include "dummies/helperFactory.h"
#include "eive/objects.h"
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
#include "linux/ObjectFactory.h"

View File

@ -43,6 +43,8 @@ enum commonObjects : uint32_t {
RW4 = 0x44120350,
STAR_TRACKER = 0x44130001,
GPS_CONTROLLER = 0x44130045,
GPS_0_HEALTH_DEV = 0x44130046,
GPS_1_HEALTH_DEV = 0x44130047,
IMTQ_POLLING = 0x44140013,
IMTQ_HANDLER = 0x44140014,

View File

@ -26,6 +26,6 @@ target_sources(
CoreControllerDummy.cpp
PlocMpsocDummy.cpp
PlocSupervisorDummy.cpp
helpers.cpp
helperFactory.cpp
MgmRm3100Dummy.cpp
Tmp1075Dummy.cpp)

View File

@ -1,4 +1,4 @@
#include "helpers.h"
#include "helperFactory.h"
#include <dummies/AcuDummy.h>
#include <dummies/BpxDummy.h>
@ -24,11 +24,12 @@
#include <dummies/StarTrackerDummy.h>
#include <dummies/SusDummy.h>
#include <dummies/SyrlinksDummy.h>
#include <fsfw/devicehandlers/HealthDevice.h>
#include <fsfw_hal/common/gpio/GpioIF.h>
#include <mission/power/gsDefs.h>
#include <mission/system/acs/ImtqAssembly.h>
#include <mission/system/acs/StrAssembly.h>
#include <mission/system/objects/CamSwitcher.h>
#include <mission/system/objects/StrAssembly.h>
#include <mission/system/objects/TcsBoardAssembly.h>
#include "TemperatureSensorInserter.h"
@ -98,6 +99,8 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
new GyroAdisDummy(objects::GYRO_2_ADIS_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
assemblyDhbs[7] =
new GyroL3GD20Dummy(objects::GYRO_3_L3G_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
new HealthDevice(objects::GPS_0_HEALTH_DEV, objects::ACS_BOARD_ASS);
new HealthDevice(objects::GPS_1_HEALTH_DEV, objects::ACS_BOARD_ASS);
auto* gpsCtrl = new GpsCtrlDummy(objects::GPS_CONTROLLER);
ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyDhbs, gpsCtrl, gpioIF);
}

View File

@ -203,6 +203,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12801;0x3201;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/AcsBoardAssembly.h
12802;0x3202;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/AcsBoardAssembly.h
12803;0x3203;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/AcsBoardAssembly.h
12804;0x3204;DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY;MEDIUM;This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode.;mission/system/acs/AcsBoardAssembly.h
12900;0x3264;TRANSITION_OTHER_SIDE_FAILED;HIGH;No description;mission/system/acs/SusAssembly.h
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
@ -266,14 +267,19 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14104;0x3718;OBC_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
14301;0x37dd;FILE_TOO_LARGE;LOW;File in store too large. P1: Detected file size P2: Allowed file size;mission/persistentTmStoreDefs.h
14302;0x37de;BUSY_DUMPING_EVENT;INFO;No description;mission/persistentTmStoreDefs.h
14303;0x37df;DUMP_WAS_CANCELLED;LOW;Dump was cancelled. P1: Object ID of store.;mission/persistentTmStoreDefs.h
14305;0x37e1;DUMP_OK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14306;0x37e2;DUMP_NOK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14307;0x37e3;DUMP_MISC_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14308;0x37e4;DUMP_HK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14309;0x37e5;DUMP_CFDP_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14310;0x37e6;DUMP_OK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14311;0x37e7;DUMP_NOK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14312;0x37e8;DUMP_MISC_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
203 12801 0x3201 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/AcsBoardAssembly.h
204 12802 0x3202 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/AcsBoardAssembly.h
205 12803 0x3203 SIDE_SWITCH_TRANSITION_NOT_ALLOWED LOW Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination mission/system/acs/AcsBoardAssembly.h
206 12804 0x3204 DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY MEDIUM This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode. mission/system/acs/AcsBoardAssembly.h
207 12900 0x3264 TRANSITION_OTHER_SIDE_FAILED HIGH No description mission/system/acs/SusAssembly.h
208 12901 0x3265 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/SusAssembly.h
209 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
267 14104 0x3718 OBC_OVERHEATING HIGH No description mission/controller/tcsDefs.h
268 14105 0x3719 CAMERA_OVERHEATING HIGH No description mission/controller/tcsDefs.h
269 14106 0x371a PCDU_SYSTEM_OVERHEATING HIGH No description mission/controller/tcsDefs.h
270 14107 0x371b HEATER_NOT_OFF_FOR_OFF_MODE MEDIUM No description mission/controller/tcsDefs.h
271 14201 0x3779 TX_TIMER_EXPIRED INFO The transmit timer to protect the Syrlinks expired P1: The current timer value mission/system/com/ComSubsystem.h
272 14202 0x377a BIT_LOCK_TX_ON INFO Transmitter will be turned on due to detection of bitlock mission/system/com/ComSubsystem.h
273 14300 0x37dc POSSIBLE_FILE_CORRUPTION LOW P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp. mission/persistentTmStoreDefs.h
274 14301 0x37dd FILE_TOO_LARGE LOW File in store too large. P1: Detected file size P2: Allowed file size mission/persistentTmStoreDefs.h
275 14302 0x37de BUSY_DUMPING_EVENT INFO No description mission/persistentTmStoreDefs.h
14303 0x37df DUMP_WAS_CANCELLED LOW Dump was cancelled. P1: Object ID of store. mission/persistentTmStoreDefs.h
276 14305 0x37e1 DUMP_OK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
277 14306 0x37e2 DUMP_NOK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
278 14307 0x37e3 DUMP_MISC_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
279 14308 0x37e4 DUMP_HK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
280 14309 0x37e5 DUMP_CFDP_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
281 14310 0x37e6 DUMP_OK_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
282 14311 0x37e7 DUMP_NOK_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
283 14312 0x37e8 DUMP_MISC_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
284 14313 0x37e9 DUMP_HK_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
285 14314 0x37ea DUMP_CFDP_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h

View File

@ -30,6 +30,8 @@
0x44120350;RW4
0x44130001;STAR_TRACKER
0x44130045;GPS_CONTROLLER
0x44130046;GPS_0_HEALTH_DEV
0x44130047;GPS_1_HEALTH_DEV
0x44140013;IMTQ_POLLING
0x44140014;IMTQ_HANDLER
0x442000A1;PCDU_HANDLER

1 0x42694269 TEST_TASK
30 0x44120350 RW4
31 0x44130001 STAR_TRACKER
32 0x44130045 GPS_CONTROLLER
33 0x44130046 GPS_0_HEALTH_DEV
34 0x44130047 GPS_1_HEALTH_DEV
35 0x44140013 IMTQ_POLLING
36 0x44140014 IMTQ_HANDLER
37 0x442000A1 PCDU_HANDLER

View File

@ -291,8 +291,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x2e02;HPA_InvalidDomainId;No description;2;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h
0x2e03;HPA_InvalidValue;No description;3;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h
0x2e05;HPA_ReadOnly;No description;5;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h
0x2f01;ASC_NoPacketFound;No description;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/DleParser.h
0x2f02;ASC_PossiblePacketLoss;No description;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/DleParser.h
0x2f01;ASC_TooLongForTargetType;No description;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h
0x2f02;ASC_InvalidCharacters;No description;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h
0x2f03;ASC_BufferTooSmall;No description;3;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h
0x3001;POS_InPowerTransition;No description;1;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h
0x3002;POS_SwitchStateMismatch;No description;2;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h
@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
@ -402,9 +402,9 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
0x4500;HSPI_HalTimeoutRetval;No description;0;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h
0x4501;HSPI_HalBusyRetval;No description;1;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h
0x4502;HSPI_HalErrorRetval;No description;2;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
@ -415,12 +415,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x4805;HGIO_GpioDuplicateDetected;No description;5;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
0x4806;HGIO_GpioInitFailed;No description;6;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
0x4807;HGIO_GpioGetValueFailed;No description;7;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
0x4aa0;MGMLIS3_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa1;MGMLIS3_InvalidRampTime;Action Message with invalid ramp time was received.;161;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa2;MGMLIS3_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa3;MGMLIS3_ExecutionFailed;Command execution failed;163;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa4;MGMLIS3_CrcError;Reaction wheel reply has invalid crc;164;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa5;MGMLIS3_ValueNotRead;No description;165;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4c00;SPPA_NoPacketFound;No description;0;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h
0x4c01;SPPA_SplitPacket;No description;1;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h
0x4fa1;HEATER_CommandNotSupported;No description;161;HEATER_HANDLER;mission/tcs/HeaterHandler.h
@ -480,8 +474,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x53b6;STRH_StartrackerAlreadyBooted;Star tracker is already in firmware mode;182;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
0x53b7;STRH_StartrackerNotRunningFirmware;Star tracker must be in firmware mode to run this command;183;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
0x53b8;STRH_StartrackerNotRunningBootloader;Star tracker must be in bootloader mode to run this command;184;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
0x58a0;SUSS_ErrorUnlockMutex;No description;160;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x58a1;SUSS_ErrorLockMutex;No description;161;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x58a0;SUSS_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;SUS_HANDLER;mission/acs/RwHandler.h
0x58a1;SUSS_InvalidRampTime;Action Message with invalid ramp time was received.;161;SUS_HANDLER;mission/acs/RwHandler.h
0x58a2;SUSS_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;SUS_HANDLER;mission/acs/RwHandler.h
0x58a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h
0x58a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h
0x58a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h
0x5d00;GOMS_PacketTooLong;No description;0;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
0x5d01;GOMS_InvalidTableId;No description;1;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
0x5d02;GOMS_InvalidAddress;No description;2;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
291 0x2e02 HPA_InvalidDomainId No description 2 HAS_PARAMETERS_IF fsfw/src/fsfw/parameters/HasParametersIF.h
292 0x2e03 HPA_InvalidValue No description 3 HAS_PARAMETERS_IF fsfw/src/fsfw/parameters/HasParametersIF.h
293 0x2e05 HPA_ReadOnly No description 5 HAS_PARAMETERS_IF fsfw/src/fsfw/parameters/HasParametersIF.h
294 0x2f01 ASC_NoPacketFound ASC_TooLongForTargetType No description 1 ASCII_CONVERTER fsfw/src/fsfw/globalfunctions/DleParser.h fsfw/src/fsfw/globalfunctions/AsciiConverter.h
295 0x2f02 ASC_PossiblePacketLoss ASC_InvalidCharacters No description 2 ASCII_CONVERTER fsfw/src/fsfw/globalfunctions/DleParser.h fsfw/src/fsfw/globalfunctions/AsciiConverter.h
296 0x2f03 ASC_BufferTooSmall No description 3 ASCII_CONVERTER fsfw/src/fsfw/globalfunctions/AsciiConverter.h
297 0x3001 POS_InPowerTransition No description 1 POWER_SWITCHER fsfw/src/fsfw/power/PowerSwitcher.h
298 0x3002 POS_SwitchStateMismatch No description 2 POWER_SWITCHER fsfw/src/fsfw/power/PowerSwitcher.h
371 0x3e03 HKM_PeriodicHelperInvalid No description 3 HOUSEKEEPING_MANAGER fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
372 0x3e04 HKM_PoolobjectNotFound No description 4 HOUSEKEEPING_MANAGER fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
373 0x3e05 HKM_DatasetNotFound No description 5 HOUSEKEEPING_MANAGER fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
374 0x3f01 DLEE_StreamTooShort DLEE_NoPacketFound No description 1 DLE_ENCODER fsfw/src/fsfw/globalfunctions/DleEncoder.h fsfw/src/fsfw/globalfunctions/DleParser.h
375 0x3f02 DLEE_DecodingError DLEE_PossiblePacketLoss No description 2 DLE_ENCODER fsfw/src/fsfw/globalfunctions/DleEncoder.h fsfw/src/fsfw/globalfunctions/DleParser.h
376 0x4201 PUS11_InvalidTypeTimeWindow No description 1 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
377 0x4202 PUS11_InvalidTimeWindow No description 2 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
378 0x4203 PUS11_TimeshiftingNotPossible No description 3 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
402 0x4403 UXOS_CommandError Command execution failed 3 LINUX_OSAL fsfw/src/fsfw_hal/linux/CommandExecutor.h
403 0x4404 UXOS_NoCommandLoadedOrPending 4 LINUX_OSAL fsfw/src/fsfw_hal/linux/CommandExecutor.h
404 0x4406 UXOS_PcloseCallError No description 6 LINUX_OSAL fsfw/src/fsfw_hal/linux/CommandExecutor.h
405 0x4500 HSPI_HalTimeoutRetval HSPI_OpeningFileFailed No description 0 HAL_SPI fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
406 0x4501 HSPI_HalBusyRetval HSPI_FullDuplexTransferFailed No description 1 HAL_SPI fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
407 0x4502 HSPI_HalErrorRetval HSPI_HalfDuplexTransferFailed No description 2 HAL_SPI fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
408 0x4601 HURT_UartReadFailure No description 1 HAL_UART fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
409 0x4602 HURT_UartReadSizeMissmatch No description 2 HAL_UART fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
410 0x4603 HURT_UartRxBufferTooSmall No description 3 HAL_UART fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
415 0x4805 HGIO_GpioDuplicateDetected No description 5 HAL_GPIO fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
416 0x4806 HGIO_GpioInitFailed No description 6 HAL_GPIO fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
417 0x4807 HGIO_GpioGetValueFailed No description 7 HAL_GPIO fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
0x4aa0 MGMLIS3_InvalidSpeed Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] 160 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa1 MGMLIS3_InvalidRampTime Action Message with invalid ramp time was received. 161 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa2 MGMLIS3_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa3 MGMLIS3_ExecutionFailed Command execution failed 163 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa4 MGMLIS3_CrcError Reaction wheel reply has invalid crc 164 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa5 MGMLIS3_ValueNotRead No description 165 MGM_LIS3MDL mission/acs/RwHandler.h
418 0x4c00 SPPA_NoPacketFound No description 0 SPACE_PACKET_PARSER fsfw/src/fsfw/tmtcservices/SpacePacketParser.h
419 0x4c01 SPPA_SplitPacket No description 1 SPACE_PACKET_PARSER fsfw/src/fsfw/tmtcservices/SpacePacketParser.h
420 0x4fa1 HEATER_CommandNotSupported No description 161 HEATER_HANDLER mission/tcs/HeaterHandler.h
474 0x53b6 STRH_StartrackerAlreadyBooted Star tracker is already in firmware mode 182 STR_HANDLER mission/acs/str/StarTrackerHandler.h
475 0x53b7 STRH_StartrackerNotRunningFirmware Star tracker must be in firmware mode to run this command 183 STR_HANDLER mission/acs/str/StarTrackerHandler.h
476 0x53b8 STRH_StartrackerNotRunningBootloader Star tracker must be in bootloader mode to run this command 184 STR_HANDLER mission/acs/str/StarTrackerHandler.h
477 0x58a0 SUSS_ErrorUnlockMutex SUSS_InvalidSpeed No description Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] 160 SUS_HANDLER mission/acs/archive/LegacySusHandler.h mission/acs/RwHandler.h
478 0x58a1 SUSS_ErrorLockMutex SUSS_InvalidRampTime No description Action Message with invalid ramp time was received. 161 SUS_HANDLER mission/acs/archive/LegacySusHandler.h mission/acs/RwHandler.h
479 0x58a2 SUSS_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 SUS_HANDLER mission/acs/RwHandler.h
480 0x58a3 SUSS_ExecutionFailed Command execution failed 163 SUS_HANDLER mission/acs/RwHandler.h
481 0x58a4 SUSS_CrcError Reaction wheel reply has invalid crc 164 SUS_HANDLER mission/acs/RwHandler.h
482 0x58a5 SUSS_ValueNotRead No description 165 SUS_HANDLER mission/acs/RwHandler.h
483 0x5d00 GOMS_PacketTooLong No description 0 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h
484 0x5d01 GOMS_InvalidTableId No description 1 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h
485 0x5d02 GOMS_InvalidAddress No description 2 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h

View File

@ -203,6 +203,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12801;0x3201;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/AcsBoardAssembly.h
12802;0x3202;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/AcsBoardAssembly.h
12803;0x3203;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/AcsBoardAssembly.h
12804;0x3204;DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY;MEDIUM;This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode.;mission/system/acs/AcsBoardAssembly.h
12900;0x3264;TRANSITION_OTHER_SIDE_FAILED;HIGH;No description;mission/system/acs/SusAssembly.h
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
@ -266,14 +267,19 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14104;0x3718;OBC_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
14301;0x37dd;FILE_TOO_LARGE;LOW;File in store too large. P1: Detected file size P2: Allowed file size;mission/persistentTmStoreDefs.h
14302;0x37de;BUSY_DUMPING_EVENT;INFO;No description;mission/persistentTmStoreDefs.h
14303;0x37df;DUMP_WAS_CANCELLED;LOW;Dump was cancelled. P1: Object ID of store.;mission/persistentTmStoreDefs.h
14305;0x37e1;DUMP_OK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14306;0x37e2;DUMP_NOK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14307;0x37e3;DUMP_MISC_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14308;0x37e4;DUMP_HK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14309;0x37e5;DUMP_CFDP_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14310;0x37e6;DUMP_OK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14311;0x37e7;DUMP_NOK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14312;0x37e8;DUMP_MISC_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
203 12801 0x3201 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/AcsBoardAssembly.h
204 12802 0x3202 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/AcsBoardAssembly.h
205 12803 0x3203 SIDE_SWITCH_TRANSITION_NOT_ALLOWED LOW Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination mission/system/acs/AcsBoardAssembly.h
206 12804 0x3204 DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY MEDIUM This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode. mission/system/acs/AcsBoardAssembly.h
207 12900 0x3264 TRANSITION_OTHER_SIDE_FAILED HIGH No description mission/system/acs/SusAssembly.h
208 12901 0x3265 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/SusAssembly.h
209 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
267 14104 0x3718 OBC_OVERHEATING HIGH No description mission/controller/tcsDefs.h
268 14105 0x3719 CAMERA_OVERHEATING HIGH No description mission/controller/tcsDefs.h
269 14106 0x371a PCDU_SYSTEM_OVERHEATING HIGH No description mission/controller/tcsDefs.h
270 14107 0x371b HEATER_NOT_OFF_FOR_OFF_MODE MEDIUM No description mission/controller/tcsDefs.h
271 14201 0x3779 TX_TIMER_EXPIRED INFO The transmit timer to protect the Syrlinks expired P1: The current timer value mission/system/com/ComSubsystem.h
272 14202 0x377a BIT_LOCK_TX_ON INFO Transmitter will be turned on due to detection of bitlock mission/system/com/ComSubsystem.h
273 14300 0x37dc POSSIBLE_FILE_CORRUPTION LOW P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp. mission/persistentTmStoreDefs.h
274 14301 0x37dd FILE_TOO_LARGE LOW File in store too large. P1: Detected file size P2: Allowed file size mission/persistentTmStoreDefs.h
275 14302 0x37de BUSY_DUMPING_EVENT INFO No description mission/persistentTmStoreDefs.h
14303 0x37df DUMP_WAS_CANCELLED LOW Dump was cancelled. P1: Object ID of store. mission/persistentTmStoreDefs.h
276 14305 0x37e1 DUMP_OK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
277 14306 0x37e2 DUMP_NOK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
278 14307 0x37e3 DUMP_MISC_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
279 14308 0x37e4 DUMP_HK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
280 14309 0x37e5 DUMP_CFDP_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
281 14310 0x37e6 DUMP_OK_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
282 14311 0x37e7 DUMP_NOK_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
283 14312 0x37e8 DUMP_MISC_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
284 14313 0x37e9 DUMP_HK_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
285 14314 0x37ea DUMP_CFDP_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h

View File

@ -29,6 +29,8 @@
0x44120350;RW4
0x44130001;STAR_TRACKER
0x44130045;GPS_CONTROLLER
0x44130046;GPS_0_HEALTH_DEV
0x44130047;GPS_1_HEALTH_DEV
0x44140013;IMTQ_POLLING
0x44140014;IMTQ_HANDLER
0x442000A1;PCDU_HANDLER

1 0x00005060 P60DOCK_TEST_TASK
29 0x44120350 RW4
30 0x44130001 STAR_TRACKER
31 0x44130045 GPS_CONTROLLER
32 0x44130046 GPS_0_HEALTH_DEV
33 0x44130047 GPS_1_HEALTH_DEV
34 0x44140013 IMTQ_POLLING
35 0x44140014 IMTQ_HANDLER
36 0x442000A1 PCDU_HANDLER

View File

@ -291,8 +291,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x2e02;HPA_InvalidDomainId;No description;2;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h
0x2e03;HPA_InvalidValue;No description;3;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h
0x2e05;HPA_ReadOnly;No description;5;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h
0x2f01;ASC_NoPacketFound;No description;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/DleParser.h
0x2f02;ASC_PossiblePacketLoss;No description;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/DleParser.h
0x2f01;ASC_TooLongForTargetType;No description;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h
0x2f02;ASC_InvalidCharacters;No description;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h
0x2f03;ASC_BufferTooSmall;No description;3;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h
0x3001;POS_InPowerTransition;No description;1;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h
0x3002;POS_SwitchStateMismatch;No description;2;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h
@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
@ -402,9 +402,9 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
0x4500;HSPI_HalTimeoutRetval;No description;0;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h
0x4501;HSPI_HalBusyRetval;No description;1;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h
0x4502;HSPI_HalErrorRetval;No description;2;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
@ -415,12 +415,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x4805;HGIO_GpioDuplicateDetected;No description;5;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
0x4806;HGIO_GpioInitFailed;No description;6;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
0x4807;HGIO_GpioGetValueFailed;No description;7;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
0x4aa0;MGMLIS3_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa1;MGMLIS3_InvalidRampTime;Action Message with invalid ramp time was received.;161;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa2;MGMLIS3_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa3;MGMLIS3_ExecutionFailed;Command execution failed;163;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa4;MGMLIS3_CrcError;Reaction wheel reply has invalid crc;164;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4aa5;MGMLIS3_ValueNotRead;No description;165;MGM_LIS3MDL;mission/acs/RwHandler.h
0x4c00;SPPA_NoPacketFound;No description;0;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h
0x4c01;SPPA_SplitPacket;No description;1;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h
0x4fa1;HEATER_CommandNotSupported;No description;161;HEATER_HANDLER;mission/tcs/HeaterHandler.h
@ -492,12 +486,16 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x57a1;PLSPVhLP_ProcessTerminated;Process has been terminated by command;161;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
0x57a2;PLSPVhLP_PathNotExists;Received command with invalid pathname;162;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
0x57a3;PLSPVhLP_EventBufferReplyInvalidApid;Expected event buffer TM but received space packet with other APID;163;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
0x58a0;SUSS_ErrorUnlockMutex;No description;160;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x58a1;SUSS_ErrorLockMutex;No description;161;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x58a0;SUSS_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;SUS_HANDLER;mission/acs/RwHandler.h
0x58a1;SUSS_InvalidRampTime;Action Message with invalid ramp time was received.;161;SUS_HANDLER;mission/acs/RwHandler.h
0x58a2;SUSS_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;SUS_HANDLER;mission/acs/RwHandler.h
0x58a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h
0x58a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h
0x58a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h
0x5900;IPCI_NoReplyAvailable;No description;0;CCSDS_IP_CORE_BRIDGE;linux/acs/ImtqPollingTask.h
0x5901;IPCI_NoPacketFound;No description;1;CCSDS_IP_CORE_BRIDGE;linux/com/SyrlinksComHandler.h
0x59a0;IPCI_PapbBusy;No description;160;CCSDS_IP_CORE_BRIDGE;linux/ipcore/PapbVcInterface.h
0x5aa0;PTME_UnknownVcId;No description;160;PTME;linux/ipcore/Ptme.h
0x5c00;STRHLP_NoReplyAvailable;No description;0;STR_HELPER;linux/acs/ImtqPollingTask.h
0x5c01;STRHLP_SdNotMounted;SD card specified in path string not mounted;1;STR_HELPER;linux/acs/StrComHandler.h
0x5c02;STRHLP_FileNotExists;Specified file does not exist on filesystem;2;STR_HELPER;linux/acs/StrComHandler.h
0x5c03;STRHLP_PathNotExists;Specified path does not exist;3;STR_HELPER;linux/acs/StrComHandler.h
@ -515,7 +513,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x5d03;GOMS_InvalidParamSize;No description;3;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
0x5d04;GOMS_InvalidPayloadSize;No description;4;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
0x5d05;GOMS_UnknownReplyId;No description;5;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
0x5e02;PLMEMDUMP_InvalidCrc;No description;2;PLOC_MEMORY_DUMPER;linux/payload/ScexHelper.h
0x5ea0;PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;160;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
0x5ea1;PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;161;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/PdecHandler.h
@ -544,6 +541,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
0x64a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;160;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
0x64a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;161;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
0x6502;PLMPHLP_InvalidCrc;No description;2;PLOC_MPSOC_HELPER;linux/payload/ScexHelper.h
0x65a0;PLMPHLP_FileClosedAccidentally;File accidentally close;160;PLOC_MPSOC_HELPER;linux/payload/PlocMpsocHelper.h
0x66a0;SADPL_CommandNotSupported;No description;160;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x66a1;SADPL_DeploymentAlreadyExecuting;No description;161;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
291 0x2e02 HPA_InvalidDomainId No description 2 HAS_PARAMETERS_IF fsfw/src/fsfw/parameters/HasParametersIF.h
292 0x2e03 HPA_InvalidValue No description 3 HAS_PARAMETERS_IF fsfw/src/fsfw/parameters/HasParametersIF.h
293 0x2e05 HPA_ReadOnly No description 5 HAS_PARAMETERS_IF fsfw/src/fsfw/parameters/HasParametersIF.h
294 0x2f01 ASC_NoPacketFound ASC_TooLongForTargetType No description 1 ASCII_CONVERTER fsfw/src/fsfw/globalfunctions/DleParser.h fsfw/src/fsfw/globalfunctions/AsciiConverter.h
295 0x2f02 ASC_PossiblePacketLoss ASC_InvalidCharacters No description 2 ASCII_CONVERTER fsfw/src/fsfw/globalfunctions/DleParser.h fsfw/src/fsfw/globalfunctions/AsciiConverter.h
296 0x2f03 ASC_BufferTooSmall No description 3 ASCII_CONVERTER fsfw/src/fsfw/globalfunctions/AsciiConverter.h
297 0x3001 POS_InPowerTransition No description 1 POWER_SWITCHER fsfw/src/fsfw/power/PowerSwitcher.h
298 0x3002 POS_SwitchStateMismatch No description 2 POWER_SWITCHER fsfw/src/fsfw/power/PowerSwitcher.h
371 0x3e03 HKM_PeriodicHelperInvalid No description 3 HOUSEKEEPING_MANAGER fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
372 0x3e04 HKM_PoolobjectNotFound No description 4 HOUSEKEEPING_MANAGER fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
373 0x3e05 HKM_DatasetNotFound No description 5 HOUSEKEEPING_MANAGER fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
374 0x3f01 DLEE_StreamTooShort DLEE_NoPacketFound No description 1 DLE_ENCODER fsfw/src/fsfw/globalfunctions/DleEncoder.h fsfw/src/fsfw/globalfunctions/DleParser.h
375 0x3f02 DLEE_DecodingError DLEE_PossiblePacketLoss No description 2 DLE_ENCODER fsfw/src/fsfw/globalfunctions/DleEncoder.h fsfw/src/fsfw/globalfunctions/DleParser.h
376 0x4201 PUS11_InvalidTypeTimeWindow No description 1 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
377 0x4202 PUS11_InvalidTimeWindow No description 2 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
378 0x4203 PUS11_TimeshiftingNotPossible No description 3 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
402 0x4403 UXOS_CommandError Command execution failed 3 LINUX_OSAL fsfw/src/fsfw_hal/linux/CommandExecutor.h
403 0x4404 UXOS_NoCommandLoadedOrPending 4 LINUX_OSAL fsfw/src/fsfw_hal/linux/CommandExecutor.h
404 0x4406 UXOS_PcloseCallError No description 6 LINUX_OSAL fsfw/src/fsfw_hal/linux/CommandExecutor.h
405 0x4500 HSPI_HalTimeoutRetval HSPI_OpeningFileFailed No description 0 HAL_SPI fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
406 0x4501 HSPI_HalBusyRetval HSPI_FullDuplexTransferFailed No description 1 HAL_SPI fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
407 0x4502 HSPI_HalErrorRetval HSPI_HalfDuplexTransferFailed No description 2 HAL_SPI fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
408 0x4601 HURT_UartReadFailure No description 1 HAL_UART fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
409 0x4602 HURT_UartReadSizeMissmatch No description 2 HAL_UART fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
410 0x4603 HURT_UartRxBufferTooSmall No description 3 HAL_UART fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
415 0x4805 HGIO_GpioDuplicateDetected No description 5 HAL_GPIO fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
416 0x4806 HGIO_GpioInitFailed No description 6 HAL_GPIO fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
417 0x4807 HGIO_GpioGetValueFailed No description 7 HAL_GPIO fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h
0x4aa0 MGMLIS3_InvalidSpeed Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] 160 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa1 MGMLIS3_InvalidRampTime Action Message with invalid ramp time was received. 161 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa2 MGMLIS3_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa3 MGMLIS3_ExecutionFailed Command execution failed 163 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa4 MGMLIS3_CrcError Reaction wheel reply has invalid crc 164 MGM_LIS3MDL mission/acs/RwHandler.h
0x4aa5 MGMLIS3_ValueNotRead No description 165 MGM_LIS3MDL mission/acs/RwHandler.h
418 0x4c00 SPPA_NoPacketFound No description 0 SPACE_PACKET_PARSER fsfw/src/fsfw/tmtcservices/SpacePacketParser.h
419 0x4c01 SPPA_SplitPacket No description 1 SPACE_PACKET_PARSER fsfw/src/fsfw/tmtcservices/SpacePacketParser.h
420 0x4fa1 HEATER_CommandNotSupported No description 161 HEATER_HANDLER mission/tcs/HeaterHandler.h
486 0x57a1 PLSPVhLP_ProcessTerminated Process has been terminated by command 161 PLOC_SUPV_HELPER linux/payload/PlocSupvUartMan.h
487 0x57a2 PLSPVhLP_PathNotExists Received command with invalid pathname 162 PLOC_SUPV_HELPER linux/payload/PlocSupvUartMan.h
488 0x57a3 PLSPVhLP_EventBufferReplyInvalidApid Expected event buffer TM but received space packet with other APID 163 PLOC_SUPV_HELPER linux/payload/PlocSupvUartMan.h
489 0x58a0 SUSS_ErrorUnlockMutex SUSS_InvalidSpeed No description Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] 160 SUS_HANDLER mission/acs/archive/LegacySusHandler.h mission/acs/RwHandler.h
490 0x58a1 SUSS_ErrorLockMutex SUSS_InvalidRampTime No description Action Message with invalid ramp time was received. 161 SUS_HANDLER mission/acs/archive/LegacySusHandler.h mission/acs/RwHandler.h
491 0x58a2 SUSS_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 SUS_HANDLER mission/acs/RwHandler.h
492 0x58a3 SUSS_ExecutionFailed Command execution failed 163 SUS_HANDLER mission/acs/RwHandler.h
493 0x58a4 SUSS_CrcError Reaction wheel reply has invalid crc 164 SUS_HANDLER mission/acs/RwHandler.h
494 0x58a5 SUSS_ValueNotRead No description 165 SUS_HANDLER mission/acs/RwHandler.h
495 0x5900 IPCI_NoReplyAvailable No description 0 CCSDS_IP_CORE_BRIDGE linux/acs/ImtqPollingTask.h
496 0x5901 IPCI_NoPacketFound No description 1 CCSDS_IP_CORE_BRIDGE linux/com/SyrlinksComHandler.h
497 0x59a0 IPCI_PapbBusy No description 160 CCSDS_IP_CORE_BRIDGE linux/ipcore/PapbVcInterface.h
498 0x5aa0 PTME_UnknownVcId No description 160 PTME linux/ipcore/Ptme.h
0x5c00 STRHLP_NoReplyAvailable No description 0 STR_HELPER linux/acs/ImtqPollingTask.h
499 0x5c01 STRHLP_SdNotMounted SD card specified in path string not mounted 1 STR_HELPER linux/acs/StrComHandler.h
500 0x5c02 STRHLP_FileNotExists Specified file does not exist on filesystem 2 STR_HELPER linux/acs/StrComHandler.h
501 0x5c03 STRHLP_PathNotExists Specified path does not exist 3 STR_HELPER linux/acs/StrComHandler.h
513 0x5d03 GOMS_InvalidParamSize No description 3 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h
514 0x5d04 GOMS_InvalidPayloadSize No description 4 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h
515 0x5d05 GOMS_UnknownReplyId No description 5 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h
0x5e02 PLMEMDUMP_InvalidCrc No description 2 PLOC_MEMORY_DUMPER linux/payload/ScexHelper.h
516 0x5ea0 PLMEMDUMP_MramAddressTooHigh The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000. 160 PLOC_MEMORY_DUMPER linux/payload/PlocMemoryDumper.h
517 0x5ea1 PLMEMDUMP_MramInvalidAddressCombination The specified end address is lower than the start address 161 PLOC_MEMORY_DUMPER linux/payload/PlocMemoryDumper.h
518 0x5fa0 PDEC_AbandonedCltuRetval No description 160 PDEC_HANDLER linux/ipcore/PdecHandler.h
541 0x63a0 NVMB_KeyNotExists Specified key does not exist in json file 160 NVM_PARAM_BASE mission/memory/NvmParameterBase.h
542 0x64a0 FSHLP_SdNotMounted SD card specified with path string not mounted 160 FILE_SYSTEM_HELPER bsp_q7s/fs/FilesystemHelper.h
543 0x64a1 FSHLP_FileNotExists Specified file does not exist on filesystem 161 FILE_SYSTEM_HELPER bsp_q7s/fs/FilesystemHelper.h
544 0x6502 PLMPHLP_InvalidCrc No description 2 PLOC_MPSOC_HELPER linux/payload/ScexHelper.h
545 0x65a0 PLMPHLP_FileClosedAccidentally File accidentally close 160 PLOC_MPSOC_HELPER linux/payload/PlocMpsocHelper.h
546 0x66a0 SADPL_CommandNotSupported No description 160 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
547 0x66a1 SADPL_DeploymentAlreadyExecuting No description 161 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 278 translations.
* @brief Auto-generated event translation file. Contains 284 translations.
* @details
* Generated on: 2023-03-26 16:47:32
* Generated on: 2023-03-31 19:17:49
*/
#include "translateEvents.h"
@ -209,6 +209,7 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED"
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE";
const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED";
const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY";
const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900";
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901";
const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902";
@ -272,17 +273,22 @@ const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE";
const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT";
const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED";
const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE";
const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE";
const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE";
const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE";
const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE";
const char *DUMP_OK_CANCELLED_STRING = "DUMP_OK_CANCELLED";
const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED";
const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED";
const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED";
const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED";
const char *translateEvents(Event event) {
switch ((event & 0xFFFF)) {
@ -694,6 +700,8 @@ const char *translateEvents(Event event) {
return POWER_STATE_MACHINE_TIMEOUT_STRING;
case (12803):
return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING;
case (12804):
return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING;
case (12900):
return TRANSITION_OTHER_SIDE_FAILED_12900_STRING;
case (12901):
@ -820,6 +828,8 @@ const char *translateEvents(Event event) {
return CAMERA_OVERHEATING_STRING;
case (14106):
return PCDU_SYSTEM_OVERHEATING_STRING;
case (14107):
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
case (14201):
return TX_TIMER_EXPIRED_STRING;
case (14202):
@ -830,8 +840,6 @@ const char *translateEvents(Event event) {
return FILE_TOO_LARGE_STRING;
case (14302):
return BUSY_DUMPING_EVENT_STRING;
case (14303):
return DUMP_WAS_CANCELLED_STRING;
case (14305):
return DUMP_OK_STORE_DONE_STRING;
case (14306):
@ -842,6 +850,16 @@ const char *translateEvents(Event event) {
return DUMP_HK_STORE_DONE_STRING;
case (14309):
return DUMP_CFDP_STORE_DONE_STRING;
case (14310):
return DUMP_OK_CANCELLED_STRING;
case (14311):
return DUMP_NOK_CANCELLED_STRING;
case (14312):
return DUMP_MISC_CANCELLED_STRING;
case (14313):
return DUMP_HK_CANCELLED_STRING;
case (14314):
return DUMP_CFDP_CANCELLED_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 173 translations.
* Generated on: 2023-03-26 16:47:32
* Contains 175 translations.
* Generated on: 2023-03-31 19:17:49
*/
#include "translateObjects.h"
@ -37,6 +37,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
const char *RW4_STRING = "RW4";
const char *STAR_TRACKER_STRING = "STAR_TRACKER";
const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER";
const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV";
const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV";
const char *IMTQ_POLLING_STRING = "IMTQ_POLLING";
const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER";
const char *PCDU_HANDLER_STRING = "PCDU_HANDLER";
@ -244,6 +246,10 @@ const char *translateObject(object_id_t object) {
return STAR_TRACKER_STRING;
case 0x44130045:
return GPS_CONTROLLER_STRING;
case 0x44130046:
return GPS_0_HEALTH_DEV_STRING;
case 0x44130047:
return GPS_1_HEALTH_DEV_STRING;
case 0x44140013:
return IMTQ_POLLING_STRING;
case 0x44140014:

View File

@ -99,6 +99,7 @@ void GpsHyperionLinuxController::setResetPinTriggerFunction(gpioResetFunction_t
ReturnValue_t GpsHyperionLinuxController::performOperation(uint8_t opCode) {
handleQueue();
poolManager.performHkOperation();
while (true) {
#if OBSW_THREAD_TRACING == 1
trace::threadTrace(opCounter, "GPS CTRL");

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 278 translations.
* @brief Auto-generated event translation file. Contains 284 translations.
* @details
* Generated on: 2023-03-26 16:47:32
* Generated on: 2023-03-31 19:17:49
*/
#include "translateEvents.h"
@ -209,11 +209,11 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED"
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE";
const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED";
const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY";
const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900";
const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901";
const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING =
"SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903";
const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903";
const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE";
const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE";
const char *CANT_GET_FIX_STRING = "CANT_GET_FIX";
@ -273,17 +273,22 @@ const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE";
const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT";
const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED";
const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE";
const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE";
const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE";
const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE";
const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE";
const char *DUMP_OK_CANCELLED_STRING = "DUMP_OK_CANCELLED";
const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED";
const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED";
const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED";
const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED";
const char *translateEvents(Event event) {
switch ((event & 0xFFFF)) {
@ -695,6 +700,8 @@ const char *translateEvents(Event event) {
return POWER_STATE_MACHINE_TIMEOUT_STRING;
case (12803):
return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING;
case (12804):
return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING;
case (12900):
return TRANSITION_OTHER_SIDE_FAILED_12900_STRING;
case (12901):
@ -821,6 +828,8 @@ const char *translateEvents(Event event) {
return CAMERA_OVERHEATING_STRING;
case (14106):
return PCDU_SYSTEM_OVERHEATING_STRING;
case (14107):
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
case (14201):
return TX_TIMER_EXPIRED_STRING;
case (14202):
@ -831,8 +840,6 @@ const char *translateEvents(Event event) {
return FILE_TOO_LARGE_STRING;
case (14302):
return BUSY_DUMPING_EVENT_STRING;
case (14303):
return DUMP_WAS_CANCELLED_STRING;
case (14305):
return DUMP_OK_STORE_DONE_STRING;
case (14306):
@ -843,6 +850,16 @@ const char *translateEvents(Event event) {
return DUMP_HK_STORE_DONE_STRING;
case (14309):
return DUMP_CFDP_STORE_DONE_STRING;
case (14310):
return DUMP_OK_CANCELLED_STRING;
case (14311):
return DUMP_NOK_CANCELLED_STRING;
case (14312):
return DUMP_MISC_CANCELLED_STRING;
case (14313):
return DUMP_HK_CANCELLED_STRING;
case (14314):
return DUMP_CFDP_CANCELLED_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 173 translations.
* Generated on: 2023-03-26 16:47:32
* Contains 175 translations.
* Generated on: 2023-03-31 19:17:49
*/
#include "translateObjects.h"
@ -37,6 +37,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER";
const char *RW4_STRING = "RW4";
const char *STAR_TRACKER_STRING = "STAR_TRACKER";
const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER";
const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV";
const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV";
const char *IMTQ_POLLING_STRING = "IMTQ_POLLING";
const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER";
const char *PCDU_HANDLER_STRING = "PCDU_HANDLER";
@ -244,6 +246,10 @@ const char *translateObject(object_id_t object) {
return STAR_TRACKER_STRING;
case 0x44130045:
return GPS_CONTROLLER_STRING;
case 0x44130046:
return GPS_0_HEALTH_DEV_STRING;
case 0x44130047:
return GPS_1_HEALTH_DEV_STRING;
case 0x44140013:
return IMTQ_POLLING_STRING;
case 0x44140014:

View File

@ -2,6 +2,9 @@
#include <linux/ipcore/PapbVcInterface.h>
#include <unistd.h>
#include <cstring>
#include <ctime>
#include "fsfw/serviceinterface/ServiceInterface.h"
PapbVcInterface::PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId,
@ -16,30 +19,71 @@ PapbVcInterface::~PapbVcInterface() {}
ReturnValue_t PapbVcInterface::initialize() {
UioMapper uioMapper(uioFile, mapNum);
uint32_t* baseReg;
ReturnValue_t result = uioMapper.getMappedAdress(&baseReg, UioMapper::Permissions::WRITE_ONLY);
ReturnValue_t result = uioMapper.getMappedAdress(const_cast<uint32_t**>(&vcBaseReg),
UioMapper::Permissions::WRITE_ONLY);
if (result != returnvalue::OK) {
return result;
}
vcBaseReg = baseReg;
return returnvalue::OK;
}
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
if (pollPapbBusySignal(0, 0) == returnvalue::OK) {
startPacketTransfer();
// There are no packets smaller than 4, this is considered a configuration error.
if (size < 4) {
return returnvalue::FAILED;
}
if (pollInterfaceReadiness(0, true) == returnvalue::OK) {
startPacketTransfer(ByteWidthCfg::ONE);
} else {
return DirectTmSinkIF::IS_BUSY;
}
// TODO: This should work but does not.. :(
// size_t idx = 0;
// while (idx < size) {
//
// nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
// if ((size - idx) < 4) {
// *vcBaseReg = CONFIG_DATA_INPUT | (size - idx - 1);
// usleep(1);
// }
// if (pollPapbBusySignal(2) == returnvalue::OK) {
// // vcBaseReg + DATA_REG_OFFSET + 3 = static_cast<uint8_t>(data + idx);
// // vcBaseReg + DATA_REG_OFFSET + 2 = static_cast<uint8_t>(data + idx + 1);
// // vcBaseReg + DATA_REG_OFFSET + 1 = static_cast<uint8_t>(data + idx + 2);
// // vcBaseReg + DATA_REG_OFFSET = static_cast<uint8_t>(data + idx + 3);
//
// // std::memcpy((vcBaseReg + DATA_REG_OFFSET), data + idx , nextWriteSize);
// *(vcBaseReg + DATA_REG_OFFSET) = *reinterpret_cast<const uint32_t*>(data + idx);
// //uint8_t* byteReg = reinterpret_cast<uint8_t*>(vcBaseReg + DATA_REG_OFFSET);
//
// //byteReg[0] = data[idx];
// //byteReg[1] = data[idx];
// } else {
// abortPacketTransfer();
// return returnvalue::FAILED;
// }
// // TODO: Change this after the bugfix. Right now, the PAPB ignores the content of the byte
// // width configuration.5
// // It's okay to increment by a larger amount for the last segment here, loop will be over
// // in any case.
// idx += 4;
// }
for (size_t idx = 0; idx < size; idx++) {
if (pollPapbBusySignal(10, 10) == returnvalue::OK) {
// This delay is super-important, DO NOT REMOVE!
// Polling the GPIO or the config register too often messes up the scheduler.
// TODO: Maybe this should not be done like this. It would be better if there was a custom
// FPGA module which can accept packets and then takes care of dumping that packet into
// the PTME. DMA would be an ideal solution for this.
nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
if (pollInterfaceReadiness(2, false) == returnvalue::OK) {
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[idx]);
} else {
abortPacketTransfer();
return returnvalue::FAILED;
}
}
if (pollPapbBusySignal(10, 10) == returnvalue::OK) {
nanosleep(&BETWEEN_POLL_DELAY, &remDelay);
if (pollInterfaceReadiness(2, false) == returnvalue::OK) {
completePacketTransfer();
} else {
abortPacketTransfer();
@ -48,34 +92,41 @@ ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
return returnvalue::OK;
}
void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; }
void PapbVcInterface::startPacketTransfer(ByteWidthCfg initWidth) {
*vcBaseReg = CONFIG_DATA_INPUT | initWidth;
}
void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; }
ReturnValue_t PapbVcInterface::pollPapbBusySignal(uint32_t maxPollRetries,
uint32_t retryDelayUs) const {
gpio::Levels papbBusyState = gpio::Levels::LOW;
ReturnValue_t result;
ReturnValue_t PapbVcInterface::pollInterfaceReadiness(uint32_t maxPollRetries,
bool checkReadyState) const {
uint32_t busyIdx = 0;
nextDelay.tv_nsec = FIRST_DELAY_PAPB_POLLING_NS;
while (true) {
/** Check if PAPB interface is ready to receive data */
result = gpioComIF->readGpio(papbBusyId, papbBusyState);
if (result != returnvalue::OK) {
sif::warning << "PapbVcInterface::pollPapbBusySignal: Failed to read papb busy signal"
<< std::endl;
return returnvalue::FAILED;
}
if (papbBusyState == gpio::Levels::HIGH) {
// Check if PAPB interface is ready to receive data. Use the configuration register for this.
// Bit 5, see PTME ptme_001_01-0-7-r2 Table 31.
uint32_t reg = *vcBaseReg;
bool busy = (reg >> 5) & 0b1;
bool ready = (reg >> 6) & 0b1;
if (not busy) {
return returnvalue::OK;
}
if (checkReadyState and not ready) {
return PAPB_BUSY;
}
busyIdx++;
if (busyIdx >= maxPollRetries) {
return PAPB_BUSY;
}
usleep(retryDelayUs);
// Ignore signal handling here for now.
nanosleep(&nextDelay, &remDelay);
// Adaptive delay.
if (nextDelay.tv_nsec * 2 <= MAX_DELAY_PAPB_POLLING_NS) {
nextDelay.tv_nsec *= 2;
}
}
return returnvalue::OK;
}
@ -100,7 +151,7 @@ void PapbVcInterface::isVcInterfaceBufferEmpty() {
return;
}
bool PapbVcInterface::isBusy() const { return pollPapbBusySignal(0, 0) == PAPB_BUSY; }
bool PapbVcInterface::isBusy() const { return pollInterfaceReadiness(0, true) == PAPB_BUSY; }
void PapbVcInterface::cancelTransfer() { abortPacketTransfer(); }

View File

@ -5,6 +5,8 @@
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include <linux/ipcore/VirtualChannelIF.h>
#include <atomic>
#include "OBSWConfig.h"
#include "fsfw/returnvalues/returnvalue.h"
@ -50,13 +52,14 @@ class PapbVcInterface : public VirtualChannelIF {
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
enum ByteWidthCfg : uint32_t { ONE = 0b00, TWO = 0b01, THREE = 0b10, FOUR = 0b11 };
/**
* Configuration bits:
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
* bit[2]: Set this bit to 1 to abort a transferred packet
* bit[3]: Signals to VcInterface the start of a new telemetry packet
*/
static constexpr uint32_t CONFIG_START = 0b00001000;
static constexpr uint32_t CONFIG_DATA_INPUT = 0b00001000;
/**
* Abort a transferred packet.
@ -76,6 +79,9 @@ class PapbVcInterface : public VirtualChannelIF {
*/
static const int DATA_REG_OFFSET = 256;
static constexpr long int FIRST_DELAY_PAPB_POLLING_NS = 10;
static constexpr long int MAX_DELAY_PAPB_POLLING_NS = 40;
LinuxLibgpioIF* gpioComIF = nullptr;
/** Pulled to low when virtual channel not ready to receive data */
@ -85,6 +91,9 @@ class PapbVcInterface : public VirtualChannelIF {
std::string uioFile;
int mapNum = 0;
mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0};
const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 10};
mutable struct timespec remDelay;
volatile uint32_t* vcBaseReg = nullptr;
@ -94,7 +103,7 @@ class PapbVcInterface : public VirtualChannelIF {
* @brief This function sends the config byte to the virtual channel of the PTME IP Core
* to initiate a packet transfer.
*/
void startPacketTransfer();
void startPacketTransfer(ByteWidthCfg initWidth);
void abortPacketTransfer();
@ -111,7 +120,7 @@ class PapbVcInterface : public VirtualChannelIF {
*
* @return returnvalue::OK when ready to receive data else PAPB_BUSY.
*/
ReturnValue_t pollPapbBusySignal(uint32_t maxPollRetries, uint32_t retryDelayUs) const;
inline ReturnValue_t pollInterfaceReadiness(uint32_t maxPollRetries, bool checkReadyState) const;
/**
* @brief This function can be used for debugging to check whether there are packets in

View File

@ -87,12 +87,11 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem
getMode() == _MODE_POWER_DOWN) {
return IGNORE_FULL_PACKET;
}
*foundLen = remainingSize;
if (remainingSize != sizeof(acs::Adis1650XReply)) {
*foundLen = remainingSize;
return returnvalue::FAILED;
}
*foundId = adis1650x::REPLY;
*foundLen = remainingSize;
if (internalState == InternalState::SHUTDOWN) {
commandExecuted = true;
}

View File

@ -99,12 +99,11 @@ ReturnValue_t GyrL3gCustomHandler::scanForReply(const uint8_t *start, size_t len
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
return IGNORE_FULL_PACKET;
}
*foundLen = len;
if (len != sizeof(acs::GyroL3gReply)) {
*foundLen = len;
return returnvalue::FAILED;
}
*foundId = l3gd20h::REPLY;
*foundLen = len;
*foundId = adis1650x::REPLY;
if (internalState == InternalState::SHUTDOWN) {
commandExecuted = true;
}

View File

@ -1,2 +1,11 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE SyrlinksHandler.cpp
CcsdsIpCoreHandler.cpp)
target_sources(
${LIB_EIVE_MISSION}
PRIVATE SyrlinksHandler.cpp
CcsdsIpCoreHandler.cpp
LiveTmTask.cpp
PersistentLogTmStoreTask.cpp
TmStoreTaskBase.cpp
VirtualChannel.cpp
VirtualChannelWithQueue.cpp
PersistentSingleTmStoreTask.cpp
LiveTmTask.cpp)

View File

@ -15,9 +15,11 @@
CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDestination,
PtmeConfig& ptmeConfig, std::atomic_bool& linkState,
GpioIF* gpioIF, PtmeGpios gpioIds)
GpioIF* gpioIF, PtmeGpios gpioIds,
std::atomic_bool& ptmeLocked)
: SystemObject(objectId),
linkState(linkState),
ptmeLocked(ptmeLocked),
tcDestination(tcDestination),
parameterHelper(this),
actionHelper(this, nullptr),
@ -29,12 +31,14 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t tcDesti
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
eventQueue =
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
ptmeLocked = true;
}
CcsdsIpCoreHandler::~CcsdsIpCoreHandler() = default;
ReturnValue_t CcsdsIpCoreHandler::performOperation(uint8_t operationCode) {
readCommandQueue();
performPtmeUpdateWhenApplicable();
return returnvalue::OK;
}
@ -76,6 +80,8 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() {
} else {
enablePrioritySelectMode();
}
resetPtme();
ptmeLocked = false;
#if OBSW_SYRLINKS_SIMULATED == 1
// Update data on rising edge
@ -127,10 +133,15 @@ ReturnValue_t CcsdsIpCoreHandler::getParameter(uint8_t domainId, uint8_t uniqueI
return HasParametersIF::INVALID_VALUE;
}
parameterWrapper->set(batPriorityParam);
if (mode == MODE_ON) {
updateBatPriorityOnTxOff = true;
} else if (mode == MODE_OFF) {
updateBatPriorityFromParam();
if (newVal != batPriorityParam) {
// This ensures that the BAT priority is updated at some point when an update of the PTME is
// allowed
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;
}
@ -148,36 +159,12 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
const uint8_t* data, size_t size) {
ReturnValue_t result = returnvalue::OK;
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: {
uint32_t bitrate = 0;
SerializeAdapter::deSerialize(&bitrate, &data, &size, SerializeIF::Endianness::BIG);
result = ptmeConfig.setRate(bitrate);
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: {
result = ptmeConfig.configTxManipulator(true);
break;
@ -206,12 +193,8 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
void CcsdsIpCoreHandler::updateLinkState() { linkState = LINK_UP; }
void CcsdsIpCoreHandler::enableTransmit() {
// Reset PTME on each transmit enable.
updateBatPriorityFromParam();
#ifndef TE0720_1CFA
gpioIF->pullHigh(ptmeGpios.enableTxClock);
gpioIF->pullHigh(ptmeGpios.enableTxData);
#endif
linkState = LINK_UP;
}
@ -236,34 +219,23 @@ ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submod
}
void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
auto rateSet = [&](uint32_t rate) {
ReturnValue_t result = ptmeConfig.setRate(rate);
if (result == returnvalue::OK) {
this->mode = HasModesIF::MODE_ON;
}
};
triggerEvent(CHANGING_MODE, mode, submode);
if (mode == HasModesIF::MODE_ON) {
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);
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();
} else if (mode == HasModesIF::MODE_OFF) {
disableTransmit();
this->mode = HasModesIF::MODE_OFF;
}
this->submode = submode;
modeHelper.modeChanged(mode, submode);
announceMode(false);
setMode(mode, submode);
}
void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); }
@ -274,9 +246,9 @@ void CcsdsIpCoreHandler::disableTransmit() {
gpioIF->pullLow(ptmeGpios.enableTxData);
#endif
linkState = LINK_DOWN;
if (updateBatPriorityOnTxOff) {
updateBatPriorityFromParam();
updateBatPriorityOnTxOff = false;
// Some parameters need update and transmitter is off now.
if (updateContext.updateBatPrio or updateContext.updateClockRate) {
initPtmeUpdateAfterXCycles();
}
}
@ -294,21 +266,9 @@ ModeTreeChildIF& CcsdsIpCoreHandler::getModeTreeChildIF() { return *this; }
object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); }
void CcsdsIpCoreHandler::enablePrioritySelectMode() {
ptmeConfig.enableBatPriorityBit(true);
// Reset the PTME
gpioIF->pullLow(ptmeGpios.ptmeResetn);
usleep(10);
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
}
void CcsdsIpCoreHandler::enablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(true); }
void CcsdsIpCoreHandler::disablePrioritySelectMode() {
ptmeConfig.enableBatPriorityBit(false);
// Reset the PTME
gpioIF->pullLow(ptmeGpios.ptmeResetn);
usleep(10);
gpioIF->pullHigh(ptmeGpios.ptmeResetn);
}
void CcsdsIpCoreHandler::disablePrioritySelectMode() { ptmeConfig.enableBatPriorityBit(false); }
void CcsdsIpCoreHandler::updateBatPriorityFromParam() {
if (batPriorityParam == 0) {
@ -317,3 +277,79 @@ void CcsdsIpCoreHandler::updateBatPriorityFromParam() {
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 = returnvalue::OK;
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;
ptmeLocked = true;
}
}
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;
}
}

View File

@ -2,7 +2,7 @@
#define CCSDSHANDLER_H_
#include <fsfw/modes/HasModesIF.h>
#include <mission/tmtc/VirtualChannelWithQueue.h>
#include <mission/com/VirtualChannelWithQueue.h>
#include <cstdint>
#include <unordered_map>
@ -79,7 +79,8 @@ class CcsdsIpCoreHandler : public SystemObject,
* @param enTxData GPIO ID of RS485 tx data enable
*/
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();
@ -137,9 +138,8 @@ class CcsdsIpCoreHandler : public SystemObject,
//! [EXPORT] : [COMMENT] Received action message with unknown action id
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& ptmeLocked;
object_id_t tcDestination;
@ -158,7 +158,15 @@ class CcsdsIpCoreHandler : public SystemObject,
PtmeGpios ptmeGpios;
// BAT priority bit on by default to enable priority selection mode for the PTME.
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;
@ -180,6 +188,8 @@ class CcsdsIpCoreHandler : public SystemObject,
*/
void disableTransmit();
void performPtmeUpdateWhenApplicable();
/**
* The following set of functions configure the mode of the PTME bandwith allocation table (BAT)
* module. This consists of the following 2 steps:
@ -189,6 +199,11 @@ class CcsdsIpCoreHandler : public SystemObject,
void enablePrioritySelectMode();
void disablePrioritySelectMode();
void updateBatPriorityFromParam();
void setMode(Mode_t mode, Submode_t submode);
void resetPtme();
void initPtmeUpdateAfterXCycles();
void finishPtmeUpdateAfterXCycles(bool doResetPtme);
};
#endif /* CCSDSHANDLER_H_ */

107
mission/com/LiveTmTask.cpp Normal file
View File

@ -0,0 +1,107 @@
#include "LiveTmTask.h"
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/subsystem/helper.h>
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked)
: SystemObject(objectId),
modeHelper(this),
pusFunnel(pusFunnel),
cfdpFunnel(cfdpFunnel),
channel(channel),
ptmeLocked(ptmeLocked) {
requestQueue = QueueFactory::instance()->createMessageQueue();
}
ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
readCommandQueue();
while (true) {
bool performWriteOp = true;
if (mode == MODE_OFF or ptmeLocked) {
performWriteOp = false;
}
// The funnel tasks are scheduled here directly as well.
ReturnValue_t result = channel.handleNextTm(performWriteOp);
if (result == DirectTmSinkIF::IS_BUSY) {
sif::error << "Lost live TM, PAPB busy" << std::endl;
}
if (result == MessageQueueIF::EMPTY) {
if (tmFunnelCd.hasTimedOut()) {
pusFunnel.performOperation(0);
cfdpFunnel.performOperation(0);
tmFunnelCd.resetTimer();
}
// Read command queue during idle times.
readCommandQueue();
// 40 ms IDLE delay. Might tweak this in the future.
TaskFactory::delayTask(40);
} else {
packetCounter++;
}
}
}
MessageQueueId_t LiveTmTask::getCommandQueue() const { return requestQueue->getId(); }
void LiveTmTask::getMode(Mode_t* mode, Submode_t* submode) {
if (mode != nullptr) {
*mode = this->mode;
}
if (submode != nullptr) {
*submode = SUBMODE_NONE;
}
}
ReturnValue_t LiveTmTask::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) {
if (mode == MODE_ON or mode == MODE_OFF) {
return returnvalue::OK;
}
return returnvalue::FAILED;
}
void LiveTmTask::startTransition(Mode_t mode, Submode_t submode) {
this->mode = mode;
modeHelper.modeChanged(mode, submode);
announceMode(false);
}
void LiveTmTask::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, SUBMODE_NONE); }
object_id_t LiveTmTask::getObjectId() const { return SystemObject::getObjectId(); }
const HasHealthIF* LiveTmTask::getOptHealthIF() const { return nullptr; }
const HasModesIF& LiveTmTask::getModeIF() const { return *this; }
ReturnValue_t LiveTmTask::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper);
}
void LiveTmTask::readCommandQueue(void) {
CommandMessage commandMessage;
ReturnValue_t result = returnvalue::FAILED;
result = requestQueue->receiveMessage(&commandMessage);
if (result == returnvalue::OK) {
result = modeHelper.handleModeCommand(&commandMessage);
if (result == returnvalue::OK) {
return;
}
CommandMessage reply;
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand());
requestQueue->reply(&reply);
return;
}
}
ModeTreeChildIF& LiveTmTask::getModeTreeChildIF() { return *this; }
ReturnValue_t LiveTmTask::initialize() {
modeHelper.initialize();
return returnvalue::OK;
}

57
mission/com/LiveTmTask.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef MISSION_TMTC_LIVETMTASK_H_
#define MISSION_TMTC_LIVETMTASK_H_
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/subsystem/ModeTreeChildIF.h>
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <mission/com/VirtualChannelWithQueue.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PusTmFunnel.h>
class LiveTmTask : public SystemObject,
public HasModesIF,
public ExecutableObjectIF,
public ModeTreeChildIF,
public ModeTreeConnectionIF {
public:
LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
VirtualChannelWithQueue& channel, const std::atomic_bool& ptmeLocked);
ReturnValue_t performOperation(uint8_t opCode) override;
ReturnValue_t initialize() override;
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
private:
MessageQueueIF* requestQueue;
ModeHelper modeHelper;
Mode_t mode = HasModesIF::MODE_OFF;
Countdown tmFunnelCd = Countdown(100);
PusTmFunnel& pusFunnel;
CfdpTmFunnel& cfdpFunnel;
VirtualChannelWithQueue& channel;
uint32_t packetCounter = 0;
const std::atomic_bool& ptmeLocked;
void readCommandQueue(void);
MessageQueueId_t getCommandQueue() const override;
void getMode(Mode_t* mode, Submode_t* submode) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override;
void startTransition(Mode_t mode, Submode_t submode) override;
void announceMode(bool recursive) override;
object_id_t getObjectId() const override;
const HasHealthIF* getOptHealthIF() const override;
const HasModesIF& getModeIF() const override;
ModeTreeChildIF& getModeTreeChildIF() override;
};
#endif /* MISSION_TMTC_LIVETMTASK_H_ */

View File

@ -0,0 +1,74 @@
#include "PersistentLogTmStoreTask.h"
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
LogStores stores, VirtualChannel& channel,
SdCardMountedIF& sdcMan,
const std::atomic_bool& ptmeLocked)
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked),
stores(stores),
okStoreContext(persTmStore::DUMP_OK_STORE_DONE, persTmStore::DUMP_OK_CANCELLED),
notOkStoreContext(persTmStore::DUMP_NOK_STORE_DONE, persTmStore::DUMP_NOK_CANCELLED),
miscStoreContext(persTmStore::DUMP_MISC_STORE_DONE, persTmStore::DUMP_MISC_CANCELLED) {}
ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
bool someonesBusy = false;
bool vcBusyDuringDump = false;
auto stateHandlingForStore = [&](bool storeIsBusy, DumpContext& ctx) {
if (storeIsBusy) {
someonesBusy = true;
}
if (fileHasSwapped) {
someFileWasSwapped = fileHasSwapped;
}
if (ctx.vcBusyDuringDump) {
vcBusyDuringDump = true;
}
};
while (true) {
readCommandQueue();
if (not cyclicStoreCheck()) {
continue;
}
someonesBusy = false;
someFileWasSwapped = false;
vcBusyDuringDump = false;
stateHandlingForStore(handleOneStore(stores.okStore, okStoreContext), okStoreContext);
stateHandlingForStore(handleOneStore(stores.notOkStore, notOkStoreContext), notOkStoreContext);
stateHandlingForStore(handleOneStore(stores.miscStore, miscStoreContext), miscStoreContext);
if (not someonesBusy) {
TaskFactory::delayTask(100);
} else if (vcBusyDuringDump) {
// TODO: Might not be necessary
sif::debug << "VC busy, delaying" << std::endl;
TaskFactory::delayTask(10);
}
}
}
bool PersistentLogTmStoreTask::initStoresIfPossible() {
if (sdcMan.isSdCardUsable(std::nullopt)) {
stores.okStore.initializeTmStore();
stores.miscStore.initializeTmStore();
stores.notOkStore.initializeTmStore();
return true;
}
return false;
}
void PersistentLogTmStoreTask::startTransition(Mode_t mode, Submode_t submode) {
if (mode == MODE_OFF) {
bool channelIsOn = channel.isTxOn();
cancelDump(okStoreContext, stores.okStore, channelIsOn);
cancelDump(notOkStoreContext, stores.notOkStore, channelIsOn);
cancelDump(miscStoreContext, stores.miscStore, channelIsOn);
this->mode = MODE_OFF;
} else if (mode == MODE_ON) {
this->mode = MODE_ON;
}
modeHelper.modeChanged(mode, submode);
announceMode(false);
}

View File

@ -5,11 +5,11 @@
#include <fsfw/storagemanager/StorageManagerIF.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
#include <mission/com/TmStoreTaskBase.h>
#include <mission/com/VirtualChannelWithQueue.h>
#include <mission/genericFactory.h>
#include <mission/tmtc/PersistentTmStore.h>
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
#include <mission/tmtc/TmStoreTaskBase.h>
#include <mission/tmtc/VirtualChannelWithQueue.h>
struct LogStores {
LogStores(PersistentTmStores& stores)
@ -22,7 +22,8 @@ struct LogStores {
class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
public:
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;
@ -35,7 +36,8 @@ class PersistentLogTmStoreTask : public TmStoreTaskBase, public ExecutableObject
Countdown graceDelayDuringDumping = Countdown(200);
bool someFileWasSwapped = false;
bool initStoresIfPossible();
bool initStoresIfPossible() override;
void startTransition(Mode_t mode, Submode_t submode) override;
};
#endif /* MISSION_TMTC_PERSISTENTLOGTMSTORETASK_H_ */

View File

@ -0,0 +1,54 @@
#include "PersistentSingleTmStoreTask.h"
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <unistd.h>
PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(
object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore,
VirtualChannel& channel, Event eventIfDumpDone, Event eventIfCancelled, SdCardMountedIF& sdcMan,
const std::atomic_bool& ptmeLocked)
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan, ptmeLocked),
storeWithQueue(tmStore),
dumpContext(eventIfDumpDone, eventIfCancelled) {}
ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
while (true) {
readCommandQueue();
// Delay done by the check
if (not cyclicStoreCheck()) {
continue;
}
bool busy = handleOneStore(storeWithQueue, dumpContext);
if (not busy) {
TaskFactory::delayTask(100);
} else if (dumpContext.vcBusyDuringDump) {
sif::debug << "VC busy, delaying" << std::endl;
// TODO: Might not be necessary
TaskFactory::delayTask(10);
} else {
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
TaskFactory::delayTask(10);
}
}
}
bool PersistentSingleTmStoreTask::initStoresIfPossible() {
if (sdcMan.isSdCardUsable(std::nullopt)) {
storeWithQueue.initializeTmStore();
return true;
}
return false;
}
void PersistentSingleTmStoreTask::startTransition(Mode_t mode, Submode_t submode) {
if (mode == MODE_OFF) {
cancelDump(dumpContext, storeWithQueue, channel.isTxOn());
this->mode = MODE_OFF;
} else if (mode == MODE_ON) {
this->mode = MODE_ON;
}
modeHelper.modeChanged(mode, submode);
announceMode(false);
}

View File

@ -3,15 +3,16 @@
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <mission/com/TmStoreTaskBase.h>
#include <mission/com/VirtualChannel.h>
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
#include <mission/tmtc/TmStoreTaskBase.h>
#include <mission/tmtc/VirtualChannel.h>
class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObjectIF {
public:
PersistentSingleTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
PersistentTmStoreWithTmQueue& storeWithQueue, VirtualChannel& channel,
Event eventIfDumpDone, SdCardMountedIF& sdcMan);
Event eventIfDumpDone, Event eventIfCancelled,
SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked);
ReturnValue_t performOperation(uint8_t opCode) override;
@ -21,7 +22,9 @@ class PersistentSingleTmStoreTask : public TmStoreTaskBase, public ExecutableObj
Countdown tcHandlingCd = Countdown(400);
Countdown graceDelayDuringDumping = Countdown(100);
bool initStoresIfPossible();
bool initStoresIfPossible() override;
void startTransition(Mode_t mode, Submode_t submode) override;
};
#endif /* MISSION_TMTC_PERSISTENTSINGLETMSTORETASK_H_ */

View File

@ -21,6 +21,7 @@ SyrlinksHandler::~SyrlinksHandler() = default;
void SyrlinksHandler::doStartUp() {
if (internalState == InternalState::OFF) {
transitionCommandPending = false;
internalState = InternalState::ENABLE_TEMPERATURE_PROTECTION;
commandExecuted = false;
}
@ -38,6 +39,7 @@ void SyrlinksHandler::doShutDown() {
// In any case, always disable TX first.
if (internalState != InternalState::SET_TX_STANDBY) {
internalState = InternalState::SET_TX_STANDBY;
transitionCommandPending = false;
commandExecuted = false;
}
if (internalState == InternalState::SET_TX_STANDBY) {
@ -122,8 +124,9 @@ ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* i
*id = syrlinks::SET_TX_MODE_STANDBY;
return buildCommandFromCommand(*id, nullptr, 0);
}
default:
default: {
break;
}
}
return NOTHING_TO_SEND;
}
@ -442,7 +445,6 @@ ReturnValue_t SyrlinksHandler::interpretDeviceReply(DeviceCommandId_t id, const
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
}
}
return returnvalue::OK;
}
@ -682,6 +684,9 @@ ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) {
}
break;
}
default: {
sif::error << "Syrlinks: Unexpected ACK reply" << std::endl;
}
}
switch (rememberCommandId) {
case (syrlinks::SET_TX_MODE_STANDBY): {
@ -728,16 +733,19 @@ void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
Mode_t tgtMode = getBaseMode(getMode());
auto commandDone = [&]() {
setMode(tgtMode);
transitionCommandPending = false;
internalState = InternalState::IDLE;
};
auto txOnHandler = [&](InternalState selMod) {
if (internalState == InternalState::IDLE) {
transitionCommandPending = false;
commandExecuted = false;
internalState = selMod;
}
// Select modulation first (BPSK or 0QPSK).
if (internalState == selMod) {
if (commandExecuted) {
transitionCommandPending = false;
internalState = InternalState::SET_TX_MODULATION;
commandExecuted = false;
}
@ -753,6 +761,7 @@ void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
};
auto txStandbyHandler = [&]() {
if (internalState == InternalState::IDLE) {
transitionCommandPending = false;
internalState = InternalState::SET_TX_STANDBY;
commandExecuted = false;
}

View File

@ -112,6 +112,7 @@ class SyrlinksHandler : public DeviceHandlerBase {
float tempPowerAmplifier = 0;
float tempBasebandBoard = 0;
bool commandExecuted = false;
bool transitionCommandPending = false;
uint8_t commandBuffer[syrlinks::MAX_COMMAND_SIZE];

View File

@ -0,0 +1,228 @@
#include "TmStoreTaskBase.h"
#include <fsfw/ipc/CommandMessageIF.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/subsystem/helper.h>
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <fsfw/tmstorage/TmStoreMessage.h>
#include "mission/persistentTmStoreDefs.h"
TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore,
VirtualChannel& channel, SdCardMountedIF& sdcMan,
const std::atomic_bool& ptmeLocked)
: SystemObject(objectId),
modeHelper(this),
ipcStore(ipcStore),
tmReader(&timeReader),
channel(channel),
sdcMan(sdcMan),
ptmeLocked(ptmeLocked) {
requestQueue = QueueFactory::instance()->createMessageQueue(10);
}
bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store,
DumpContext& dumpContext) {
ReturnValue_t result;
bool tmToStoreReceived = false;
bool tcRequestReceived = false;
bool dumpPerformed = false;
fileHasSwapped = false;
dumpContext.packetWasDumped = false;
dumpContext.vcBusyDuringDump = false;
// Store TM persistently
result = store.handleNextTm();
if (result == returnvalue::OK) {
tmToStoreReceived = true;
}
// Dump TMs
if (store.getState() == PersistentTmStore::State::DUMPING) {
if (handleOneDump(store, dumpContext, dumpPerformed) != returnvalue::OK) {
return result;
}
} else {
Command_t execCmd;
// Handle TC requests, for example deletion or retrieval requests.
result = store.handleCommandQueue(ipcStore, execCmd);
if (result == returnvalue::OK) {
if (execCmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) {
cancelDumpCd.resetTimer();
tmSinkBusyCd.resetTimer();
dumpContext.reset();
}
tcRequestReceived = true;
}
}
if (tcRequestReceived or tmToStoreReceived or dumpPerformed) {
return true;
}
return false;
}
bool TmStoreTaskBase::cyclicStoreCheck() {
if (not storesInitialized) {
storesInitialized = initStoresIfPossible();
if (not storesInitialized) {
TaskFactory::delayTask(400);
return false;
}
} else if (sdCardCheckCd.hasTimedOut()) {
if (not sdcMan.isSdCardUsable(std::nullopt)) {
// Might be due to imminent shutdown or SD card switch.
storesInitialized = false;
TaskFactory::delayTask(100);
return false;
}
sdCardCheckCd.resetTimer();
}
return true;
}
void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn) {
ctx.reset();
if (store.getState() == PersistentTmStore::State::DUMPING) {
triggerEvent(ctx.eventIfCancelled, ctx.numberOfDumpedPackets, ctx.dumpedBytes);
}
store.cancelDump();
if (isTxOn) {
channel.cancelTransfer();
}
}
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);
} else {
// The PTME might be at full load, so it might sense to delay for a bit to let it do
// its work until some more bandwidth is available. Set a flag here so the upper layer can
// do ths.
dumpContext.vcBusyDuringDump = true;
dumpContext.ptmeBusyCounter++;
if (dumpContext.ptmeBusyCounter == 100) {
// If this happens, something is probably wrong.
sif::warning << "PTME busy for longer period. Cancelling dump" << std::endl;
cancelDump(dumpContext, store, channel.isTxOn());
}
}
if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) {
cancelDump(dumpContext, store, channel.isTxOn());
}
return result;
}
ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
DumpContext& dumpContext, bool& dumpPerformed) {
size_t dumpedLen = 0;
auto dumpDoneHandler = [&]() {
uint32_t startTime;
uint32_t endTime;
store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime);
triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets,
dumpContext.dumpedBytes);
dumpContext.reset();
};
// Dump the next packet into the PTME.
dumpContext.ptmeBusyCounter = 0;
tmSinkBusyCd.resetTimer();
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) {
// This can happen if a file is corrupted and the next file swap completes the dump.
dumpDoneHandler();
return returnvalue::OK;
}
dumpedLen = tmReader.getFullPacketLen();
// Only write to VC if mode is on, but always confirm the dump.
// If the mode is OFF, it is assumed the PTME is not usable and is not allowed to be written
// (e.g. to confirm a reset or the transmitter is off anyway).
if (mode == MODE_ON) {
result = channel.write(tmReader.getFullData(), dumpedLen);
if (result == DirectTmSinkIF::IS_BUSY) {
sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl;
} else if (result != returnvalue::OK) {
sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl;
}
}
result = store.confirmDump(tmReader, fileHasSwapped);
if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) {
dumpPerformed = true;
if (dumpedLen > 0) {
dumpContext.dumpedBytes += dumpedLen;
dumpContext.numberOfDumpedPackets += 1;
dumpContext.packetWasDumped = true;
}
}
if (result == PersistentTmStore::DUMP_DONE) {
dumpDoneHandler();
}
return returnvalue::OK;
}
ReturnValue_t TmStoreTaskBase::initialize() {
modeHelper.initialize();
return returnvalue::OK;
}
void TmStoreTaskBase::getMode(Mode_t* mode, Submode_t* submode) {
if (mode != nullptr) {
*mode = this->mode;
}
if (submode != nullptr) {
*submode = SUBMODE_NONE;
}
}
ReturnValue_t TmStoreTaskBase::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) {
if (mode == MODE_ON or mode == MODE_OFF) {
return returnvalue::OK;
}
return returnvalue::FAILED;
}
MessageQueueId_t TmStoreTaskBase::getCommandQueue() const { return requestQueue->getId(); }
void TmStoreTaskBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, SUBMODE_NONE); }
object_id_t TmStoreTaskBase::getObjectId() const { return SystemObject::getObjectId(); }
const HasHealthIF* TmStoreTaskBase::getOptHealthIF() const { return nullptr; }
const HasModesIF& TmStoreTaskBase::getModeIF() const { return *this; }
ReturnValue_t TmStoreTaskBase::connectModeTreeParent(HasModeTreeChildrenIF& parent) {
return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper);
}
ModeTreeChildIF& TmStoreTaskBase::getModeTreeChildIF() { return *this; }
void TmStoreTaskBase::readCommandQueue(void) {
CommandMessage commandMessage;
ReturnValue_t result = returnvalue::FAILED;
result = requestQueue->receiveMessage(&commandMessage);
if (result == returnvalue::OK) {
result = modeHelper.handleModeCommand(&commandMessage);
if (result == returnvalue::OK) {
return;
}
CommandMessage reply;
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand());
requestQueue->reply(&reply);
return;
}
}

View File

@ -0,0 +1,106 @@
#ifndef MISSION_TMTC_TMSTORETASKBASE_H_
#define MISSION_TMTC_TMSTORETASKBASE_H_
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/subsystem/ModeTreeChildIF.h>
#include <fsfw/subsystem/ModeTreeConnectionIF.h>
#include <fsfw/timemanager/CdsShortTimeStamper.h>
#include <fsfw/timemanager/Countdown.h>
#include <mission/com/VirtualChannel.h>
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
/**
* Generic class which composes a Virtual Channel and a persistent TM stores. This allows dumping
* the TM store into the virtual channel directly.
*/
class TmStoreTaskBase : public SystemObject,
public HasModesIF,
public ModeTreeChildIF,
public ModeTreeConnectionIF {
public:
struct DumpContext {
DumpContext(Event eventIfDone, Event eventIfCancelled)
: eventIfDone(eventIfDone), eventIfCancelled(eventIfCancelled) {}
void reset() {
numberOfDumpedPackets = 0;
dumpedBytes = 0;
vcBusyDuringDump = false;
packetWasDumped = false;
bytesDumpedAtLastDelay = 0;
ptmeBusyCounter = 0;
}
const Event eventIfDone;
const Event eventIfCancelled;
size_t numberOfDumpedPackets = 0;
size_t bytesDumpedAtLastDelay = 0;
size_t dumpedBytes = 0;
uint32_t ptmeBusyCounter = 0;
bool packetWasDumped = false;
bool vcBusyDuringDump = false;
};
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel,
SdCardMountedIF& sdcMan, const std::atomic_bool& ptmeLocked);
ReturnValue_t initialize() override;
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override;
protected:
ModeHelper modeHelper;
MessageQueueIF* requestQueue;
StorageManagerIF& ipcStore;
PusTmReader tmReader;
CdsShortTimeStamper timeReader;
VirtualChannel& channel;
SdCardMountedIF& sdcMan;
const std::atomic_bool& ptmeLocked;
Mode_t mode = HasModesIF::MODE_OFF;
Countdown sdCardCheckCd = Countdown(800);
// 20 minutes are allowed as maximum dump time.
Countdown cancelDumpCd = Countdown(60 * 20 * 1000);
// If the TM sink is busy for 1 minute for whatever reason, cancel the dump.
Countdown tmSinkBusyCd = Countdown(60 * 1000);
bool storesInitialized = false;
bool fileHasSwapped = false;
void readCommandQueue(void);
virtual bool initStoresIfPossible() = 0;
virtual void startTransition(Mode_t mode, Submode_t submode) = 0;
void cancelDump(DumpContext& ctx, PersistentTmStore& store, bool isTxOn);
/**
*
* Handling for one store. Returns if anything was done.
* @param store
* @return
*/
bool handleOneStore(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext);
ReturnValue_t handleOneDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext,
bool& dumpPerformed);
ReturnValue_t performDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext,
bool& dumpPerformed);
/**
* Occasionally check whether SD card is okay to be used. If not, poll whether it is ready to
* be used again and re-initialize stores. Returns whether store is okay to be used.
*/
bool cyclicStoreCheck();
MessageQueueId_t getCommandQueue() const override;
void getMode(Mode_t* mode, Submode_t* submode) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override;
void announceMode(bool recursive) override;
object_id_t getObjectId() const override;
const HasHealthIF* getOptHealthIF() const override;
const HasModesIF& getModeIF() const override;
ModeTreeChildIF& getModeTreeChildIF() override;
};
#endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */

View File

@ -1,12 +1,8 @@
#include "VirtualChannel.h"
VirtualChannel::VirtualChannel(object_id_t objectId, uint8_t vcId, const char* vcName, PtmeIF& ptme,
const std::atomic_bool& linkStateProvider)
: SystemObject(objectId),
ptme(ptme),
vcId(vcId),
vcName(vcName),
linkStateProvider(linkStateProvider) {}
const std::atomic_bool& txOn)
: SystemObject(objectId), ptme(ptme), vcId(vcId), vcName(vcName), txOn(txOn) {}
ReturnValue_t VirtualChannel::initialize() { return returnvalue::OK; }
@ -15,7 +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 (linkStateProvider.load()) {
if (txOn) {
return ptme.writeToVc(vcId, data, size);
}
return returnvalue::OK;
@ -27,10 +23,12 @@ const char* VirtualChannel::getName() const { return vcName.c_str(); }
bool VirtualChannel::isBusy() const {
// Data is discarded, so channel is not busy.
if (linkStateProvider.load()) {
if (not txOn) {
return false;
}
return ptme.isBusy(vcId);
}
void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); }
bool VirtualChannel::isTxOn() const { return txOn; }

View File

@ -30,6 +30,7 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF {
ReturnValue_t write(const uint8_t* data, size_t size) override;
void cancelTransfer() override;
uint8_t getVcid() const;
bool isTxOn() const;
const char* getName() const;
@ -37,5 +38,5 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF {
PtmeIF& ptme;
uint8_t vcId = 0;
std::string vcName;
const std::atomic_bool& linkStateProvider;
const std::atomic_bool& txOn;
};

View File

@ -1,4 +1,4 @@
#include <mission/tmtc/VirtualChannelWithQueue.h>
#include "VirtualChannelWithQueue.h"
#include "OBSWConfig.h"
#include "fsfw/ipc/QueueFactory.h"
@ -19,7 +19,7 @@ VirtualChannelWithQueue::VirtualChannelWithQueue(object_id_t objectId, uint8_t v
const char* VirtualChannelWithQueue::getName() const { return VirtualChannel::getName(); }
ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) {
TmTcMessage message;
ReturnValue_t result = tmQueue->receiveMessage(&message);
if (result == MessageQueueIF::EMPTY) {
@ -36,15 +36,13 @@ ReturnValue_t VirtualChannelWithQueue::sendNextTm() {
return result;
}
result = write(data, size);
if (result != returnvalue::OK) {
return result;
if (performWriteOp) {
result = write(data, size);
}
// Try delete in any case, ignore failures (which should not happen), it is more important to
// propagate write errors.
tmStore.deleteData(storeId);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
return result;
}
MessageQueueId_t VirtualChannelWithQueue::getReportReceptionQueue(uint8_t virtualChannel) const {

View File

@ -4,7 +4,7 @@
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <linux/ipcore/PtmeIF.h>
#include <mission/tmtc/VirtualChannel.h>
#include <mission/com/VirtualChannel.h>
#include <atomic>
@ -34,7 +34,7 @@ class VirtualChannelWithQueue : public VirtualChannel, public AcceptsTelemetryIF
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) const override;
[[nodiscard]] const char* getName() const override;
ReturnValue_t sendNextTm();
ReturnValue_t handleNextTm(bool performWriteOp);
private:
MessageQueueIF* tmQueue = nullptr;

View File

@ -3,6 +3,8 @@
#include <fsfw/ipc/MutexFactory.h>
#include <fsfw/ipc/MutexGuard.h>
#include <atomic>
com::Datarate DATARATE_CFG_RAW = com::Datarate::LOW_RATE_MODULATION_BPSK;
MutexIF* DATARATE_LOCK = nullptr;

View File

@ -347,7 +347,8 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
AcsBoardHelper acsBoardHelper = AcsBoardHelper(
objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER,
objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER,
objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER);
objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER,
objects::GPS_0_HEALTH_DEV, objects::GPS_1_HEALTH_DEV);
auto acsAss =
new AcsBoardAssembly(objects::ACS_BOARD_ASS, &pwrSwitcher, acsBoardHelper, gpioComIF);
for (auto& assChild : assemblyDhbs) {

View File

@ -205,7 +205,7 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
using namespace scex;
ReturnValue_t status = OK;
auto oneFileHandler = [&](std::string cmdName) {
auto oneFileHandler = [&](const char* cmdName) {
auto activeSd = sdcMan.getActiveSdCard();
if (not activeSd) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
@ -216,7 +216,7 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
if (prefix == nullptr) {
return returnvalue::FAILED;
}
oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin";
oss << prefix << "/scex/scex-" << cmdName << "-" << fileId << ".bin";
fileName = oss.str();
ofstream out(fileName, ofstream::binary);
if (out.bad()) {
@ -227,7 +227,7 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
out << helper;
return OK;
};
auto multiFileHandler = [&](std::string cmdName) {
auto multiFileHandler = [&](const char* cmdName) {
if ((helper.getPacketCounter() == 1) or (not fileNameSet)) {
auto activeSd = sdcMan.getActiveSdCard();
if (not activeSd) {
@ -264,31 +264,31 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
id = helper.getCmd();
switch (id) {
case (PING): {
status = oneFileHandler("ping_");
status = oneFileHandler(PING_IDLE_BASE_NAME);
break;
}
case (ION_CMD): {
status = oneFileHandler("ion_");
status = oneFileHandler(ION_BASE_NAME);
break;
}
case (TEMP_CMD): {
status = oneFileHandler("temp_");
status = oneFileHandler(TEMPERATURE_BASE_NAME);
break;
}
case (EXP_STATUS_CMD): {
status = oneFileHandler("exp_status_");
status = oneFileHandler(EXP_STATUS_BASE_NAME);
break;
}
case (FRAM): {
status = multiFileHandler("fram_");
status = multiFileHandler(FRAM_BASE_NAME);
break;
}
case (ONE_CELL): {
status = multiFileHandler("one_cell_");
status = multiFileHandler(ONE_CELL_BASE_NAME);
break;
}
case (ALL_CELLS_CMD): {
status = multiFileHandler("multi_cell_");
status = multiFileHandler(ALL_CELLS_BASE_NAME);
break;
}
default:
@ -362,9 +362,9 @@ std::string ScexDeviceHandler::date_time_string() {
ostringstream oss(std::ostringstream::ate);
if (tod.hour < 10) {
oss << tod.year << tod.month << tod.day << "_0" << tod.hour;
oss << tod.year << tod.month << tod.day << "T0" << tod.hour;
} else {
oss << tod.year << tod.month << tod.day << "_" << tod.hour;
oss << tod.year << tod.month << tod.day << "T" << tod.hour;
}
if (tod.minute < 10) {
oss << 0 << tod.minute;

View File

@ -13,6 +13,14 @@ class SdCardMountedIF;
class ScexDeviceHandler : public DeviceHandlerBase {
public:
static constexpr char FRAM_BASE_NAME[] = "framContent";
static constexpr char ION_BASE_NAME[] = "ion";
static constexpr char TEMPERATURE_BASE_NAME[] = "temperature";
static constexpr char EXP_STATUS_BASE_NAME[] = "expStatus";
static constexpr char ONE_CELL_BASE_NAME[] = "oneCell";
static constexpr char ALL_CELLS_BASE_NAME[] = "allCells";
static constexpr char PING_IDLE_BASE_NAME[] = "pingIdle";
ScexDeviceHandler(object_id_t objectId, ScexUartReader &reader, CookieIF *cookie,
SdCardMountedIF &sdcMan);
void setPowerSwitcher(PowerSwitchIF &powerSwitcher, power::Switch_t switchId);

View File

@ -25,8 +25,6 @@ static constexpr Event POSSIBLE_FILE_CORRUPTION = event::makeEvent(SUBSYSTEM_ID,
//! P2: Allowed file size
static constexpr Event FILE_TOO_LARGE = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
static constexpr Event BUSY_DUMPING_EVENT = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
//! [EXPORT] : [COMMENT] Dump was cancelled. P1: Object ID of store.
static constexpr Event DUMP_WAS_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_OK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO);
@ -38,6 +36,17 @@ static constexpr Event DUMP_MISC_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 7,
static constexpr Event DUMP_HK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_CFDP_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 9, severity::INFO);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_OK_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 10, severity::LOW);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_NOK_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 11, severity::LOW);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_MISC_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 12, severity::LOW);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_HK_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 13, severity::LOW);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_CFDP_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 14, severity::LOW);
}; // namespace persTmStore
#endif /* MISSION_PERSISTENTTMSTOREDEFS_H_ */

View File

@ -26,10 +26,12 @@ ReturnValue_t pst::pstSyrlinks(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.7, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ);
static_cast<void>(length);

View File

@ -77,14 +77,16 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_
if (wantedSubmode == A_SIDE) {
if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or
(helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or
helper.gpsMode != MODE_ON) {
(helper.gpsMode != MODE_ON) or
(healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY)) {
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
}
return returnvalue::OK;
} else if (wantedSubmode == B_SIDE) {
if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or
(helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or
helper.gpsMode != MODE_ON) {
(helper.gpsMode != MODE_ON) or
(healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY)) {
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
}
return returnvalue::OK;
@ -126,12 +128,33 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) {
if (mode == devMode) {
modeTable[tableIdx].setMode(mode);
} else if (isUseable(objectId, devMode)) {
} else if (isModeCommandable(objectId, devMode)) {
modeTable[tableIdx].setMode(mode);
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
}
};
bool gpsUsable = isUseable(helper.gpsId, helper.gpsMode);
bool gpsUsable = isModeCommandable(helper.gpsId, helper.gpsMode);
auto gpsCmd = [&](bool gnss0NReset, bool gnss1NReset, uint8_t gnssSelect) {
if (gpsUsable) {
if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) {
modeTable[ModeTableIdx::GPS].setMode(MODE_ON);
} else if (mode == MODE_OFF) {
gnss0NReset = true;
gnss1NReset = true;
modeTable[ModeTableIdx::GPS].setMode(MODE_OFF);
}
modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE);
gpioHandler(gpioIds::GNSS_0_NRESET, gnss0NReset,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
"of GNSS 0");
gpioHandler(gpioIds::GNSS_1_NRESET, gnss1NReset,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
"of GNSS 1");
gpioHandler(gpioIds::GNSS_SELECT, gnssSelect,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select");
}
};
switch (submode) {
case (A_SIDE): {
modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF);
@ -146,16 +169,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A);
cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A);
cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A);
if (gpsUsable) {
gpioHandler(gpioIds::GNSS_0_NRESET, true,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
"of GNSS 0 high (used GNSS)");
gpioHandler(gpioIds::GNSS_1_NRESET, false,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
"of GNSS 1 low (unused GNSS)");
gpioHandler(gpioIds::GNSS_SELECT, false,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select low");
}
gpsCmd(true, false, 0);
break;
}
case (B_SIDE): {
@ -171,20 +185,10 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B);
cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B);
cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B);
if (gpsUsable) {
gpioHandler(gpioIds::GNSS_0_NRESET, false,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
"of GNSS 0 low (unused GNSS)");
gpioHandler(gpioIds::GNSS_1_NRESET, true,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
"of GNSS 1 high (used GNSS)");
gpioHandler(gpioIds::GNSS_SELECT, true,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select high");
}
gpsCmd(false, true, 1);
break;
}
case (DUAL_MODE): {
cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS);
cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A);
cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A);
cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A);
@ -193,26 +197,10 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B);
cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B);
cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B);
ReturnValue_t status = returnvalue::OK;
if (gpsUsable) {
gpioHandler(gpioIds::GNSS_0_NRESET, true,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
"of GNSS 0 high (used GNSS)");
gpioHandler(gpioIds::GNSS_1_NRESET, true,
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
"of GNSS 1 high (used GNSS)");
if (defaultSubmode == Submodes::A_SIDE) {
status = gpioIF->pullLow(gpioIds::GNSS_SELECT);
} else {
status = gpioIF->pullHigh(gpioIds::GNSS_SELECT);
}
if (status != returnvalue::OK) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select to"
"default side for dual mode"
<< std::endl;
#endif
}
if (defaultSubmode == Submodes::A_SIDE) {
gpsCmd(true, true, 0);
} else {
gpsCmd(true, true, 1);
}
break;
}
@ -220,10 +208,6 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
sif::error << "AcsBoardAssembly::handleNormalModeCmd: Unknown submode" << std::endl;
}
}
if (gpsUsable) {
modeTable[ModeTableIdx::GPS].setMode(MODE_ON);
modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE);
}
if (needsSecondStep) {
result = NEED_SECOND_STEP;
}
@ -289,25 +273,54 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
Submode_t deviceSubmode) {
using namespace returnvalue;
ReturnValue_t status = returnvalue::OK;
auto overwriteHealthForOneDev = [&](object_id_t dev) {
HealthState health = healthHelper.healthTable->getHealth(dev);
if (health == FAULTY or health == PERMANENT_FAULTY) {
overwriteDeviceHealth(dev, health);
status = NEED_TO_CHANGE_HEALTH;
} else if (health == EXTERNAL_CONTROL) {
auto checkAcsBoardSensorGroup = [&](object_id_t o0, object_id_t o1, object_id_t o2,
object_id_t o3) {
HealthState h0 = healthHelper.healthTable->getHealth(o0);
HealthState h1 = healthHelper.healthTable->getHealth(o1);
HealthState h2 = healthHelper.healthTable->getHealth(o2);
HealthState h3 = healthHelper.healthTable->getHealth(o3);
if ((h0 == FAULTY or h0 == PERMANENT_FAULTY) and (h1 == FAULTY or h1 == PERMANENT_FAULTY) and
(h2 == FAULTY or h2 == PERMANENT_FAULTY) and (h3 == FAULTY or h3 == PERMANENT_FAULTY)) {
overwriteDeviceHealth(o0, h0);
overwriteDeviceHealth(o1, h1);
overwriteDeviceHealth(o2, h2);
overwriteDeviceHealth(o3, h3);
}
if (h0 == EXTERNAL_CONTROL or h1 == EXTERNAL_CONTROL or h2 == EXTERNAL_CONTROL or
h3 == EXTERNAL_CONTROL) {
modeHelper.setForced(true);
}
};
if (healthHelper.healthTable->getHealth(helper.gpsId) == EXTERNAL_CONTROL) {
modeHelper.setForced(true);
}
if (deviceSubmode == duallane::DUAL_MODE) {
overwriteHealthForOneDev(helper.mgm0Lis3IdSideA);
overwriteHealthForOneDev(helper.mgm1Rm3100IdSideA);
overwriteHealthForOneDev(helper.mgm2Lis3IdSideB);
overwriteHealthForOneDev(helper.mgm3Rm3100IdSideB);
overwriteHealthForOneDev(helper.gyro0AdisIdSideA);
overwriteHealthForOneDev(helper.gyro1L3gIdSideA);
overwriteHealthForOneDev(helper.gyro2AdisIdSideB);
overwriteHealthForOneDev(helper.gyro3L3gIdSideB);
overwriteHealthForOneDev(helper.gpsId);
checkAcsBoardSensorGroup(helper.mgm0Lis3IdSideA, helper.mgm1Rm3100IdSideA,
helper.mgm2Lis3IdSideB, helper.mgm3Rm3100IdSideB);
checkAcsBoardSensorGroup(helper.gyro0AdisIdSideA, helper.gyro1L3gIdSideA,
helper.gyro2AdisIdSideB, helper.gyro3L3gIdSideB);
}
return status;
}
void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) {
using namespace duallane;
// Special handling to account for GPS devices being faulty. If the GPS device on the other
// side is marked faulty, directly to to dual side.
if (submode == Submodes::A_SIDE) {
if (healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY or
healthHelper.healthTable->getHealth(helper.healthDevGps1) == PERMANENT_FAULTY) {
triggerEvent(DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY, submode, 0);
startTransition(mode, Submodes::DUAL_MODE);
return;
}
} else if (submode == Submodes::B_SIDE) {
if (healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY or
healthHelper.healthTable->getHealth(helper.healthDevGps0) == PERMANENT_FAULTY) {
triggerEvent(DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY, submode, 0);
startTransition(mode, Submodes::DUAL_MODE);
return;
}
}
DualLaneAssemblyBase::handleChildrenLostMode(result);
}

View File

@ -12,7 +12,7 @@
struct AcsBoardHelper {
AcsBoardHelper(object_id_t mgm0Id, object_id_t mgm1Id, object_id_t mgm2Id, object_id_t mgm3Id,
object_id_t gyro0Id, object_id_t gyro1Id, object_id_t gyro2Id, object_id_t gyro3Id,
object_id_t gpsId)
object_id_t gpsId, object_id_t gps0HealthDev, object_id_t gps1HealthDev)
: mgm0Lis3IdSideA(mgm0Id),
mgm1Rm3100IdSideA(mgm1Id),
mgm2Lis3IdSideB(mgm2Id),
@ -35,6 +35,9 @@ struct AcsBoardHelper {
object_id_t gpsId = objects::NO_OBJECT;
object_id_t healthDevGps0 = objects::NO_OBJECT;
object_id_t healthDevGps1 = objects::NO_OBJECT;
Mode_t gyro0SideAMode = HasModesIF::MODE_OFF;
Mode_t gyro1SideAMode = HasModesIF::MODE_OFF;
Mode_t gyro2SideBMode = HasModesIF::MODE_OFF;
@ -91,6 +94,11 @@ class AcsBoardAssembly : public DualLaneAssemblyBase {
//! desired mode/submode combination
static constexpr Event SIDE_SWITCH_TRANSITION_NOT_ALLOWED =
event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW);
//! [EXPORT] : [COMMENT] This is triggered when the assembly would have normally switched
//! the board side, but the GPS device of the other side was marked faulty.
//! P1: Current submode.
static constexpr Event DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY =
event::makeEvent(SUBSYSTEM_ID, 4, severity::MEDIUM);
static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9;
@ -120,6 +128,8 @@ class AcsBoardAssembly : public DualLaneAssemblyBase {
ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override;
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override;
void handleChildrenLostMode(ReturnValue_t result) override;
ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode);
ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode);
void refreshHelperModes();

View File

@ -2,6 +2,7 @@ target_sources(
${LIB_EIVE_MISSION}
PRIVATE AcsBoardAssembly.cpp
AcsSubsystem.cpp
StrAssembly.cpp
DualLaneAssemblyBase.cpp
ImtqAssembly.cpp
RwAssembly.cpp

View File

@ -46,6 +46,9 @@ void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
AssemblyBase::startTransition(mode, submode);
return;
}
if (sideSwitchState == SideSwitchState::NONE and sideSwitchTransition(mode, submode)) {
sideSwitchState = SideSwitchState::REQUESTED;
}
uint8_t pwrSubmode = submode;
if (sideSwitchState == SideSwitchState::REQUESTED) {
pwrSubmode = duallane::DUAL_MODE;
@ -61,7 +64,7 @@ void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
}
}
bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) {
bool DualLaneAssemblyBase::isModeCommandable(object_id_t object, Mode_t mode) {
if (healthHelper.healthTable->isFaulty(object)) {
return false;
}
@ -70,10 +73,7 @@ bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) {
if (childrenMap[object].mode == mode) {
return true;
}
if (healthHelper.healthTable->isCommandable(object)) {
return true;
}
// Check for external control health state is done by base class.
return false;
}
@ -115,9 +115,6 @@ ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_
if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) {
return returnvalue::FAILED;
}
if (sideSwitchTransition(mode, submode)) {
sideSwitchState = SideSwitchState::REQUESTED;
}
return returnvalue::OK;
}

View File

@ -49,12 +49,12 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF {
MessageQueueIF* eventQueue = nullptr;
/**
* Check whether it makes sense to send mode commands to the device
* Check whether it makes sense to send mode commands to the device.
* @param object
* @param mode
* @return
*/
bool isUseable(object_id_t object, Mode_t mode);
bool isModeCommandable(object_id_t object, Mode_t mode);
/**
* Thin wrapper function which is required because the helper class

View File

@ -158,18 +158,29 @@ void SusAssembly::refreshHelperModes() {
ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode) {
using namespace returnvalue;
ReturnValue_t status = returnvalue::OK;
auto overwriteHealthForOneDev = [&](object_id_t dev) {
auto checkSusGroup = [&](object_id_t devNom, object_id_t devRed) {
HealthState healthNom = healthHelper.healthTable->getHealth(devNom);
HealthState healthRed = healthHelper.healthTable->getHealth(devRed);
if ((healthNom == FAULTY or healthNom == PERMANENT_FAULTY) and
(healthRed == FAULTY or healthRed == PERMANENT_FAULTY)) {
overwriteDeviceHealth(devNom, healthNom);
overwriteDeviceHealth(devRed, healthRed);
}
};
auto checkHealthForOneDev = [&](object_id_t dev) {
HealthState health = healthHelper.healthTable->getHealth(dev);
if (health == FAULTY or health == PERMANENT_FAULTY) {
overwriteDeviceHealth(dev, health);
status = NEED_TO_CHANGE_HEALTH;
} else if (health == EXTERNAL_CONTROL) {
if (health == EXTERNAL_CONTROL) {
modeHelper.setForced(true);
}
};
if (deviceSubmode == duallane::DUAL_MODE) {
for (uint8_t idx = 0; idx < 12; idx++) {
overwriteHealthForOneDev(helper.susIds[idx]);
uint8_t idx = 0;
for (idx = 0; idx < 6; idx++) {
checkSusGroup(helper.susIds[idx], helper.susIds[idx + 6]);
checkHealthForOneDev(helper.susIds[idx]);
}
for (idx = 6; idx < 12; idx++) {
checkHealthForOneDev(helper.susIds[idx]);
}
}
return status;

View File

@ -22,7 +22,7 @@ auto COM_SEQUENCE_RX_ONLY =
auto COM_TABLE_RX_ONLY_TGT = std::make_pair(
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TRANS_0 = std::make_pair(
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 2, FixedArrayList<ModeListEntry, 3>());
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 2, FixedArrayList<ModeListEntry, 6>());
auto COM_TABLE_RX_ONLY_TRANS_1 = std::make_pair(
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 3, FixedArrayList<ModeListEntry, 3>());
@ -36,7 +36,7 @@ auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0 =
FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1 =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 3,
FixedArrayList<ModeListEntry, 3>());
FixedArrayList<ModeListEntry, 6>());
auto COM_SEQUENCE_RX_AND_TX_HIGH_RATE =
std::make_pair(::com::Submode::RX_AND_TX_HIGH_DATARATE, FixedArrayList<ModeListEntry, 3>());
@ -48,7 +48,7 @@ auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0 =
FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1 =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 3,
FixedArrayList<ModeListEntry, 3>());
FixedArrayList<ModeListEntry, 6>());
auto COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE =
std::make_pair(::com::Submode::RX_AND_TX_DEFAULT_DATARATE, FixedArrayList<ModeListEntry, 3>());
@ -60,7 +60,7 @@ auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0 =
FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1 =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 3,
FixedArrayList<ModeListEntry, 3>());
FixedArrayList<ModeListEntry, 6>());
namespace {
@ -110,6 +110,10 @@ void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh) {
// Build RX Only transition 0
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TRANS_0.second);
iht(objects::LOG_STORE_AND_TM_TASK, OFF, 0, COM_TABLE_RX_ONLY_TRANS_0.second);
iht(objects::HK_STORE_AND_TM_TASK, OFF, 0, COM_TABLE_RX_ONLY_TRANS_0.second);
iht(objects::CFDP_STORE_AND_TM_TASK, OFF, 0, COM_TABLE_RX_ONLY_TRANS_0.second);
iht(objects::LIVE_TM_TASK, OFF, 0, COM_TABLE_RX_ONLY_TRANS_0.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TRANS_0.first, &COM_TABLE_RX_ONLY_TRANS_0.second)),
ctxc);
@ -165,6 +169,10 @@ void buildTxAndRxLowRateSequence(Subsystem& ss, ModeListEntry& eh) {
// Build TX and RX low transition 1
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE,
COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second);
iht(objects::LOG_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second);
iht(objects::HK_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second);
iht(objects::CFDP_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second);
iht(objects::LIVE_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.first,
&COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second)),
ctxc);
@ -217,6 +225,10 @@ void buildTxAndRxHighRateSequence(Subsystem& ss, ModeListEntry& eh) {
// Build TX and RX high transition 1
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE,
COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second);
iht(objects::LOG_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second);
iht(objects::HK_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second);
iht(objects::CFDP_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second);
iht(objects::LIVE_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.first,
&COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second)),
ctxc);
@ -271,6 +283,10 @@ void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh) {
// Build TX and RX default transition 1
iht(objects::SYRLINKS_ASSY, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE,
COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second);
iht(objects::LOG_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second);
iht(objects::HK_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second);
iht(objects::CFDP_STORE_AND_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second);
iht(objects::LIVE_TM_TASK, ON, 0, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.first,
&COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second)),
ctxc);

View File

@ -5,6 +5,5 @@ target_sources(
TcsSubsystem.cpp
PayloadSubsystem.cpp
Stack5VHandler.cpp
StrAssembly.cpp
PowerStateMachineBase.cpp
TcsBoardAssembly.cpp)

View File

@ -1,17 +1,11 @@
target_sources(
${LIB_EIVE_MISSION}
PRIVATE VirtualChannelWithQueue.cpp
PersistentTmStoreWithTmQueue.cpp
LiveTmTask.cpp
VirtualChannel.cpp
PRIVATE PersistentTmStoreWithTmQueue.cpp
TmFunnelHandler.cpp
TmFunnelBase.cpp
CfdpTmFunnel.cpp
tmFilters.cpp
PusLiveDemux.cpp
PersistentSingleTmStoreTask.cpp
PersistentLogTmStoreTask.cpp
TmStoreTaskBase.cpp
PusPacketFilter.cpp
PusTmRouteByFilterHelper.cpp
Service15TmStorage.cpp

View File

@ -1,27 +0,0 @@
#include "LiveTmTask.h"
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
VirtualChannelWithQueue& channel)
: SystemObject(objectId), pusFunnel(pusFunnel), cfdpFunnel(cfdpFunnel), channel(channel) {}
ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
while (true) {
// The funnel tasks are scheduled here directly as well.
ReturnValue_t result = channel.sendNextTm();
if (result == DirectTmSinkIF::IS_BUSY) {
sif::error << "Lost live TM, PAPB busy" << std::endl;
}
if (result == MessageQueueIF::EMPTY) {
if (tmFunnelCd.hasTimedOut()) {
pusFunnel.performOperation(0);
cfdpFunnel.performOperation(0);
tmFunnelCd.resetTimer();
}
// 40 ms IDLE delay. Might tweak this in the future.
TaskFactory::delayTask(40);
}
}
}

View File

@ -1,25 +0,0 @@
#ifndef MISSION_TMTC_LIVETMTASK_H_
#define MISSION_TMTC_LIVETMTASK_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PusTmFunnel.h>
#include <mission/tmtc/VirtualChannelWithQueue.h>
class LiveTmTask : public SystemObject, public ExecutableObjectIF {
public:
LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
VirtualChannelWithQueue& channel);
ReturnValue_t performOperation(uint8_t opCode) override;
private:
Countdown tmFunnelCd = Countdown(100);
PusTmFunnel& pusFunnel;
CfdpTmFunnel& cfdpFunnel;
VirtualChannelWithQueue& channel;
};
#endif /* MISSION_TMTC_LIVETMTASK_H_ */

View File

@ -1,50 +0,0 @@
#include "PersistentLogTmStoreTask.h"
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
PersistentLogTmStoreTask::PersistentLogTmStoreTask(object_id_t objectId, StorageManagerIF& ipcStore,
LogStores stores, VirtualChannel& channel,
SdCardMountedIF& sdcMan)
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan),
stores(stores),
okStoreContext(persTmStore::DUMP_OK_STORE_DONE),
notOkStoreContext(persTmStore::DUMP_NOK_STORE_DONE),
miscStoreContext(persTmStore::DUMP_MISC_STORE_DONE) {}
ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
bool someonesBusy = false;
auto stateHandlingForStore = [&](bool storeIsBusy) {
if (storeIsBusy) {
someonesBusy = true;
}
if (fileHasSwapped) {
someFileWasSwapped = fileHasSwapped;
}
};
while (true) {
if (not cyclicStoreCheck()) {
continue;
}
someonesBusy = false;
someFileWasSwapped = false;
stateHandlingForStore(handleOneStore(stores.okStore, okStoreContext));
stateHandlingForStore(handleOneStore(stores.notOkStore, notOkStoreContext));
stateHandlingForStore(handleOneStore(stores.miscStore, miscStoreContext));
if (not someonesBusy) {
TaskFactory::delayTask(100);
} else if (someFileWasSwapped) {
TaskFactory::delayTask(10);
}
}
}
bool PersistentLogTmStoreTask::initStoresIfPossible() {
if (sdcMan.isSdCardUsable(std::nullopt)) {
stores.okStore.initializeTmStore();
stores.miscStore.initializeTmStore();
stores.notOkStore.initializeTmStore();
return true;
}
return false;
}

View File

@ -1,33 +0,0 @@
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <mission/tmtc/PersistentSingleTmStoreTask.h>
PersistentSingleTmStoreTask::PersistentSingleTmStoreTask(
object_id_t objectId, StorageManagerIF& ipcStore, PersistentTmStoreWithTmQueue& tmStore,
VirtualChannel& channel, Event eventIfDumpDone, SdCardMountedIF& sdcMan)
: TmStoreTaskBase(objectId, ipcStore, channel, sdcMan),
storeWithQueue(tmStore),
dumpContext(eventIfDumpDone) {}
ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
while (true) {
// Delay done by the check
if (not cyclicStoreCheck()) {
continue;
}
bool busy = handleOneStore(storeWithQueue, dumpContext);
if (not busy) {
TaskFactory::delayTask(100);
} else if (fileHasSwapped) {
TaskFactory::delayTask(10);
}
}
}
bool PersistentSingleTmStoreTask::initStoresIfPossible() {
if (sdcMan.isSdCardUsable(std::nullopt)) {
storeWithQueue.initializeTmStore();
return true;
}
return false;
}

View File

@ -171,7 +171,7 @@ void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) {
// Convert file time to the UNIX epoch
struct tm fileTime {};
if (pathToTime(file.path(), fileTime) != returnvalue::OK) {
sif::error << "Time extraction for " << file << "failed" << std::endl;
sif::error << "Time extraction for " << file << " failed" << std::endl;
continue;
}
time_t fileEpoch = timegm(&fileTime);
@ -212,7 +212,7 @@ ReturnValue_t PersistentTmStore::loadNextDumpFile() {
sif::error << "PersistentTmStore: Could not retrieve file size: " << e.message() << std::endl;
continue;
}
sif::debug << "Path: " << dumpParams.dirEntry.path() << std::endl;
// sif::debug << "Path: " << dumpParams.dirEntry.path() << std::endl;
// File empty or can't even read CCSDS header.
if (dumpParams.fileSize <= 6) {
@ -251,41 +251,37 @@ ReturnValue_t PersistentTmStore::loadNextDumpFile() {
return DUMP_DONE;
}
ReturnValue_t PersistentTmStore::dumpNextPacket(DirectTmSinkIF& tmSink, size_t& dumpedLen,
bool& fileHasSwapped) {
if (state == State::IDLE) {
ReturnValue_t PersistentTmStore::getNextDumpPacket(PusTmReader& reader, bool& fileHasSwapped) {
if (state == State::IDLE or dumpParams.pendingPacketDump) {
return returnvalue::FAILED;
}
PusTmReader reader(&timeReader, fileBuf.data() + dumpParams.currentSize,
fileBuf.size() - dumpParams.currentSize);
reader.setReadOnlyData(fileBuf.data() + dumpParams.currentSize,
fileBuf.size() - dumpParams.currentSize);
// CRC check to fully ensure this is a valid TM
ReturnValue_t result = reader.parseDataWithCrcCheck();
if (result == returnvalue::OK) {
result = tmSink.write(fileBuf.data() + dumpParams.currentSize, reader.getFullPacketLen());
if (result == DirectTmSinkIF::IS_BUSY) {
return result;
} else if (result != returnvalue::OK) {
// TODO: Event?
sif::error << "PersistentTmStore: Writing to TM sink failed" << std::endl;
return result;
}
dumpParams.currentSize += reader.getFullPacketLen();
dumpedLen = reader.getFullPacketLen();
if (dumpParams.currentSize >= dumpParams.fileSize) {
fileHasSwapped = true;
return loadNextDumpFile();
}
} else {
if (result != returnvalue::OK) {
sif::error << "PersistentTmStore: Parsing of PUS TM failed with code " << result << std::endl;
triggerEvent(persTmStore::POSSIBLE_FILE_CORRUPTION, result, dumpParams.currentFileUnixStamp);
// Delete the file and load next. Could use better algorithm to partially
// restore the file dump, but for now do not trust the file.
dumpedLen = 0;
std::error_code e;
std::filesystem::remove(dumpParams.dirEntry.path().c_str(), e);
fileHasSwapped = true;
return loadNextDumpFile();
}
fileHasSwapped = false;
dumpParams.pendingPacketDump = true;
return returnvalue::OK;
}
ReturnValue_t PersistentTmStore::confirmDump(const PusTmReader& reader, bool& fileHasSwapped) {
dumpParams.pendingPacketDump = false;
dumpParams.currentSize += reader.getFullPacketLen();
if (dumpParams.currentSize >= dumpParams.fileSize) {
fileHasSwapped = true;
return loadNextDumpFile();
}
fileHasSwapped = false;
return returnvalue::OK;
}

View File

@ -4,12 +4,10 @@
#include <fsfw/ipc/CommandMessageIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/storagemanager/StorageManagerIF.h>
#include <fsfw/timemanager/CdsShortTimeStamper.h>
#include <fsfw/tmstorage/TmStoreFrontendSimpleIF.h>
#include <fsfw/tmtcpacket/pus/tm/PusTmReader.h>
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
#include <mission/memory/SdCardMountedIF.h>
#include <mission/tmtc/DirectTmSinkIF.h>
#include <filesystem>
@ -57,13 +55,25 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
ReturnValue_t startDumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds);
/**
*
* @param tmSink
* @param dumpedLen
* @param fileHasSwapped
* @return DUMP_DONE if dump is finished, returnvalue::OK if dump of next packet was a success,
* and DirectTmSinkIF::IS_BUSY is TM sink is busy.
* @param tmReader: Next packet will be loaded into the PUS TM reader. A CRC check will be
* performed on the packet. If that check fails, the file is considered corrupted and will
* be deleted for now.
* @param fileHasSwapped: If the CRC check fails, the file will be deleted and a new one has to
* be loaded. The dump can reach completion during that process. If a file is swapped, this
* boolean is set to true
* @return DUMP_DONE if dump is finished, returnvalue::OK if the next packet was loaded into the
* TM reader, and the returnvalue of the file swap operation if the CRC check failed and
* a new file was loaded.
*/
ReturnValue_t dumpNextPacket(DirectTmSinkIF& tmSink, size_t& dumpedLen, bool& fileHasSwapped);
ReturnValue_t getNextDumpPacket(PusTmReader& tmReader, bool& fileHasSwapped);
/**
* Confirm the dump to advance the dump state machine.
* @param tmReader
* @param fileHasSwapped: If the confirmed dumps completes the current file, a new file will
* be loaded and this parameter will be set to true.
* @return If a file is swapped, the retrunvalue of the file swap operation.
*/
ReturnValue_t confirmDump(const PusTmReader& tmReader, bool& fileHasSwapped);
void getStartAndEndTimeCurrentOrLastDump(uint32_t& startTime, uint32_t& endTime) const;
ReturnValue_t storePacket(PusTmReader& reader);
@ -83,8 +93,6 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
MessageQueueIF* tcQueue;
State state = State::IDLE;
// PacketFilter filter;
CdsShortTimeStamper timeReader;
bool baseDirUninitialized = true;
const char* baseDir;
std::string baseName;
@ -96,6 +104,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
timeval activeFileTv{};
struct ActiveDumpParams {
bool pendingPacketDump = false;
uint32_t fromUnixTime = 0;
uint32_t untilUnixTime = 0;
uint32_t currentFileUnixStamp = 0;

View File

@ -1,96 +0,0 @@
#include "TmStoreTaskBase.h"
#include <fsfw/ipc/CommandMessageIF.h>
#include <fsfw/tasks/TaskFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <fsfw/tmstorage/TmStoreMessage.h>
#include "mission/persistentTmStoreDefs.h"
TmStoreTaskBase::TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore,
VirtualChannel& channel, SdCardMountedIF& sdcMan)
: SystemObject(objectId), ipcStore(ipcStore), channel(channel), sdcMan(sdcMan) {}
bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store,
DumpContext& dumpContext) {
ReturnValue_t result;
bool tmToStoreReceived = false;
bool tcRequestReceived = false;
bool dumpsPerformed = false;
// Store TM persistently
result = store.handleNextTm();
if (result == returnvalue::OK) {
tmToStoreReceived = true;
}
// Dump TMs when applicable
if (store.getState() == PersistentTmStore::State::DUMPING) {
size_t dumpedLen = 0;
if (not channel.isBusy()) {
tmSinkBusyCd.resetTimer();
result = store.dumpNextPacket(channel, dumpedLen, fileHasSwapped);
if (result == DirectTmSinkIF::IS_BUSY) {
sif::warning << "Unexpected PAPB busy" << std::endl;
}
if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK) and dumpedLen > 0) {
dumpContext.dumpedBytes += dumpedLen;
dumpContext.numberOfDumpedPackets += 1;
}
if (result == PersistentTmStore::DUMP_DONE) {
uint32_t startTime;
uint32_t endTime;
store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime);
triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets,
dumpContext.dumpedBytes);
dumpsPerformed = true;
} else if (result == returnvalue::OK) {
dumpsPerformed = true;
}
} else {
dumpContext.ptmeBusyCounter++;
if (dumpContext.ptmeBusyCounter == 50) {
sif::warning << "PTME busy for longer period. Dumped length so far: "
<< dumpContext.dumpedBytes << std::endl;
dumpContext.ptmeBusyCounter = 0;
}
}
if (cancelDumpCd.hasTimedOut() or tmSinkBusyCd.hasTimedOut()) {
triggerEvent(persTmStore::DUMP_WAS_CANCELLED, store.getObjectId());
store.cancelDump();
}
} else {
Command_t execCmd;
// Handle TC requests, for example deletion or retrieval requests.
result = store.handleCommandQueue(ipcStore, execCmd);
if (result == returnvalue::OK) {
if (execCmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) {
cancelDumpCd.resetTimer();
tmSinkBusyCd.resetTimer();
dumpContext.reset();
}
tcRequestReceived = true;
}
}
if (tcRequestReceived or tmToStoreReceived or dumpsPerformed) {
return true;
}
return false;
}
bool TmStoreTaskBase::cyclicStoreCheck() {
if (not storesInitialized) {
storesInitialized = initStoresIfPossible();
if (not storesInitialized) {
TaskFactory::delayTask(400);
return false;
}
} else if (sdCardCheckCd.hasTimedOut()) {
if (not sdcMan.isSdCardUsable(std::nullopt)) {
// Might be due to imminent shutdown or SD card switch.
storesInitialized = false;
TaskFactory::delayTask(100);
return false;
}
sdCardCheckCd.resetTimer();
}
return true;
}

View File

@ -1,53 +0,0 @@
#ifndef MISSION_TMTC_TMSTORETASKBASE_H_
#define MISSION_TMTC_TMSTORETASKBASE_H_
#include <fsfw/timemanager/Countdown.h>
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
#include <mission/tmtc/VirtualChannel.h>
class TmStoreTaskBase : public SystemObject {
public:
struct DumpContext {
DumpContext(Event eventIfDone) : eventIfDone(eventIfDone) {}
void reset() {
numberOfDumpedPackets = 0;
dumpedBytes = 0;
}
const Event eventIfDone;
uint32_t numberOfDumpedPackets = 0;
uint32_t dumpedBytes = 0;
uint32_t ptmeBusyCounter = 0;
};
TmStoreTaskBase(object_id_t objectId, StorageManagerIF& ipcStore, VirtualChannel& channel,
SdCardMountedIF& sdcMan);
protected:
/**
* Handling for one store. Returns if anything was done.
* @param store
* @return
*/
bool handleOneStore(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext);
/**
* Occasionally check whether SD card is okay to be used. If not, poll whether it is ready to
* be used again and re-initialize stores. Returns whether store is okay to be used.
*/
bool cyclicStoreCheck();
virtual bool initStoresIfPossible() = 0;
StorageManagerIF& ipcStore;
Countdown sdCardCheckCd = Countdown(800);
// 20 minutes are allowed as maximum dump time.
Countdown cancelDumpCd = Countdown(60 * 20 * 1000);
// If the TM sink is busy for 1 minute for whatever reason, cancel the dump.
Countdown tmSinkBusyCd = Countdown(60 * 1000);
VirtualChannel& channel;
bool storesInitialized = false;
bool fileHasSwapped = false;
SdCardMountedIF& sdcMan;
};
#endif /* MISSION_TMTC_TMSTORETASKBASE_H_ */

2
tmtc

@ -1 +1 @@
Subproject commit f2897fa6060e178ef8d11c9d29faa058896c9253
Subproject commit 523dd9b759a57c5bff2ae9221eee303dfa080558