added mutex protection for power switches
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good

This commit is contained in:
Robin Müller 2022-03-03 19:39:36 +01:00
parent 63c4095d4d
commit a7c1dafce5
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
10 changed files with 104 additions and 71 deletions

View File

@ -4,6 +4,7 @@
#include <devices/powerSwitcherList.h> #include <devices/powerSwitcherList.h>
#include <fsfw/datapool/PoolReadGuard.h> #include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/housekeeping/HousekeepingSnapshot.h> #include <fsfw/housekeeping/HousekeepingSnapshot.h>
#include <fsfw/ipc/MutexFactory.h>
#include <fsfw/ipc/QueueFactory.h> #include <fsfw/ipc/QueueFactory.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h> #include <mission/devices/devicedefinitions/GomSpacePackets.h>
@ -15,6 +16,7 @@ PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize)
cmdQueueSize(cmdQueueSize) { cmdQueueSize(cmdQueueSize) {
commandQueue = QueueFactory::instance()->createMessageQueue( commandQueue = QueueFactory::instance()->createMessageQueue(
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE);
pwrMutex = MutexFactory::instance()->createMutex();
} }
PCDUHandler::~PCDUHandler() {} PCDUHandler::~PCDUHandler() {}
@ -156,8 +158,9 @@ void PCDUHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet
void PCDUHandler::updatePdu2SwitchStates() { void PCDUHandler::updatePdu2SwitchStates() {
using namespace pcduSwitches; using namespace pcduSwitches;
PoolReadGuard rf(&pdu2HkTableDataset); PoolReadGuard rg(&pdu2HkTableDataset);
if (rf.getReadResult() == RETURN_OK) { if (rg.getReadResult() == RETURN_OK) {
MutexGuard mg(pwrMutex);
switchStates[Switches::PDU2_CH0_Q7S] = pdu2HkTableDataset.outEnabledQ7S.value; switchStates[Switches::PDU2_CH0_Q7S] = pdu2HkTableDataset.outEnabledQ7S.value;
switchStates[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8] = switchStates[Switches::PDU2_CH1_PL_PCDU_BATT_0_14V8] =
pdu2HkTableDataset.outEnabledPlPCDUCh1.value; pdu2HkTableDataset.outEnabledPlPCDUCh1.value;
@ -181,9 +184,10 @@ void PCDUHandler::updatePdu2SwitchStates() {
} }
void PCDUHandler::updatePdu1SwitchStates() { void PCDUHandler::updatePdu1SwitchStates() {
if (pdu1HkTableDataset.read() == RETURN_OK) { using namespace pcduSwitches;
using namespace pcduSwitches; PoolReadGuard rg(&pdu1HkTableDataset);
PoolReadGuard rf(&pdu1HkTableDataset); if (rg.getReadResult() == RETURN_OK) {
MutexGuard mg(pwrMutex);
switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pdu1HkTableDataset.outEnabledTCSBoard3V3.value; switchStates[Switches::PDU1_CH0_TCS_BOARD_3V3] = pdu1HkTableDataset.outEnabledTCSBoard3V3.value;
switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pdu1HkTableDataset.outEnabledSyrlinks.value; switchStates[Switches::PDU1_CH1_SYRLINKS_12V] = pdu1HkTableDataset.outEnabledSyrlinks.value;
switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] = switchStates[Switches::PDU1_CH2_STAR_TRACKER_5V] =
@ -352,7 +356,10 @@ ReturnValue_t PCDUHandler::getSwitchState(uint8_t switchNr) const {
sif::debug << "PCDUHandler::getSwitchState: Invalid switch number" << std::endl; sif::debug << "PCDUHandler::getSwitchState: Invalid switch number" << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
if (switchStates[switchNr] == 1) { pwrMutex->lockMutex();
uint8_t currentState = switchStates[switchNr];
pwrMutex->unlockMutex();
if (currentState == 1) {
return PowerSwitchIF::SWITCH_ON; return PowerSwitchIF::SWITCH_ON;
} else { } else {
return PowerSwitchIF::SWITCH_OFF; return PowerSwitchIF::SWITCH_OFF;

View File

@ -47,6 +47,7 @@ class PCDUHandler : public PowerSwitchIF,
private: private:
uint32_t pstIntervalMs = 0; uint32_t pstIntervalMs = 0;
MutexIF* pwrMutex = nullptr;
/** Housekeeping manager. Handles updates of local pool variables. */ /** Housekeeping manager. Handles updates of local pool variables. */
LocalDataPoolManager poolManager; LocalDataPoolManager poolManager;

View File

@ -2,9 +2,8 @@
#define MISSION_DEVICES_RADIATIONSENSORHANDLER_H_ #define MISSION_DEVICES_RADIATIONSENSORHANDLER_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h> #include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/devices/devicedefinitions/RadSensorDefinitions.h>
#include <fsfw_hal/common/gpio/GpioIF.h> #include <fsfw_hal/common/gpio/GpioIF.h>
#include <mission/devices/devicedefinitions/RadSensorDefinitions.h>
/** /**
* @brief This is the device handler class for radiation sensor on the OBC IF Board. The * @brief This is the device handler class for radiation sensor on the OBC IF Board. The

View File

@ -174,35 +174,36 @@ void AcsBoardAssembly::powerStateMachine(Mode_t mode, Submode_t submode) {
if (state == States::IDLE or state == States::SWITCHING_POWER) { if (state == States::IDLE or state == States::SWITCHING_POWER) {
switchStateA = pwrSwitcher->getSwitchState(SWITCH_A); switchStateA = pwrSwitcher->getSwitchState(SWITCH_A);
switchStateB = pwrSwitcher->getSwitchState(SWITCH_B); switchStateB = pwrSwitcher->getSwitchState(SWITCH_B);
if (mode == MODE_OFF) { } else {
if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { return;
state = States::MODE_COMMANDING; }
return; if (mode == MODE_OFF) {
if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) {
state = States::MODE_COMMANDING;
return;
}
} else {
switch (submode) {
case (A_SIDE): {
if (switchStateA == PowerSwitchIF::SWITCH_ON and
switchStateB == PowerSwitchIF::SWITCH_OFF) {
state = States::MODE_COMMANDING;
return;
}
break;
} }
} else { case (B_SIDE): {
switch (submode) { if (switchStateA == PowerSwitchIF::SWITCH_OFF and
case (A_SIDE): { switchStateB == PowerSwitchIF::SWITCH_ON) {
if (switchStateA == PowerSwitchIF::SWITCH_ON and state = States::MODE_COMMANDING;
switchStateB == PowerSwitchIF::SWITCH_OFF) { return;
state = States::MODE_COMMANDING;
return;
}
break;
} }
case (B_SIDE): { break;
if (switchStateA == PowerSwitchIF::SWITCH_OFF and }
switchStateB == PowerSwitchIF::SWITCH_ON) { case (DUAL_MODE): {
state = States::MODE_COMMANDING; if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_ON) {
return; state = States::MODE_COMMANDING;
} return;
break;
}
case (DUAL_MODE): {
if (switchStateA == PowerSwitchIF::SWITCH_ON and
switchStateB == PowerSwitchIF::SWITCH_ON) {
state = States::MODE_COMMANDING;
return;
}
} }
} }
} }

View File

@ -56,40 +56,61 @@ void SusAssembly::powerStateMachine(Mode_t mode, Submode_t submode) {
ReturnValue_t switchStateNom = RETURN_OK; ReturnValue_t switchStateNom = RETURN_OK;
ReturnValue_t switchStateRed = RETURN_OK; ReturnValue_t switchStateRed = RETURN_OK;
if (state == States::IDLE or state == States::SWITCHING_POWER) { if (state == States::IDLE or state == States::SWITCHING_POWER) {
switchStateNom = pwrSwitcher->getSwitchState(pcduSwitches::PDU1_CH4_SUS_NOMINAL_3V3); switchStateNom = pwrSwitcher->getSwitchState(SWITCH_NOM);
switchStateRed = pwrSwitcher->getSwitchState(pcduSwitches::PDU2_CH4_SUS_REDUNDANT_3V3); switchStateRed = pwrSwitcher->getSwitchState(SWITCH_RED);
if (mode == MODE_OFF) { } else {
if (switchStateNom == PowerSwitchIF::SWITCH_OFF and return;
switchStateRed == PowerSwitchIF::SWITCH_OFF) { }
state = States::MODE_COMMANDING; if (mode == MODE_OFF) {
return; if (switchStateNom == PowerSwitchIF::SWITCH_OFF and
} switchStateRed == PowerSwitchIF::SWITCH_OFF) {
} else { state = States::MODE_COMMANDING;
switch (submode) { return;
case (NOMINAL): { }
if (switchStateNom == PowerSwitchIF::SWITCH_ON and } else {
switchStateRed == PowerSwitchIF::SWITCH_OFF) { if (state == States::IDLE) {
state = States::MODE_COMMANDING; if (mode == MODE_OFF) {
return; if (switchStateNom != PowerSwitchIF::SWITCH_OFF) {
} pwrSwitcher->sendSwitchCommand(SWITCH_NOM, false);
break;
} }
case (REDUNDANT): { if (switchStateRed != PowerSwitchIF::SWITCH_OFF) {
if (switchStateNom == PowerSwitchIF::SWITCH_OFF and pwrSwitcher->sendSwitchCommand(SWITCH_RED, false);
switchStateRed == PowerSwitchIF::SWITCH_ON) {
state = States::MODE_COMMANDING;
return;
}
break;
} }
case (DUAL_MODE): { } else {
if (switchStateNom == PowerSwitchIF::SWITCH_ON and switch (submode) {
switchStateRed == PowerSwitchIF::SWITCH_ON) { case (NOMINAL): {
state = States::MODE_COMMANDING; if (switchStateNom != PowerSwitchIF::SWITCH_ON) {
return; pwrSwitcher->sendSwitchCommand(SWITCH_NOM, true);
}
if (switchStateRed != PowerSwitchIF::SWITCH_OFF) {
pwrSwitcher->sendSwitchCommand(SWITCH_RED, false);
}
break;
}
case (REDUNDANT): {
if (switchStateRed != PowerSwitchIF::SWITCH_OFF) {
pwrSwitcher->sendSwitchCommand(SWITCH_RED, false);
}
if (switchStateNom != PowerSwitchIF::SWITCH_ON) {
pwrSwitcher->sendSwitchCommand(SWITCH_NOM, true);
}
break;
}
case (DUAL_MODE): {
if (switchStateNom != PowerSwitchIF::SWITCH_ON) {
pwrSwitcher->sendSwitchCommand(SWITCH_NOM, true);
}
if (switchStateRed != PowerSwitchIF::SWITCH_ON) {
pwrSwitcher->sendSwitchCommand(SWITCH_RED, true);
}
break;
} }
} }
} }
state = States::SWITCHING_POWER;
}
if (state == States::SWITCHING_POWER) {
// TODO: Could check for a timeout (temporal or cycles) here and resend command
} }
} }
} }

View File

@ -1,6 +1,7 @@
#ifndef MISSION_SYSTEM_SUSASSEMBLY_H_ #ifndef MISSION_SYSTEM_SUSASSEMBLY_H_
#define MISSION_SYSTEM_SUSASSEMBLY_H_ #define MISSION_SYSTEM_SUSASSEMBLY_H_
#include <devices/powerSwitcherList.h>
#include <fsfw/devicehandlers/AssemblyBase.h> #include <fsfw/devicehandlers/AssemblyBase.h>
struct SusAssHelper { struct SusAssHelper {
@ -25,7 +26,10 @@ class SusAssembly : AssemblyBase {
private: private:
enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE; enum class States { IDLE, SWITCHING_POWER, MODE_COMMANDING } state = States::IDLE;
static constexpr pcduSwitches::Switches SWITCH_NOM =
pcduSwitches::Switches::PDU1_CH4_SUS_NOMINAL_3V3;
static constexpr pcduSwitches::Switches SWITCH_RED =
pcduSwitches::Switches::PDU2_CH4_SUS_REDUNDANT_3V3;
FixedArrayList<ModeListEntry, NUMBER_SUN_SENSORS> modeTable; FixedArrayList<ModeListEntry, NUMBER_SUN_SENSORS> modeTable;
SusAssHelper helper; SusAssHelper helper;

2
tmtc

@ -1 +1 @@
Subproject commit 37c1a68da1b465514e84403b06ce40d035e4ad88 Subproject commit 07601b734eec162771251e8e5f5fae16d20f1655

View File

@ -15,10 +15,12 @@ class EventManagerMock : public EventManager {
void clearEventList(); void clearEventList();
bool isEventInEventList(object_id_t object, Event event); bool isEventInEventList(object_id_t object, Event event);
bool isEventInEventList(object_id_t object, Event event, uint32_t parameter1, uint32_t parameter2); bool isEventInEventList(object_id_t object, Event event, uint32_t parameter1,
uint32_t parameter2);
bool isEventInEventList(object_id_t object, EventId_t eventId); bool isEventInEventList(object_id_t object, EventId_t eventId);
bool isEventInEventList(object_id_t object, EventId_t eventId, uint32_t parameter1, uint32_t parameter2); bool isEventInEventList(object_id_t object, EventId_t eventId, uint32_t parameter1,
uint32_t parameter2);
private: private:
std::list<EventMessage> eventList; std::list<EventMessage> eventList;

View File

@ -2,7 +2,6 @@
#include <fsfw/objectmanager/frameworkObjects.h> #include <fsfw/objectmanager/frameworkObjects.h>
HouseKeepingMock::HouseKeepingMock() : SystemObject(objects::PUS_SERVICE_3_HOUSEKEEPING) {} HouseKeepingMock::HouseKeepingMock() : SystemObject(objects::PUS_SERVICE_3_HOUSEKEEPING) {}
MessageQueueId_t HouseKeepingMock::getHkQueue() const { return MessageQueueIF::NO_QUEUE; } MessageQueueId_t HouseKeepingMock::getHkQueue() const { return MessageQueueIF::NO_QUEUE; }

View File

@ -2,8 +2,8 @@
#define HOUSEKEEPINGMOCK_H_ #define HOUSEKEEPINGMOCK_H_
#include <fsfw/housekeeping/AcceptsHkPacketsIF.h> #include <fsfw/housekeeping/AcceptsHkPacketsIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/ipc/MessageQueueIF.h> #include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/objectmanager/SystemObject.h>
class HouseKeepingMock : public SystemObject, public AcceptsHkPacketsIF { class HouseKeepingMock : public SystemObject, public AcceptsHkPacketsIF {
public: public:
@ -12,5 +12,4 @@ class HouseKeepingMock : public SystemObject, public AcceptsHkPacketsIF {
virtual MessageQueueId_t getHkQueue() const; virtual MessageQueueId_t getHkQueue() const;
}; };
#endif /*HOUSEKEEPINGMOCK_H_*/ #endif /*HOUSEKEEPINGMOCK_H_*/