Compare commits
55 Commits
tmtcbridge
...
2efff4d2c5
Author | SHA1 | Date | |
---|---|---|---|
2efff4d2c5 | |||
c327985222 | |||
c8469ca647 | |||
2d6622b8b8 | |||
5f9eb01d94 | |||
3568bdbecf | |||
fcd84b59ae | |||
e3c968096b | |||
be015b4c66 | |||
a6d707a7db | |||
fe41d73895 | |||
9de6c4b3aa | |||
d256ede8c1 | |||
f0b8457ba2 | |||
dac2d210b5 | |||
8b4f73a97b | |||
7fae6cbd6d | |||
d302ba7185 | |||
14a92b3d89 | |||
e4fd424d66 | |||
341a66c265 | |||
b9b076aa4c | |||
d93486a340 | |||
820a7f059c | |||
f4d188c36f | |||
1841f92944 | |||
b279985859 | |||
fa7675897d | |||
3a2393885f | |||
c752b6d143 | |||
b676040c7c | |||
010509efb4 | |||
dfb1633f00 | |||
5f7172e130 | |||
0c6465cd95 | |||
f94987c46d | |||
1809ce359b | |||
8c712441ab | |||
6ce80ea6c5 | |||
f1b0ca7cff | |||
000df85556 | |||
1fffcc2229 | |||
a419806a05 | |||
134d908f26 | |||
40a9e12416 | |||
f39054edd4 | |||
5adf89b911 | |||
c2e6a22dec | |||
c8e065a713 | |||
3ed49dbae3 | |||
4cf52d5dfe | |||
46230e6c6d | |||
b22d439300 | |||
7e7b3bbbc9 | |||
b1e9dd9e4a |
@@ -12,15 +12,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Fixes
|
||||
|
||||
- Bugfix in `Service11TelecommandScheduling` which allowed commands
|
||||
time tagged in the past to be inserted.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/738
|
||||
- `CService200ModeManagement`: Various bugfixes which lead to now execution complete being generated
|
||||
on mode announcements, duplicate mode reply generated on announce commands, and the mode read
|
||||
subservice not working properly.
|
||||
- Memory leak fixes for the TCP/IP TMTC bridge.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/737
|
||||
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
|
||||
seconds instead of uptime.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726
|
||||
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
|
||||
only the X scaling factor was used.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/724
|
||||
- Bugfix for RM3100 MGM sensors. Z value was previously calculated
|
||||
with bytes of the X value.
|
||||
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
|
||||
to false correctly because the `read` and `write` calls were missing.
|
||||
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
|
||||
@@ -43,6 +50,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
- `CServiceHealthCommanding`: Add announce all health info implementation
|
||||
PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/122
|
||||
- Empty constructor for `CdsShortTimeStamper` which does not do an object manager registration.
|
||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/730
|
||||
- `Service9TimeManagement`: Add `DUMP_TIME` (129) subservice.
|
||||
- `TcpTmTcServer`: Allow setting the `SO_REUSEADDR` and `SO_REUSEPORT`
|
||||
option on the TCP server. CTOR prototype has changed and expects an explicit
|
||||
|
@@ -153,12 +153,12 @@ if(FSFW_BUILD_TESTS)
|
||||
"${MSG_PREFIX} Building the FSFW unittests in addition to the static library"
|
||||
)
|
||||
# Check whether the user has already installed Catch2 first
|
||||
find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION})
|
||||
find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION} QUIET)
|
||||
# Not installed, so use FetchContent to download and provide Catch2
|
||||
if(NOT Catch2_FOUND)
|
||||
message(
|
||||
STATUS
|
||||
"${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent"
|
||||
"${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent."
|
||||
)
|
||||
include(FetchContent)
|
||||
|
||||
@@ -196,13 +196,13 @@ message(
|
||||
)
|
||||
|
||||
# Check whether the user has already installed ETL first
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} CONFIG QUIET)
|
||||
find_package(${FSFW_ETL_LIB_NAME} ${FSFW_ETL_LIB_MAJOR_VERSION} QUIET)
|
||||
# Not installed, so use FetchContent to download and provide etl
|
||||
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||
message(
|
||||
STATUS
|
||||
"${MSG_PREFIX} No ETL installation was found with find_package. Installing and providing "
|
||||
"etl with FindPackage")
|
||||
"${MSG_PREFIX} ETL installation not found. Downloading ETL with FetchContent."
|
||||
)
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
|
@@ -58,12 +58,7 @@ void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
||||
this->hkDestination = hkDestination;
|
||||
}
|
||||
|
||||
void DeviceHandlerBase::setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId,
|
||||
lp_id_t heaterRequestPoolId,
|
||||
uint32_t thermalSetId) {
|
||||
thermalSet =
|
||||
new DeviceHandlerThermalSet(this, thermalSetId, thermalStatePoolId, heaterRequestPoolId);
|
||||
}
|
||||
void DeviceHandlerBase::enableThermalModule(ThermalStateCfg cfg) { this->thermalStateCfg = cfg; }
|
||||
|
||||
DeviceHandlerBase::~DeviceHandlerBase() {
|
||||
if (comCookie != nullptr) {
|
||||
@@ -227,12 +222,11 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
||||
fillCommandAndReplyMap();
|
||||
|
||||
if (thermalSet != nullptr) {
|
||||
PoolReadGuard pg(thermalSet);
|
||||
// Set temperature target state to NON_OP.
|
||||
result = thermalSet->read();
|
||||
if (result == returnvalue::OK) {
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
||||
thermalSet->heaterRequest.setValid(true);
|
||||
thermalSet->commit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,7 +376,7 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
}
|
||||
ReturnValue_t switchState = getStateOfSwitches();
|
||||
if ((switchState == PowerSwitchIF::SWITCH_OFF) || (switchState == NO_SWITCH)) {
|
||||
setMode(_MODE_SWITCH_IS_OFF);
|
||||
setMode(MODE_OFF, SUBMODE_NONE);
|
||||
}
|
||||
} break;
|
||||
case MODE_OFF:
|
||||
@@ -395,9 +389,6 @@ void DeviceHandlerBase::doStateMachine() {
|
||||
case MODE_NORMAL:
|
||||
case MODE_ERROR_ON:
|
||||
break;
|
||||
case _MODE_SWITCH_IS_OFF:
|
||||
setMode(MODE_OFF, SUBMODE_NONE);
|
||||
break;
|
||||
default:
|
||||
triggerEvent(OBJECT_IN_INVALID_MODE, mode, submode);
|
||||
setMode(_MODE_POWER_DOWN, 0);
|
||||
@@ -594,12 +585,12 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
||||
Clock::getUptime(&timeoutStart);
|
||||
|
||||
if (mode == MODE_OFF and thermalSet != nullptr) {
|
||||
ReturnValue_t result = thermalSet->read();
|
||||
if (result == returnvalue::OK) {
|
||||
PoolReadGuard pg(thermalSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
||||
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
||||
}
|
||||
thermalSet->heaterRequest.commit(PoolVariableIF::VALID);
|
||||
thermalSet->heaterRequest.setValid(true);
|
||||
}
|
||||
}
|
||||
/* TODO: This will probably be done by the LocalDataPoolManager now */
|
||||
@@ -1088,8 +1079,8 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, Submode_
|
||||
// Do not check thermal state for MODE_RAW
|
||||
if ((mode == MODE_OFF) and ((commandedMode == MODE_ON) or (commandedMode == MODE_NORMAL)) and
|
||||
(thermalSet != nullptr)) {
|
||||
ReturnValue_t result = thermalSet->read();
|
||||
if (result == returnvalue::OK) {
|
||||
PoolReadGuard pg(thermalSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if ((thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) and
|
||||
(not ThermalComponentIF::isOperational(thermalSet->thermalState.value))) {
|
||||
triggerEvent(ThermalComponentIF::TEMP_NOT_IN_OP_RANGE, thermalSet->thermalState.value);
|
||||
@@ -1150,11 +1141,10 @@ void DeviceHandlerBase::handleTransitionToOnMode(Mode_t commandedMode, Submode_t
|
||||
childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, MODE_ON);
|
||||
triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode);
|
||||
if (thermalSet != nullptr) {
|
||||
ReturnValue_t result = thermalSet->read();
|
||||
if (result == returnvalue::OK) {
|
||||
PoolReadGuard pg(thermalSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (thermalSet->heaterRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
||||
thermalSet->heaterRequest = ThermalComponentIF::STATE_REQUEST_OPERATIONAL;
|
||||
thermalSet->commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1477,11 +1467,11 @@ void DeviceHandlerBase::performOperationHook() {}
|
||||
|
||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
if (thermalSet != nullptr) {
|
||||
localDataPoolMap.emplace(thermalSet->thermalStatePoolId,
|
||||
new PoolEntry<DeviceHandlerIF::dh_thermal_state_t>);
|
||||
localDataPoolMap.emplace(thermalSet->heaterRequestPoolId,
|
||||
new PoolEntry<DeviceHandlerIF::dh_heater_request_t>);
|
||||
if (thermalStateCfg.has_value()) {
|
||||
localDataPoolMap.emplace(thermalStateCfg.value().thermalStatePoolId,
|
||||
new PoolEntry<DeviceHandlerIF::dh_thermal_state_t>());
|
||||
localDataPoolMap.emplace(thermalStateCfg.value().thermalRequestPoolId,
|
||||
new PoolEntry<DeviceHandlerIF::dh_heater_request_t>());
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
@@ -1494,6 +1484,10 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
||||
}
|
||||
this->poolManager.initializeAfterTaskCreation();
|
||||
|
||||
if (thermalStateCfg.has_value()) {
|
||||
ThermalStateCfg& cfg = thermalStateCfg.value();
|
||||
thermalSet = new DeviceHandlerThermalSet(this, cfg);
|
||||
}
|
||||
if (setStartupImmediately) {
|
||||
startTransition(MODE_ON, getInitialSubmode());
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
|
||||
#include "DeviceCommunicationIF.h"
|
||||
#include "DeviceHandlerFailureIsolation.h"
|
||||
@@ -149,11 +150,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
//! has been commanded on and the handler waits for it to be on.
|
||||
//! When the switch is on, the mode changes to @c _MODE_TO_ON.
|
||||
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4;
|
||||
//! This is a transitional state which can not be commanded. The switch has
|
||||
//! been commanded off and is off now. This state is only to do an RMAP
|
||||
//! cycle once more where the doSendRead() function will set the mode to
|
||||
//! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board.
|
||||
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5;
|
||||
|
||||
void setHkDestination(object_id_t hkDestination);
|
||||
|
||||
@@ -163,13 +159,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
* The device handler will then take care of creating local pool entries
|
||||
* for the device thermal state and device heating request.
|
||||
* Custom local pool IDs can be assigned as well.
|
||||
* @param thermalStatePoolId
|
||||
* @param thermalRequestPoolId
|
||||
*/
|
||||
void setThermalStateRequestPoolIds(
|
||||
lp_id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
||||
lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID,
|
||||
uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID);
|
||||
void enableThermalModule(ThermalStateCfg cfg);
|
||||
|
||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||
@@ -931,6 +922,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
||||
//! Object which may be the root cause of an identified fault.
|
||||
static object_id_t defaultFdirParentId;
|
||||
|
||||
std::optional<ThermalStateCfg> thermalStateCfg;
|
||||
|
||||
/**
|
||||
* @brief Send a reply to a received device handler command.
|
||||
*
|
||||
|
@@ -136,4 +136,10 @@ class DeviceHandlerIF {
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
};
|
||||
|
||||
struct ThermalStateCfg {
|
||||
lp_id_t thermalStatePoolId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID;
|
||||
lp_id_t thermalRequestPoolId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID;
|
||||
uint32_t thermalSetId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID;
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ */
|
||||
|
@@ -7,27 +7,21 @@
|
||||
|
||||
class DeviceHandlerThermalSet : public StaticLocalDataSet<2> {
|
||||
public:
|
||||
DeviceHandlerThermalSet(
|
||||
HasLocalDataPoolIF* hkOwner, uint32_t setId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID,
|
||||
lp_id_t thermalStateId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
||||
lp_id_t heaterRequestId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID)
|
||||
: DeviceHandlerThermalSet(hkOwner->getObjectId(), setId, thermalStateId, heaterRequestId) {}
|
||||
DeviceHandlerThermalSet(HasLocalDataPoolIF* hkOwner, ThermalStateCfg cfg)
|
||||
: DeviceHandlerThermalSet(hkOwner->getObjectId(), cfg) {}
|
||||
|
||||
DeviceHandlerThermalSet(
|
||||
object_id_t deviceHandler, uint32_t setId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID,
|
||||
lp_id_t thermalStateId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
||||
lp_id_t thermalStateRequestId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID)
|
||||
: StaticLocalDataSet(sid_t(deviceHandler, setId)),
|
||||
thermalStatePoolId(thermalStateId),
|
||||
heaterRequestPoolId(thermalStateRequestId) {}
|
||||
DeviceHandlerThermalSet(object_id_t deviceHandler, ThermalStateCfg cfg)
|
||||
: StaticLocalDataSet(sid_t(deviceHandler, cfg.thermalSetId)),
|
||||
thermalStatePoolId(cfg.thermalStatePoolId),
|
||||
heaterRequestPoolId(cfg.thermalRequestPoolId) {}
|
||||
|
||||
const lp_id_t thermalStatePoolId;
|
||||
const lp_id_t heaterRequestPoolId;
|
||||
|
||||
lp_var_t<DeviceHandlerIF::dh_thermal_state_t> thermalState =
|
||||
lp_var_t<DeviceHandlerIF::dh_thermal_state_t>(thermalStatePoolId, sid.objectId, this);
|
||||
lp_var_t<DeviceHandlerIF::dh_thermal_state_t>(sid.objectId, thermalStatePoolId, this);
|
||||
lp_var_t<DeviceHandlerIF::dh_heater_request_t> heaterRequest =
|
||||
lp_var_t<DeviceHandlerIF::dh_heater_request_t>(heaterRequestPoolId, sid.objectId, this);
|
||||
lp_var_t<DeviceHandlerIF::dh_heater_request_t>(sid.objectId, heaterRequestPoolId, this);
|
||||
};
|
||||
|
||||
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERTHERMALSET_H_ */
|
||||
|
@@ -41,6 +41,7 @@ int TcpIpBase::closeSocket(socket_t socket) {
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
return close(socket);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int TcpIpBase::getLastSocketError() {
|
||||
@@ -49,4 +50,5 @@ int TcpIpBase::getLastSocketError() {
|
||||
#elif defined(PLATFORM_UNIX)
|
||||
return errno;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@@ -126,10 +126,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
|
||||
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
|
||||
}
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
|
||||
sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent
|
||||
<< " bytes were"
|
||||
" sent."
|
||||
<< std::endl;
|
||||
sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent << " bytes were sent" << std::endl;
|
||||
#endif
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) {
|
||||
switch (subservice) {
|
||||
case (Subservice::COMMAND_MODE_COMMAND):
|
||||
case (Subservice::COMMAND_MODE_READ):
|
||||
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE):
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
|
||||
return returnvalue::OK;
|
||||
default:
|
||||
@@ -54,6 +54,7 @@ ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
|
||||
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
||||
const uint8_t *tcData, size_t tcDataLen,
|
||||
uint32_t *state, object_id_t objectId) {
|
||||
bool recursive = false;
|
||||
switch (subservice) {
|
||||
case (Subservice::COMMAND_MODE_COMMAND): {
|
||||
ModePacket modeCommandPacket;
|
||||
@@ -67,22 +68,17 @@ ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message,
|
||||
modeCommandPacket.getMode(), modeCommandPacket.getSubmode());
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY): {
|
||||
bool recursive = true;
|
||||
if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE) {
|
||||
recursive = false;
|
||||
}
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
|
||||
recursive = true;
|
||||
[[fallthrough]];
|
||||
case (Subservice::COMMAND_MODE_ANNOUNCE):
|
||||
ModeMessage::setModeAnnounceMessage(*message, recursive);
|
||||
return EXECUTION_COMPLETE;
|
||||
}
|
||||
case (Subservice::COMMAND_MODE_READ): {
|
||||
case (Subservice::COMMAND_MODE_READ):
|
||||
ModeMessage::setModeReadMessage(*message);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
default: {
|
||||
default:
|
||||
return CommandingServiceBase::INVALID_SUBSERVICE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -52,7 +52,7 @@ class CService200ModeCommanding : public CommandingServiceBase {
|
||||
COMMAND_MODE_READ = 3,
|
||||
//!< [EXPORT] : [COMMAND] Trigger an ModeInfo Event.
|
||||
//! This command does NOT have a reply
|
||||
COMMAND_MODE_ANNCOUNCE = 4,
|
||||
COMMAND_MODE_ANNOUNCE = 4,
|
||||
//!< [EXPORT] : [COMMAND] Trigger a ModeInfo Event and to send this
|
||||
//! command to every child. This command does NOT have a reply.
|
||||
COMMAND_MODE_ANNOUNCE_RECURSIVELY = 5,
|
||||
|
@@ -160,7 +160,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
|
||||
// (See requirement for Time margin)
|
||||
timeval tNow = {};
|
||||
Clock::getClock_timeval(&tNow);
|
||||
if (timestamp - tNow.tv_sec <= RELEASE_TIME_MARGIN_SECONDS) {
|
||||
if (timestamp < static_cast<uint32_t>(tNow.tv_sec + RELEASE_TIME_MARGIN_SECONDS)) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "Service11TelecommandScheduling::doInsertActivity: Release time too close to "
|
||||
"current time"
|
||||
|
@@ -117,6 +117,20 @@ ReturnValue_t SubsystemBase::updateChildMode(MessageQueueId_t queue, Mode_t mode
|
||||
return CHILD_NOT_FOUND;
|
||||
}
|
||||
|
||||
ReturnValue_t SubsystemBase::updateChildModeByObjId(object_id_t objectId, Mode_t mode,
|
||||
Submode_t submode) {
|
||||
std::map<object_id_t, ChildInfo>::iterator iter;
|
||||
|
||||
for (iter = childrenMap.begin(); iter != childrenMap.end(); iter++) {
|
||||
if (iter->first == objectId) {
|
||||
iter->second.mode = mode;
|
||||
iter->second.submode = submode;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
}
|
||||
return CHILD_NOT_FOUND;
|
||||
}
|
||||
|
||||
ReturnValue_t SubsystemBase::updateChildChangedHealth(MessageQueueId_t queue, bool changedHealth) {
|
||||
for (auto iter = childrenMap.begin(); iter != childrenMap.end(); iter++) {
|
||||
if (iter->second.commandQueue == queue) {
|
||||
|
@@ -115,6 +115,7 @@ class SubsystemBase : public SystemObject,
|
||||
Submode_t targetSubmode = SUBMODE_NONE);
|
||||
|
||||
ReturnValue_t updateChildMode(MessageQueueId_t queue, Mode_t mode, Submode_t submode);
|
||||
ReturnValue_t updateChildModeByObjId(object_id_t objectId, Mode_t mode, Submode_t submode);
|
||||
|
||||
ReturnValue_t updateChildChangedHealth(MessageQueueId_t queue, bool changedHealth = true);
|
||||
|
||||
|
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "fsfw/timemanager/Clock.h"
|
||||
|
||||
CdsShortTimeStamper::CdsShortTimeStamper() : SystemObject(0, false) {}
|
||||
|
||||
CdsShortTimeStamper::CdsShortTimeStamper(object_id_t objectId) : SystemObject(objectId) {}
|
||||
|
||||
ReturnValue_t CdsShortTimeStamper::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
|
@@ -18,6 +18,7 @@
|
||||
class CdsShortTimeStamper : public TimeWriterIF, public TimeReaderIF, public SystemObject {
|
||||
public:
|
||||
static constexpr size_t TIMESTAMP_LEN = 7;
|
||||
CdsShortTimeStamper();
|
||||
/**
|
||||
* @brief Default constructor which also registers the time stamper as a
|
||||
* system object so it can be found with the #objectManager.
|
||||
|
@@ -17,7 +17,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
||||
public:
|
||||
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
|
||||
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
|
||||
static constexpr unsigned int LIMIT_DOWNLINK_PACKETS_STORED = 1000;
|
||||
static constexpr unsigned int LIMIT_DOWNLINK_PACKETS_STORED = 500;
|
||||
|
||||
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
|
||||
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "version.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "fsfw/FSFWVersion.h"
|
||||
|
||||
@@ -20,7 +21,7 @@ fsfw::Version::Version(int major, int minor, int revision, const char* addInfo)
|
||||
|
||||
void fsfw::Version::getVersion(char* str, size_t maxLen) const {
|
||||
size_t len = snprintf(str, maxLen, "%d.%d.%d", major, minor, revision);
|
||||
if (addInfo != nullptr) {
|
||||
if (addInfo != nullptr and std::strcmp(addInfo, "") != 0) {
|
||||
snprintf(str + len, maxLen - len, "-%s", addInfo);
|
||||
}
|
||||
}
|
||||
@@ -30,7 +31,7 @@ namespace fsfw {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
std::ostream& operator<<(std::ostream& os, const Version& v) {
|
||||
os << v.major << "." << v.minor << "." << v.revision;
|
||||
if (v.addInfo != nullptr) {
|
||||
if (v.addInfo != nullptr and std::strcmp(v.addInfo, "") != 0) {
|
||||
os << "-" << v.addInfo;
|
||||
}
|
||||
return os;
|
||||
|
@@ -6,14 +6,11 @@
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
UnixFileGuard::UnixFileGuard(const std::string& device, int* fileDescriptor, int flags,
|
||||
UnixFileGuard::UnixFileGuard(const std::string& device, int& fileDescriptor, int flags,
|
||||
std::string diagnosticPrefix)
|
||||
: fileDescriptor(fileDescriptor) {
|
||||
if (fileDescriptor == nullptr) {
|
||||
return;
|
||||
}
|
||||
*fileDescriptor = open(device.c_str(), flags);
|
||||
if (*fileDescriptor < 0) {
|
||||
: fdRef(fileDescriptor) {
|
||||
fileDescriptor = open(device.c_str(), flags);
|
||||
if (fileDescriptor < 0) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << diagnosticPrefix << ": Opening device failed with error code " << errno << ": "
|
||||
@@ -27,10 +24,6 @@ UnixFileGuard::UnixFileGuard(const std::string& device, int* fileDescriptor, int
|
||||
}
|
||||
}
|
||||
|
||||
UnixFileGuard::~UnixFileGuard() {
|
||||
if (fileDescriptor != nullptr) {
|
||||
close(*fileDescriptor);
|
||||
}
|
||||
}
|
||||
UnixFileGuard::~UnixFileGuard() { close(fdRef); }
|
||||
|
||||
ReturnValue_t UnixFileGuard::getOpenResult() const { return openStatus; }
|
||||
|
@@ -15,7 +15,15 @@ class UnixFileGuard {
|
||||
|
||||
static constexpr ReturnValue_t OPEN_FILE_FAILED = 1;
|
||||
|
||||
UnixFileGuard(const std::string& device, int* fileDescriptor, int flags,
|
||||
/**
|
||||
* Open a device and assign the given file descriptor variable
|
||||
* @param device [in] Device name.
|
||||
* @param fileDescriptor [in/out] Will be assigned by file guard and re-used to
|
||||
* close the guard.
|
||||
* @param flags
|
||||
* @param diagnosticPrefix
|
||||
*/
|
||||
UnixFileGuard(const std::string& device, int& fileDescriptor, int flags,
|
||||
std::string diagnosticPrefix = "");
|
||||
|
||||
virtual ~UnixFileGuard();
|
||||
@@ -23,7 +31,7 @@ class UnixFileGuard {
|
||||
ReturnValue_t getOpenResult() const;
|
||||
|
||||
private:
|
||||
int* fileDescriptor = nullptr;
|
||||
int& fdRef;
|
||||
ReturnValue_t openStatus = returnvalue::OK;
|
||||
};
|
||||
|
||||
|
@@ -66,8 +66,7 @@ ReturnValue_t I2cComIF::initializeInterface(CookieIF* cookie) {
|
||||
|
||||
ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
|
||||
ReturnValue_t result;
|
||||
int fd;
|
||||
std::string deviceFile;
|
||||
int fd = 0;
|
||||
|
||||
if (sendData == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@@ -98,12 +97,12 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
deviceFile = i2cCookie->getDeviceFile();
|
||||
UnixFileGuard fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::sendMessage");
|
||||
const auto& deviceFile = i2cCookie->getDeviceFile();
|
||||
UnixFileGuard fileHelper(deviceFile, fd, O_RDWR, "I2cComIF::sendMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return fileHelper.getOpenResult();
|
||||
}
|
||||
result = openDevice(deviceFile, i2cAddress, &fd);
|
||||
result = openI2cSlave(deviceFile, i2cAddress, fd);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
@@ -131,8 +130,7 @@ ReturnValue_t I2cComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::O
|
||||
|
||||
ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||
ReturnValue_t result;
|
||||
int fd;
|
||||
std::string deviceFile;
|
||||
int fd = 0;
|
||||
|
||||
if (requestLen == 0) {
|
||||
return returnvalue::OK;
|
||||
@@ -157,12 +155,12 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
}
|
||||
i2cDeviceMapIter->second.replyLen = 0;
|
||||
|
||||
deviceFile = i2cCookie->getDeviceFile();
|
||||
UnixFileGuard fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::requestReceiveMessage");
|
||||
auto& deviceFile = i2cCookie->getDeviceFile();
|
||||
UnixFileGuard fileHelper(deviceFile, fd, O_RDWR, "I2cComIF::requestReceiveMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return fileHelper.getOpenResult();
|
||||
}
|
||||
result = openDevice(deviceFile, i2cAddress, &fd);
|
||||
result = openI2cSlave(deviceFile, i2cAddress, fd);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
@@ -220,9 +218,9 @@ ReturnValue_t I2cComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t I2cComIF::openDevice(std::string deviceFile, address_t i2cAddress,
|
||||
int* fileDescriptor) {
|
||||
if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) {
|
||||
ReturnValue_t I2cComIF::openI2cSlave(const std::string& deviceFile, address_t i2cAddress,
|
||||
int& fileDescriptor) {
|
||||
if (ioctl(fileDescriptor, I2C_SLAVE, i2cAddress) < 0) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "I2cComIF: Specifying target device failed with error code " << errno << "."
|
||||
|
@@ -49,7 +49,8 @@ class I2cComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
* @param fileDescriptor Pointer to device descriptor.
|
||||
* @return returnvalue::OK if successful, otherwise returnvalue::FAILED.
|
||||
*/
|
||||
ReturnValue_t openDevice(std::string deviceFile, address_t i2cAddress, int *fileDescriptor);
|
||||
ReturnValue_t openI2cSlave(const std::string &deviceFile, address_t i2cAddress,
|
||||
int &fileDescriptor);
|
||||
};
|
||||
|
||||
#endif /* LINUX_I2C_I2COMIF_H_ */
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#include "fsfw_hal/linux/i2c/I2cCookie.h"
|
||||
|
||||
I2cCookie::I2cCookie(address_t i2cAddress_, size_t maxReplyLen_, std::string deviceFile_)
|
||||
: i2cAddress(i2cAddress_), maxReplyLen(maxReplyLen_), deviceFile(deviceFile_) {}
|
||||
: i2cAddress(i2cAddress_), maxReplyLen(maxReplyLen_), deviceFile(std::move(deviceFile_)) {}
|
||||
|
||||
address_t I2cCookie::getAddress() const { return i2cAddress; }
|
||||
|
||||
size_t I2cCookie::getMaxReplyLen() const { return maxReplyLen; }
|
||||
|
||||
std::string I2cCookie::getDeviceFile() const { return deviceFile; }
|
||||
const std::string& I2cCookie::getDeviceFile() const { return deviceFile; }
|
||||
|
||||
I2cCookie::~I2cCookie() {}
|
||||
|
@@ -25,7 +25,7 @@ class I2cCookie : public CookieIF {
|
||||
|
||||
address_t getAddress() const;
|
||||
size_t getMaxReplyLen() const;
|
||||
std::string getDeviceFile() const;
|
||||
const std::string& getDeviceFile() const;
|
||||
|
||||
uint8_t errorCounter = 0;
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||
#include "fsfw/ipc/MutexIF.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
|
@@ -75,7 +75,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
|
||||
spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms);
|
||||
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return fileHelper.getOpenResult();
|
||||
}
|
||||
@@ -171,7 +171,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
int retval = 0;
|
||||
/* Prepare transfer */
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return OPENING_FILE_FAILED;
|
||||
}
|
||||
@@ -179,12 +179,11 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
uint32_t spiSpeed = 0;
|
||||
spiCookie->getSpiParameters(spiMode, spiSpeed, nullptr);
|
||||
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||
spiCookie->assignWriteBuffer(sendData);
|
||||
spiCookie->setTransferSize(sendLen);
|
||||
|
||||
bool fullDuplex = spiCookie->isFullDuplex();
|
||||
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
||||
bool csLockManual = spiCookie->getCsLockManual();
|
||||
spiCookie->setTransferSize(0);
|
||||
|
||||
MutexIF::TimeoutType csType;
|
||||
dur_millis_t csTimeout = 0;
|
||||
@@ -195,9 +194,13 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
||||
<< std::endl;
|
||||
if (result == MutexIF::MUTEX_TIMEOUT) {
|
||||
sif::error << "SpiComIF::sendMessage: Lock timeout" << std::endl;
|
||||
} else {
|
||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
#else
|
||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
||||
#endif
|
||||
@@ -214,17 +217,22 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
sif::printWarning("SpiComIF::sendMessage: Pulling low CS pin failed");
|
||||
#endif
|
||||
#endif
|
||||
csMutex->unlockMutex();
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
updateLinePolarity(fileDescriptor);
|
||||
}
|
||||
|
||||
spiCookie->assignWriteBuffer(sendData);
|
||||
spiCookie->setTransferSize(sendLen);
|
||||
|
||||
/* Execute transfer */
|
||||
if (fullDuplex) {
|
||||
/* Initiate a full duplex SPI transfer. */
|
||||
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle());
|
||||
if (retval < 0) {
|
||||
spiCookie->setTransferSize(0);
|
||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||
result = FULL_DUPLEX_TRANSFER_FAILED;
|
||||
}
|
||||
@@ -234,6 +242,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
||||
} else {
|
||||
/* We write with a blocking half-duplex transfer here */
|
||||
if (write(fileDescriptor, sendData, sendLen) != static_cast<ssize_t>(sendLen)) {
|
||||
spiCookie->setTransferSize(0);
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << std::endl;
|
||||
@@ -276,7 +285,7 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
||||
UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return OPENING_FILE_FAILED;
|
||||
}
|
||||
|
Reference in New Issue
Block a user