Merge pull request 'refactor power module' (#590) from eive/fsfw:mueller/refactor-power-switch-if-etc into development
Reviewed-on: fsfw/fsfw#590
This commit is contained in:
commit
a83b86ccd2
33
CHANGELOG.md
33
CHANGELOG.md
@ -25,19 +25,42 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
||||||
- HAL Devicehandlers: Periodic printout is run-time configurable now
|
- HAL Devicehandlers: Periodic printout is run-time configurable now
|
||||||
- `oneShotAction` flag in the `TestTask` class is not static anymore
|
- `oneShotAction` flag in the `TestTask` class is not static anymore
|
||||||
- HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations
|
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585
|
|
||||||
- IPC Message Queue Handling: Allow passing an optional `MqArgs` argument into the MessageQueue
|
- IPC Message Queue Handling: Allow passing an optional `MqArgs` argument into the MessageQueue
|
||||||
creation call. It allows passing context information and an arbitrary user argument into
|
creation call. It allows passing context information and an arbitrary user argument into
|
||||||
the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs
|
the message queue. Also streamlined and simplified `MessageQueue` implementation for all OSALs
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/583
|
||||||
- Clock:
|
|
||||||
|
### HAL
|
||||||
|
|
||||||
|
- HAL Linux SPI: Set the Clock Default State when setting new SPI speed
|
||||||
|
and mode
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/573
|
||||||
|
- GPIO HAL: `Direction`, `GpioOperation` and `Levels` are enum classes now, which prevents
|
||||||
|
name clashes with Windows defines.
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/572
|
||||||
|
- HAL Linux Uart: Baudrate and bits per word are enums now, avoiding misconfigurations
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/585
|
||||||
|
|
||||||
|
### Time
|
||||||
|
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/584 and
|
||||||
|
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/593
|
||||||
|
|
||||||
- `timeval` to `TimeOfDay_t`
|
- `timeval` to `TimeOfDay_t`
|
||||||
- Added Mutex for gmtime calls: (compare http://www.opengate.at/blog/2020/01/timeless/)
|
- Added Mutex for gmtime calls: (compare http://www.opengate.at/blog/2020/01/timeless/)
|
||||||
- Moved the statics used by Clock in ClockCommon.cpp to this file
|
- Moved the statics used by Clock in ClockCommon.cpp to this file
|
||||||
- Better check for leap seconds
|
- Better check for leap seconds
|
||||||
- Added Unittests for Clock (only getter)
|
- Added Unittests for Clock (only getter)
|
||||||
|
|
||||||
|
### Power
|
||||||
|
|
||||||
|
- `PowerSwitchIF`: Remove `const` specifier from `sendSwitchCommand` and `sendFuseOnCommand` and
|
||||||
|
also specify a `ReturnValue_t` return type
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
||||||
|
- Extend `PowerSwitcher` module to optionally check current state when calling `turnOn` or
|
||||||
|
`turnOff`. Tis can be helpful to avoid commanding switches which do not need commanding
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
||||||
|
|
||||||
## Removed
|
## Removed
|
||||||
|
|
||||||
- Removed the `HkSwitchHelper`. This module should not be needed anymore, now that the local
|
- Removed the `HkSwitchHelper`. This module should not be needed anymore, now that the local
|
||||||
@ -66,6 +89,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/559
|
||||||
- Added ETL dependency and improved library dependency management
|
- Added ETL dependency and improved library dependency management
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/592
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/592
|
||||||
|
- Add a `DummyPowerSwitcher` module which can be useful for test setups when no PCDU is available
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
||||||
|
- New typedef for switcher type
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/590
|
||||||
- `Subsystem`: New API to add table and sequence entries
|
- `Subsystem`: New API to add table and sequence entries
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
target_sources(${LIB_FSFW_NAME}
|
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||||
PRIVATE
|
|
||||||
Fuse.cpp
|
Fuse.cpp
|
||||||
PowerComponent.cpp
|
PowerComponent.cpp
|
||||||
PowerSensor.cpp
|
PowerSensor.cpp
|
||||||
PowerSwitcher.cpp
|
PowerSwitcher.cpp
|
||||||
|
DummyPowerSwitcher.cpp
|
||||||
)
|
)
|
47
src/fsfw/power/DummyPowerSwitcher.cpp
Normal file
47
src/fsfw/power/DummyPowerSwitcher.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include "DummyPowerSwitcher.h"
|
||||||
|
|
||||||
|
DummyPowerSwitcher::DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwitches,
|
||||||
|
size_t numberOfFuses, bool registerGlobally,
|
||||||
|
uint32_t switchDelayMs)
|
||||||
|
: SystemObject(objectId, registerGlobally),
|
||||||
|
switcherList(numberOfSwitches),
|
||||||
|
fuseList(numberOfFuses),
|
||||||
|
switchDelayMs(switchDelayMs) {}
|
||||||
|
|
||||||
|
void DummyPowerSwitcher::setInitialSwitcherList(std::vector<ReturnValue_t> switcherList) {
|
||||||
|
this->switcherList = switcherList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DummyPowerSwitcher::setInitialFusesList(std::vector<ReturnValue_t> fuseList) {
|
||||||
|
this->fuseList = fuseList;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t DummyPowerSwitcher::sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) {
|
||||||
|
if (switchNr < switcherList.capacity()) {
|
||||||
|
switcherList[switchNr] = onOff;
|
||||||
|
}
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t DummyPowerSwitcher::sendFuseOnCommand(uint8_t fuseNr) {
|
||||||
|
if (fuseNr < fuseList.capacity()) {
|
||||||
|
fuseList[fuseNr] = FUSE_ON;
|
||||||
|
}
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t DummyPowerSwitcher::getSwitchState(power::Switch_t switchNr) const {
|
||||||
|
if (switchNr < switcherList.capacity()) {
|
||||||
|
return switcherList[switchNr];
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t DummyPowerSwitcher::getFuseState(uint8_t fuseNr) const {
|
||||||
|
if (fuseNr < fuseList.capacity()) {
|
||||||
|
return fuseList[fuseNr];
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DummyPowerSwitcher::getSwitchDelayMs(void) const { return switchDelayMs; }
|
38
src/fsfw/power/DummyPowerSwitcher.h
Normal file
38
src/fsfw/power/DummyPowerSwitcher.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef FSFW_SRC_FSFW_POWER_DUMMYPOWERSWITCHER_H_
|
||||||
|
#define FSFW_SRC_FSFW_POWER_DUMMYPOWERSWITCHER_H_
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "PowerSwitchIF.h"
|
||||||
|
#include "definitions.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This component can be used to simulate a power switcher like a
|
||||||
|
* Power Control Distribution Unit (PCDU)
|
||||||
|
* @details
|
||||||
|
* The dummy switcher will simply cache the commanded fuse and switch states and return them
|
||||||
|
* in the according switch getter functions. In that sense, it simulates an ideal PCDU.
|
||||||
|
*/
|
||||||
|
class DummyPowerSwitcher : public SystemObject, public PowerSwitchIF {
|
||||||
|
public:
|
||||||
|
DummyPowerSwitcher(object_id_t objectId, size_t numberOfSwitches, size_t numberOfFuses,
|
||||||
|
bool registerGlobally = true, uint32_t switchDelayMs = 5000);
|
||||||
|
|
||||||
|
void setInitialSwitcherList(std::vector<ReturnValue_t> switcherList);
|
||||||
|
void setInitialFusesList(std::vector<ReturnValue_t> switcherList);
|
||||||
|
|
||||||
|
virtual ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) override;
|
||||||
|
virtual ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
|
||||||
|
virtual ReturnValue_t getSwitchState(power::Switch_t switchNr) const override;
|
||||||
|
virtual ReturnValue_t getFuseState(uint8_t fuseNr) const override;
|
||||||
|
virtual uint32_t getSwitchDelayMs(void) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<ReturnValue_t> switcherList;
|
||||||
|
std::vector<ReturnValue_t> fuseList;
|
||||||
|
uint32_t switchDelayMs = 5000;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_SRC_FSFW_POWER_DUMMYPOWERSWITCHER_H_ */
|
@ -34,14 +34,14 @@ class Fuse : public SystemObject,
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1;
|
||||||
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(
|
//! PSS detected that current on a fuse is totally out of bounds.
|
||||||
1, severity::LOW); //!< PSS detected that current on a fuse is totally out of bounds.
|
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(1, severity::LOW);
|
||||||
static const Event FUSE_WENT_OFF =
|
//! PSS detected a fuse that went off.
|
||||||
MAKE_EVENT(2, severity::LOW); //!< PSS detected a fuse that went off.
|
static const Event FUSE_WENT_OFF = MAKE_EVENT(2, severity::LOW);
|
||||||
static const Event POWER_ABOVE_HIGH_LIMIT =
|
//! PSS detected a fuse that violates its limits.
|
||||||
MAKE_EVENT(4, severity::LOW); //!< PSS detected a fuse that violates its limits.
|
static const Event POWER_ABOVE_HIGH_LIMIT = MAKE_EVENT(4, severity::LOW);
|
||||||
static const Event POWER_BELOW_LOW_LIMIT =
|
//! PSS detected a fuse that violates its limits.
|
||||||
MAKE_EVENT(5, severity::LOW); //!< PSS detected a fuse that violates its limits.
|
static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, severity::LOW);
|
||||||
|
|
||||||
typedef std::list<PowerComponentIF *> DeviceList;
|
typedef std::list<PowerComponentIF *> DeviceList;
|
||||||
Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,
|
Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,
|
||||||
|
@ -15,7 +15,8 @@ PowerSensor::PowerSensor(object_id_t objectId, sid_t setId, VariableIds ids, Def
|
|||||||
limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh),
|
limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh),
|
||||||
voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount,
|
voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount,
|
||||||
limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) {
|
limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue();
|
commandQueue =
|
||||||
|
QueueFactory::instance()->createMessageQueue(3, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "../events/Event.h"
|
#include "../events/Event.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||||
|
#include "definitions.h"
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @brief This interface defines a connection to a device that is capable of
|
* @brief This interface defines a connection to a device that is capable of
|
||||||
@ -37,11 +38,11 @@ class PowerSwitchIF : public HasReturnvaluesIF {
|
|||||||
* @param switchNr
|
* @param switchNr
|
||||||
* @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON
|
* @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON
|
||||||
*/
|
*/
|
||||||
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const = 0;
|
virtual ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) = 0;
|
||||||
/**
|
/**
|
||||||
* Sends a command to the Power Unit to enable a certain fuse.
|
* Sends a command to the Power Unit to enable a certain fuse.
|
||||||
*/
|
*/
|
||||||
virtual void sendFuseOnCommand(uint8_t fuseNr) const = 0;
|
virtual ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the state of the Switches.
|
* get the state of the Switches.
|
||||||
@ -51,7 +52,7 @@ class PowerSwitchIF : public HasReturnvaluesIF {
|
|||||||
* - @c SWITCH_OFF if the specified switch is off.
|
* - @c SWITCH_OFF if the specified switch is off.
|
||||||
* - @c RETURN_FAILED if an error occured
|
* - @c RETURN_FAILED if an error occured
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getSwitchState(uint8_t switchNr) const = 0;
|
virtual ReturnValue_t getSwitchState(power::Switch_t switchNr) const = 0;
|
||||||
/**
|
/**
|
||||||
* get state of a fuse.
|
* get state of a fuse.
|
||||||
* @param fuseNr
|
* @param fuseNr
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
#include "fsfw/power/PowerSwitcher.h"
|
#include "fsfw/power/PowerSwitcher.h"
|
||||||
|
|
||||||
|
#include "definitions.h"
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2,
|
PowerSwitcher::PowerSwitcher(PowerSwitchIF* switcher, power::Switch_t setSwitch1,
|
||||||
PowerSwitcher::State_t setStartState)
|
power::Switch_t setSwitch2, PowerSwitcher::State_t setStartState)
|
||||||
: state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2) {}
|
: power(switcher), state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2) {}
|
||||||
|
|
||||||
ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) {
|
|
||||||
power = ObjectManager::instance()->get<PowerSwitchIF>(powerSwitchId);
|
|
||||||
if (power == nullptr) {
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PowerSwitcher::getStateOfSwitches() {
|
ReturnValue_t PowerSwitcher::getStateOfSwitches() {
|
||||||
SwitchReturn_t result = howManySwitches();
|
SwitchReturn_t result = howManySwitches();
|
||||||
@ -52,18 +45,37 @@ void PowerSwitcher::commandSwitches(ReturnValue_t onOff) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerSwitcher::turnOn() {
|
void PowerSwitcher::turnOn(bool checkCurrentState) {
|
||||||
|
if (checkCurrentState) {
|
||||||
|
if (getStateOfSwitches() == PowerSwitchIF::SWITCH_ON) {
|
||||||
|
state = SWITCH_IS_ON;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
commandSwitches(PowerSwitchIF::SWITCH_ON);
|
commandSwitches(PowerSwitchIF::SWITCH_ON);
|
||||||
state = WAIT_ON;
|
state = WAIT_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerSwitcher::turnOff() {
|
void PowerSwitcher::turnOff(bool checkCurrentState) {
|
||||||
|
if (checkCurrentState) {
|
||||||
|
if (getStateOfSwitches() == PowerSwitchIF::SWITCH_OFF) {
|
||||||
|
state = SWITCH_IS_OFF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
commandSwitches(PowerSwitchIF::SWITCH_OFF);
|
commandSwitches(PowerSwitchIF::SWITCH_OFF);
|
||||||
state = WAIT_OFF;
|
state = WAIT_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PowerSwitcher::active() {
|
||||||
|
if (state == WAIT_OFF or state == WAIT_ON) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
PowerSwitcher::SwitchReturn_t PowerSwitcher::howManySwitches() {
|
PowerSwitcher::SwitchReturn_t PowerSwitcher::howManySwitches() {
|
||||||
if (secondSwitch == NO_SWITCH) {
|
if (secondSwitch == power::NO_SWITCH) {
|
||||||
return ONE_SWITCH;
|
return ONE_SWITCH;
|
||||||
} else {
|
} else {
|
||||||
return TWO_SWITCHES;
|
return TWO_SWITCHES;
|
||||||
|
@ -14,28 +14,29 @@ class PowerSwitcher : public HasReturnvaluesIF {
|
|||||||
SWITCH_IS_OFF,
|
SWITCH_IS_OFF,
|
||||||
SWITCH_IS_ON,
|
SWITCH_IS_ON,
|
||||||
};
|
};
|
||||||
State_t state;
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER;
|
static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER;
|
||||||
static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1);
|
static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1);
|
||||||
static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2);
|
static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2);
|
||||||
PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH,
|
PowerSwitcher(PowerSwitchIF* switcher, power::Switch_t setSwitch1,
|
||||||
|
power::Switch_t setSwitch2 = power::NO_SWITCH,
|
||||||
State_t setStartState = SWITCH_IS_OFF);
|
State_t setStartState = SWITCH_IS_OFF);
|
||||||
ReturnValue_t initialize(object_id_t powerSwitchId);
|
void turnOn(bool checkCurrentState = true);
|
||||||
void turnOn();
|
void turnOff(bool checkCurrentState = true);
|
||||||
void turnOff();
|
bool active();
|
||||||
void doStateMachine();
|
void doStateMachine();
|
||||||
State_t getState();
|
State_t getState();
|
||||||
ReturnValue_t checkSwitchState();
|
ReturnValue_t checkSwitchState();
|
||||||
uint32_t getSwitchDelay();
|
uint32_t getSwitchDelay();
|
||||||
uint8_t getFirstSwitch() const;
|
power::Switch_t getFirstSwitch() const;
|
||||||
uint8_t getSecondSwitch() const;
|
power::Switch_t getSecondSwitch() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t firstSwitch;
|
|
||||||
uint8_t secondSwitch;
|
|
||||||
PowerSwitchIF* power = nullptr;
|
PowerSwitchIF* power = nullptr;
|
||||||
|
State_t state;
|
||||||
|
power::Switch_t firstSwitch = power::NO_SWITCH;
|
||||||
|
power::Switch_t secondSwitch = power::NO_SWITCH;
|
||||||
|
|
||||||
static const uint8_t NO_SWITCH = 0xFF;
|
|
||||||
enum SwitchReturn_t { ONE_SWITCH = 1, TWO_SWITCHES = 2 };
|
enum SwitchReturn_t { ONE_SWITCH = 1, TWO_SWITCHES = 2 };
|
||||||
ReturnValue_t getStateOfSwitches();
|
ReturnValue_t getStateOfSwitches();
|
||||||
void commandSwitches(ReturnValue_t onOff);
|
void commandSwitches(ReturnValue_t onOff);
|
||||||
|
13
src/fsfw/power/definitions.h
Normal file
13
src/fsfw/power/definitions.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef FSFW_SRC_FSFW_POWER_DEFINITIONS_H_
|
||||||
|
#define FSFW_SRC_FSFW_POWER_DEFINITIONS_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace power {
|
||||||
|
|
||||||
|
using Switch_t = uint8_t;
|
||||||
|
static constexpr Switch_t NO_SWITCH = 0xFF;
|
||||||
|
|
||||||
|
} // namespace power
|
||||||
|
|
||||||
|
#endif /* FSFW_SRC_FSFW_POWER_DEFINITIONS_H_ */
|
@ -11,7 +11,10 @@ target_sources(${FSFW_TEST_TGT} PRIVATE
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(testcfg)
|
add_subdirectory(testcfg)
|
||||||
|
add_subdirectory(mocks)
|
||||||
|
|
||||||
add_subdirectory(action)
|
add_subdirectory(action)
|
||||||
|
add_subdirectory(power)
|
||||||
add_subdirectory(container)
|
add_subdirectory(container)
|
||||||
add_subdirectory(osal)
|
add_subdirectory(osal)
|
||||||
add_subdirectory(serialize)
|
add_subdirectory(serialize)
|
||||||
|
3
tests/src/fsfw_tests/unit/mocks/CMakeLists.txt
Normal file
3
tests/src/fsfw_tests/unit/mocks/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
target_sources(${FSFW_TEST_TGT} PRIVATE
|
||||||
|
PowerSwitcherMock.cpp
|
||||||
|
)
|
77
tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.cpp
Normal file
77
tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "PowerSwitcherMock.h"
|
||||||
|
|
||||||
|
static uint32_t SWITCH_REQUEST_UPDATE_VALUE = 0;
|
||||||
|
|
||||||
|
PowerSwitcherMock::PowerSwitcherMock() {}
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcherMock::sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) {
|
||||||
|
if (switchMap.count(switchNr) == 0) {
|
||||||
|
switchMap.emplace(switchNr, SwitchInfo(switchNr, onOff));
|
||||||
|
} else {
|
||||||
|
SwitchInfo& info = switchMap.at(switchNr);
|
||||||
|
info.currentState = onOff;
|
||||||
|
if (onOff == PowerSwitchIF::SWITCH_ON) {
|
||||||
|
info.timesCalledOn++;
|
||||||
|
} else {
|
||||||
|
info.timesCalledOff++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcherMock::sendFuseOnCommand(uint8_t fuseNr) {
|
||||||
|
if (fuseMap.count(fuseNr) == 0) {
|
||||||
|
fuseMap.emplace(fuseNr, FuseInfo(fuseNr));
|
||||||
|
} else {
|
||||||
|
FuseInfo& info = fuseMap.at(fuseNr);
|
||||||
|
info.timesCalled++;
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcherMock::getSwitchState(power::Switch_t switchNr) const {
|
||||||
|
if (switchMap.count(switchNr) == 1) {
|
||||||
|
auto& info = switchMap.at(switchNr);
|
||||||
|
SWITCH_REQUEST_UPDATE_VALUE++;
|
||||||
|
return info.currentState;
|
||||||
|
}
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PowerSwitcherMock::getFuseState(uint8_t fuseNr) const {
|
||||||
|
if (fuseMap.count(fuseNr) == 1) {
|
||||||
|
return FUSE_ON;
|
||||||
|
} else {
|
||||||
|
return FUSE_OFF;
|
||||||
|
}
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PowerSwitcherMock::getSwitchDelayMs(void) const { return 5000; }
|
||||||
|
|
||||||
|
SwitchInfo::SwitchInfo() : switcher(0) {}
|
||||||
|
|
||||||
|
SwitchInfo::SwitchInfo(power::Switch_t switcher, ReturnValue_t initState)
|
||||||
|
: switcher(switcher), currentState(initState) {}
|
||||||
|
|
||||||
|
FuseInfo::FuseInfo(uint8_t fuse) : fuse(fuse) {}
|
||||||
|
|
||||||
|
void PowerSwitcherMock::getSwitchInfo(power::Switch_t switcher, SwitchInfo& info) {
|
||||||
|
if (switchMap.count(switcher) == 1) {
|
||||||
|
info = switchMap.at(switcher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerSwitcherMock::getFuseInfo(uint8_t fuse, FuseInfo& info) {
|
||||||
|
if (fuseMap.count(fuse) == 1) {
|
||||||
|
info = fuseMap.at(fuse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PowerSwitcherMock::getAmountSwitchStatWasRequested() {
|
||||||
|
return SWITCH_REQUEST_UPDATE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerSwitcherMock::initSwitch(power::Switch_t switchNr) {
|
||||||
|
switchMap.emplace(switchNr, SwitchInfo(switchNr, PowerSwitchIF::SWITCH_OFF));
|
||||||
|
}
|
52
tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.h
Normal file
52
tests/src/fsfw_tests/unit/mocks/PowerSwitcherMock.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef FSFW_TESTS_SRC_FSFW_TESTS_UNIT_MOCKS_POWERSWITCHERMOCK_H_
|
||||||
|
#define FSFW_TESTS_SRC_FSFW_TESTS_UNIT_MOCKS_POWERSWITCHERMOCK_H_
|
||||||
|
|
||||||
|
#include <fsfw/power/PowerSwitchIF.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
struct SwitchInfo {
|
||||||
|
public:
|
||||||
|
SwitchInfo();
|
||||||
|
SwitchInfo(power::Switch_t switcher, ReturnValue_t initState);
|
||||||
|
|
||||||
|
power::Switch_t switcher;
|
||||||
|
ReturnValue_t currentState = PowerSwitchIF::SWITCH_OFF;
|
||||||
|
uint32_t timesCalledOn = 0;
|
||||||
|
uint32_t timesCalledOff = 0;
|
||||||
|
uint32_t timesStatusRequested = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FuseInfo {
|
||||||
|
public:
|
||||||
|
FuseInfo(uint8_t fuse);
|
||||||
|
uint8_t fuse;
|
||||||
|
uint32_t timesCalled = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PowerSwitcherMock : public PowerSwitchIF {
|
||||||
|
public:
|
||||||
|
PowerSwitcherMock();
|
||||||
|
|
||||||
|
ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) override;
|
||||||
|
ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
|
||||||
|
ReturnValue_t getSwitchState(power::Switch_t switchNr) const override;
|
||||||
|
ReturnValue_t getFuseState(uint8_t fuseNr) const override;
|
||||||
|
uint32_t getSwitchDelayMs(void) const override;
|
||||||
|
|
||||||
|
void getSwitchInfo(power::Switch_t switcher, SwitchInfo& info);
|
||||||
|
void getFuseInfo(uint8_t fuse, FuseInfo& info);
|
||||||
|
|
||||||
|
uint32_t getAmountSwitchStatWasRequested();
|
||||||
|
|
||||||
|
void initSwitch(power::Switch_t switchNr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
using SwitchOnOffPair = std::pair<power::Switch_t, ReturnValue_t>;
|
||||||
|
using FuseOnOffPair = std::pair<uint8_t, ReturnValue_t>;
|
||||||
|
std::map<power::Switch_t, SwitchInfo> switchMap;
|
||||||
|
std::map<uint8_t, FuseInfo> fuseMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_TESTS_SRC_FSFW_TESTS_UNIT_MOCKS_POWERSWITCHERMOCK_H_ */
|
3
tests/src/fsfw_tests/unit/power/CMakeLists.txt
Normal file
3
tests/src/fsfw_tests/unit/power/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
target_sources(${FSFW_TEST_TGT} PRIVATE
|
||||||
|
testPowerSwitcher.cpp
|
||||||
|
)
|
73
tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp
Normal file
73
tests/src/fsfw_tests/unit/power/testPowerSwitcher.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include <fsfw/power/DummyPowerSwitcher.h>
|
||||||
|
#include <fsfw/power/PowerSwitcher.h>
|
||||||
|
#include <fsfw_tests/unit/mocks/PowerSwitcherMock.h>
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "objects/systemObjectList.h"
|
||||||
|
|
||||||
|
TEST_CASE("Power Switcher", "[power-switcher]") {
|
||||||
|
PowerSwitcherMock mock;
|
||||||
|
PowerSwitcher switcher(&mock, 1);
|
||||||
|
DummyPowerSwitcher dummySwitcher(objects::DUMMY_POWER_SWITCHER, 5, 5, false);
|
||||||
|
PowerSwitcher switcherUsingDummy(&dummySwitcher, 1);
|
||||||
|
SwitchInfo switchInfo;
|
||||||
|
mock.initSwitch(1);
|
||||||
|
|
||||||
|
SECTION("Basic Tests") {
|
||||||
|
REQUIRE(switcher.getFirstSwitch() == 1);
|
||||||
|
REQUIRE(switcher.getSecondSwitch() == power::NO_SWITCH);
|
||||||
|
// Default start state
|
||||||
|
REQUIRE(switcher.getState() == PowerSwitcher::SWITCH_IS_OFF);
|
||||||
|
switcher.turnOn(true);
|
||||||
|
REQUIRE(mock.getAmountSwitchStatWasRequested() == 1);
|
||||||
|
REQUIRE(switcher.getState() == PowerSwitcher::WAIT_ON);
|
||||||
|
REQUIRE(switcher.checkSwitchState() == PowerSwitcher::IN_POWER_TRANSITION);
|
||||||
|
REQUIRE(switcher.active());
|
||||||
|
switcher.doStateMachine();
|
||||||
|
REQUIRE(switcher.getState() == PowerSwitcher::SWITCH_IS_ON);
|
||||||
|
mock.getSwitchInfo(1, switchInfo);
|
||||||
|
REQUIRE(switchInfo.timesCalledOn == 1);
|
||||||
|
REQUIRE(not switcher.active());
|
||||||
|
REQUIRE(mock.getAmountSwitchStatWasRequested() == 2);
|
||||||
|
REQUIRE(switcher.checkSwitchState() == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
REQUIRE(mock.getAmountSwitchStatWasRequested() == 3);
|
||||||
|
switcher.turnOff(false);
|
||||||
|
REQUIRE(mock.getAmountSwitchStatWasRequested() == 3);
|
||||||
|
REQUIRE(switcher.getState() == PowerSwitcher::WAIT_OFF);
|
||||||
|
REQUIRE(switcher.active());
|
||||||
|
REQUIRE(switcher.getState() == PowerSwitcher::WAIT_OFF);
|
||||||
|
switcher.doStateMachine();
|
||||||
|
mock.getSwitchInfo(1, switchInfo);
|
||||||
|
REQUIRE(switcher.getState() == PowerSwitcher::SWITCH_IS_OFF);
|
||||||
|
REQUIRE(switchInfo.timesCalledOn == 1);
|
||||||
|
REQUIRE(switchInfo.timesCalledOff == 1);
|
||||||
|
REQUIRE(not switcher.active());
|
||||||
|
REQUIRE(mock.getAmountSwitchStatWasRequested() == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Dummy Test") {
|
||||||
|
// Same tests, but we can't really check the dummy
|
||||||
|
REQUIRE(switcherUsingDummy.getFirstSwitch() == 1);
|
||||||
|
REQUIRE(switcherUsingDummy.getSecondSwitch() == power::NO_SWITCH);
|
||||||
|
REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::SWITCH_IS_OFF);
|
||||||
|
switcherUsingDummy.turnOn(true);
|
||||||
|
REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::WAIT_ON);
|
||||||
|
REQUIRE(switcherUsingDummy.active());
|
||||||
|
switcherUsingDummy.doStateMachine();
|
||||||
|
REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::SWITCH_IS_ON);
|
||||||
|
REQUIRE(not switcherUsingDummy.active());
|
||||||
|
|
||||||
|
switcherUsingDummy.turnOff(false);
|
||||||
|
REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::WAIT_OFF);
|
||||||
|
REQUIRE(switcherUsingDummy.active());
|
||||||
|
REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::WAIT_OFF);
|
||||||
|
switcherUsingDummy.doStateMachine();
|
||||||
|
REQUIRE(switcherUsingDummy.getState() == PowerSwitcher::SWITCH_IS_OFF);
|
||||||
|
REQUIRE(not switcherUsingDummy.active());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("More Dummy Tests") {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -21,8 +21,9 @@ enum sourceObjects : uint32_t {
|
|||||||
HK_RECEIVER_MOCK = 22,
|
HK_RECEIVER_MOCK = 22,
|
||||||
TEST_LOCAL_POOL_OWNER_BASE = 25,
|
TEST_LOCAL_POOL_OWNER_BASE = 25,
|
||||||
|
|
||||||
SHARED_SET_ID = 26
|
SHARED_SET_ID = 26,
|
||||||
|
|
||||||
|
DUMMY_POWER_SWITCHER = 27
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user