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-21 14:55:55 +01:00
commit 0fdc79df5e
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
10 changed files with 42 additions and 10 deletions

View File

@ -22,11 +22,13 @@ will consitute of a breaking change warranting a new major release:
the `MEKF` on its own once. This way, there will not be an event spam and operators will have
to look into the reason of wrong outputs. To restore the reset ability, an action command has
been added.
- Contingency handling for non-working I2C bus bug. Reboot the system if the I2C is not working.
## Fixed
- Fixed transition for dual power lane assemblies: When going from dual side submode to single side
submode, perform logical commanding first, similarly to when going to OFF mode.
- GPS time is only set to valid if at least one satellite is in view.
## Changed
@ -36,7 +38,8 @@ will consitute of a breaking change warranting a new major release:
consit of just one digit.
- EIVE system fallback and COM system fallback: Perform general subsystem handling first, then
event reception, and finally any new transition handling.
- Safe mode controller failure event now only triggers once per minute.
# [v1.38.0] 2023-03-17
eive-tmtc: v2.19.2

View File

@ -31,14 +31,15 @@
xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP;
xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY;
CoreController::CoreController(object_id_t objectId)
CoreController::CoreController(object_id_t objectId, const std::atomic_uint16_t& i2cErrors)
: ExtendedControllerBase(objectId, 5),
cmdExecutor(4096),
cmdReplyBuf(4096, true),
cmdRepliesSizes(128),
opDivider5(5),
opDivider10(10),
hkSet(this) {
hkSet(this),
i2cErrors(i2cErrors) {
cmdExecutor.setRingBuffer(&cmdReplyBuf, &cmdRepliesSizes);
try {
sdcMan = SdCardManager::instance();
@ -107,6 +108,12 @@ void CoreController::performControlOperation() {
sdStateMachine();
performMountedSdCardOperations();
readHkData();
if(i2cErrors >= 5) {
bool protOpPerformed = false;
triggerEvent(I2C_UNAVAILABLE_REBOOT);
gracefulShutdownTasks(CURRENT_CHIP, CURRENT_COPY, protOpPerformed);
std::system("xsc_boot_copy -r");
}
if (shellCmdIsExecuting) {
bool replyReceived = false;
// TODO: We could read the data in the ring buffer and send it as an action data reply.

View File

@ -15,6 +15,7 @@
#include "fsfw/controller/ExtendedControllerBase.h"
#include "mission/devices/devicedefinitions/GPSDefinitions.h"
#include "mission/trace.h"
#include <atomic>
class Timer;
class SdCardManager;
@ -131,8 +132,9 @@ class CoreController : public ExtendedControllerBase {
//! P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1.
//! P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.
static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
static constexpr Event I2C_UNAVAILABLE_REBOOT = event::makeEvent(SUBSYSTEM_ID, 10, severity::MEDIUM);
CoreController(object_id_t objectId);
CoreController(object_id_t objectId, const std::atomic_uint16_t& i2cErrors);
virtual ~CoreController();
ReturnValue_t initialize() override;
@ -262,6 +264,7 @@ class CoreController : public ExtendedControllerBase {
PoolEntry<float> plVoltageEntry = PoolEntry<float>(0.0);
core::HkSet hkSet;
const std::atomic_uint16_t& i2cErrors;
#if OBSW_SD_CARD_MUST_BE_ON == 1
bool remountAttemptFlag = true;

View File

@ -123,6 +123,7 @@ using gpio::Levels;
ResetArgs RESET_ARGS_GNSS;
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
std::atomic_uint16_t I2C_FATAL_ERRORS = 0;
void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::PUS_DISTRIBUTOR = objects::PUS_PACKET_DISTRIBUTOR;
@ -953,7 +954,7 @@ void ObjectFactory::createImtqComponents(PowerSwitchIF* pwrSwitcher) {
auto* imtqAssy = new ImtqAssembly(objects::IMTQ_ASSY);
imtqAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
new ImtqPollingTask(objects::IMTQ_POLLING);
new ImtqPollingTask(objects::IMTQ_POLLING, I2C_FATAL_ERRORS);
I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, imtq::MAX_REPLY_SIZE, q7s::I2C_PL_EIVE);
auto imtqHandler = new ImtqHandler(objects::IMTQ_HANDLER, objects::IMTQ_POLLING, imtqI2cCookie,
power::Switches::PDU1_CH3_MGT_5V);

View File

@ -12,6 +12,7 @@
#include <mission/tmtc/PusTmFunnel.h>
#include <string>
#include <atomic>
class LinuxLibgpioIF;
class SerialComIF;
@ -22,6 +23,8 @@ class HealthTableIF;
class AcsBoardAssembly;
class GpioIF;
extern std::atomic_uint16_t I2C_FATAL_ERRORS;
namespace ObjectFactory {
struct CcsdsComponentArgs {

View File

@ -38,7 +38,7 @@ void ObjectFactory::produce(void* args) {
q7s::gpioCallbacks::initSpiCsDecoder(gpioComIF);
gpioCallbacks::disableAllDecoder(gpioComIF);
new CoreController(objects::CORE_CONTROLLER);
new CoreController(objects::CORE_CONTROLLER, I2C_FATAL_ERRORS);
createPcduComponents(gpioComIF, &pwrSwitcher);
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);

View File

@ -302,7 +302,10 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
// TIME is set for every message, no need for a counter
bool timeValid = false;
if (TIME_SET == (TIME_SET & gps.set)) {
timeValid = true;
// To prevent totally incorrect times from being declared valid.
if(gpsSet.satInView.isValid() and gpsSet.satInView.value >= 1) {
timeValid = true;
}
timeval time = {};
#if LIBGPS_VERSION_MINOR <= 17
gpsSet.unixSeconds.value = std::floor(gps.fix.time);

View File

@ -10,7 +10,9 @@
#include "fsfw/FSFW.h"
ImtqPollingTask::ImtqPollingTask(object_id_t imtqPollingTask) : SystemObject(imtqPollingTask) {
ImtqPollingTask::ImtqPollingTask(object_id_t imtqPollingTask,
std::atomic_uint16_t& i2cFatalErrors): SystemObject(imtqPollingTask),
i2cFatalErrors(i2cFatalErrors) {
semaphore = SemaphoreFactory::instance()->createBinarySemaphore();
semaphore->acquire();
ipcLock = MutexFactory::instance()->createMutex();
@ -427,12 +429,20 @@ ReturnValue_t ImtqPollingTask::performI2cFullRequest(uint8_t* reply, size_t repl
if (ioctl(fd, I2C_SLAVE, i2cAddr) < 0) {
sif::warning << "Opening IMTQ slave device failed with code " << errno << ": "
<< strerror(errno) << std::endl;
if(errno == EBUSY) {
i2cFatalErrors++;
}
}
int written = write(fd, cmdBuf.data(), cmdLen);
if (written < 0) {
sif::error << "IMTQ: Failed to send with error code " << errno
<< ". Error description: " << strerror(errno) << std::endl;
// This is a weird issue which sometimes occurs on debug builds. All I2C buses are busy
// for all writes,
if(errno == EBUSY) {
i2cFatalErrors++;
}
return returnvalue::FAILED;
} else if (static_cast<size_t>(written) != cmdLen) {
sif::error << "IMTQ: Could not write all bytes" << std::endl;

View File

@ -8,12 +8,13 @@
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
#include "mission/devices/devicedefinitions/imtqHelpers.h"
#include <atomic>
class ImtqPollingTask : public SystemObject,
public ExecutableObjectIF,
public DeviceCommunicationIF {
public:
ImtqPollingTask(object_id_t imtqPollingTask);
ImtqPollingTask(object_id_t imtqPollingTask, std::atomic_uint16_t& i2cFatalErrors);
ReturnValue_t performOperation(uint8_t operationCode) override;
ReturnValue_t initialize() override;
@ -28,6 +29,7 @@ class ImtqPollingTask : public SystemObject,
ReturnValue_t comStatus = returnvalue::OK;
MutexIF* ipcLock;
MutexIF* bufLock;
std::atomic_uint16_t& i2cFatalErrors;
I2cCookie* i2cCookie = nullptr;
const char* i2cDev = nullptr;
address_t i2cAddr = 0;

View File

@ -186,7 +186,7 @@ void AcsController::performSafe() {
safeCtrlFailureFlag = true;
}
safeCtrlFailureCounter++;
if (safeCtrlFailureCounter > 50) {
if (safeCtrlFailureCounter > 150) {
safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0;
}