Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
This commit is contained in:
commit
70b785984c
@ -12,15 +12,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Fixes
|
## 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
|
- `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
|
on mode announcements, duplicate mode reply generated on announce commands, and the mode read
|
||||||
subservice not working properly.
|
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
|
- `Service9TimeManagement`: Fix the time dump at the `SET_TIME` subservice: Include clock timeval
|
||||||
seconds instead of uptime.
|
seconds instead of uptime.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726
|
||||||
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
|
- HAL MGM3100 Handler: Use axis specific gain/scaling factors. Previously,
|
||||||
only the X scaling factor was used.
|
only the X scaling factor was used.
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/724
|
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
|
- DHB `setNormalDatapoolEntriesInvalid`: The default implementation did not set the validity
|
||||||
to false correctly because the `read` and `write` calls were missing.
|
to false correctly because the `read` and `write` calls were missing.
|
||||||
- PUS TMTC creator module: Sequence flags were set to continuation segment (0b00) instead
|
- 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
|
- `CServiceHealthCommanding`: Add announce all health info implementation
|
||||||
PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/122
|
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.
|
- `Service9TimeManagement`: Add `DUMP_TIME` (129) subservice.
|
||||||
- `TcpTmTcServer`: Allow setting the `SO_REUSEADDR` and `SO_REUSEPORT`
|
- `TcpTmTcServer`: Allow setting the `SO_REUSEADDR` and `SO_REUSEPORT`
|
||||||
option on the TCP server. CTOR prototype has changed and expects an explicit
|
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"
|
"${MSG_PREFIX} Building the FSFW unittests in addition to the static library"
|
||||||
)
|
)
|
||||||
# Check whether the user has already installed Catch2 first
|
# 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
|
# Not installed, so use FetchContent to download and provide Catch2
|
||||||
if(NOT Catch2_FOUND)
|
if(NOT Catch2_FOUND)
|
||||||
message(
|
message(
|
||||||
STATUS
|
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)
|
include(FetchContent)
|
||||||
|
|
||||||
@ -196,13 +196,13 @@ message(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Check whether the user has already installed ETL first
|
# 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
|
# Not installed, so use FetchContent to download and provide etl
|
||||||
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
if(NOT ${FSFW_ETL_LIB_NAME}_FOUND)
|
||||||
message(
|
message(
|
||||||
STATUS
|
STATUS
|
||||||
"${MSG_PREFIX} No ETL installation was found with find_package. Installing and providing "
|
"${MSG_PREFIX} ETL installation not found. Downloading ETL with FetchContent."
|
||||||
"etl with FindPackage")
|
)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
|
@ -58,12 +58,7 @@ void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) {
|
|||||||
this->hkDestination = hkDestination;
|
this->hkDestination = hkDestination;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceHandlerBase::setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId,
|
void DeviceHandlerBase::enableThermalModule(ThermalStateCfg cfg) { this->thermalStateCfg = cfg; }
|
||||||
lp_id_t heaterRequestPoolId,
|
|
||||||
uint32_t thermalSetId) {
|
|
||||||
thermalSet =
|
|
||||||
new DeviceHandlerThermalSet(this, thermalSetId, thermalStatePoolId, heaterRequestPoolId);
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceHandlerBase::~DeviceHandlerBase() {
|
DeviceHandlerBase::~DeviceHandlerBase() {
|
||||||
if (comCookie != nullptr) {
|
if (comCookie != nullptr) {
|
||||||
@ -227,12 +222,11 @@ ReturnValue_t DeviceHandlerBase::initialize() {
|
|||||||
fillCommandAndReplyMap();
|
fillCommandAndReplyMap();
|
||||||
|
|
||||||
if (thermalSet != nullptr) {
|
if (thermalSet != nullptr) {
|
||||||
|
PoolReadGuard pg(thermalSet);
|
||||||
// Set temperature target state to NON_OP.
|
// Set temperature target state to NON_OP.
|
||||||
result = thermalSet->read();
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
||||||
thermalSet->heaterRequest.setValid(true);
|
thermalSet->heaterRequest.setValid(true);
|
||||||
thermalSet->commit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,12 +588,12 @@ void DeviceHandlerBase::setMode(Mode_t newMode, uint8_t newSubmode) {
|
|||||||
Clock::getUptime(&timeoutStart);
|
Clock::getUptime(&timeoutStart);
|
||||||
|
|
||||||
if (mode == MODE_OFF and thermalSet != nullptr) {
|
if (mode == MODE_OFF and thermalSet != nullptr) {
|
||||||
ReturnValue_t result = thermalSet->read();
|
PoolReadGuard pg(thermalSet);
|
||||||
if (result == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
if (thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
if (thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
||||||
thermalSet->heaterRequest.value = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
|
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 */
|
/* TODO: This will probably be done by the LocalDataPoolManager now */
|
||||||
@ -1088,8 +1082,8 @@ ReturnValue_t DeviceHandlerBase::checkModeCommand(Mode_t commandedMode, Submode_
|
|||||||
// Do not check thermal state for MODE_RAW
|
// Do not check thermal state for MODE_RAW
|
||||||
if ((mode == MODE_OFF) and ((commandedMode == MODE_ON) or (commandedMode == MODE_NORMAL)) and
|
if ((mode == MODE_OFF) and ((commandedMode == MODE_ON) or (commandedMode == MODE_NORMAL)) and
|
||||||
(thermalSet != nullptr)) {
|
(thermalSet != nullptr)) {
|
||||||
ReturnValue_t result = thermalSet->read();
|
PoolReadGuard pg(thermalSet);
|
||||||
if (result == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
if ((thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) and
|
if ((thermalSet->heaterRequest.value != ThermalComponentIF::STATE_REQUEST_IGNORE) and
|
||||||
(not ThermalComponentIF::isOperational(thermalSet->thermalState.value))) {
|
(not ThermalComponentIF::isOperational(thermalSet->thermalState.value))) {
|
||||||
triggerEvent(ThermalComponentIF::TEMP_NOT_IN_OP_RANGE, thermalSet->thermalState.value);
|
triggerEvent(ThermalComponentIF::TEMP_NOT_IN_OP_RANGE, thermalSet->thermalState.value);
|
||||||
@ -1150,11 +1144,10 @@ void DeviceHandlerBase::handleTransitionToOnMode(Mode_t commandedMode, Submode_t
|
|||||||
childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, MODE_ON);
|
childTransitionDelay = getTransitionDelayMs(_MODE_START_UP, MODE_ON);
|
||||||
triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode);
|
triggerEvent(CHANGING_MODE, commandedMode, commandedSubmode);
|
||||||
if (thermalSet != nullptr) {
|
if (thermalSet != nullptr) {
|
||||||
ReturnValue_t result = thermalSet->read();
|
PoolReadGuard pg(thermalSet);
|
||||||
if (result == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
if (thermalSet->heaterRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
if (thermalSet->heaterRequest != ThermalComponentIF::STATE_REQUEST_IGNORE) {
|
||||||
thermalSet->heaterRequest = ThermalComponentIF::STATE_REQUEST_OPERATIONAL;
|
thermalSet->heaterRequest = ThermalComponentIF::STATE_REQUEST_OPERATIONAL;
|
||||||
thermalSet->commit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1477,11 +1470,11 @@ void DeviceHandlerBase::performOperationHook() {}
|
|||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t DeviceHandlerBase::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) {
|
LocalDataPoolManager& poolManager) {
|
||||||
if (thermalSet != nullptr) {
|
if (thermalStateCfg.has_value()) {
|
||||||
localDataPoolMap.emplace(thermalSet->thermalStatePoolId,
|
localDataPoolMap.emplace(thermalStateCfg.value().thermalStatePoolId,
|
||||||
new PoolEntry<DeviceHandlerIF::dh_thermal_state_t>);
|
new PoolEntry<DeviceHandlerIF::dh_thermal_state_t>());
|
||||||
localDataPoolMap.emplace(thermalSet->heaterRequestPoolId,
|
localDataPoolMap.emplace(thermalStateCfg.value().thermalRequestPoolId,
|
||||||
new PoolEntry<DeviceHandlerIF::dh_heater_request_t>);
|
new PoolEntry<DeviceHandlerIF::dh_heater_request_t>());
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
@ -1494,6 +1487,10 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() {
|
|||||||
}
|
}
|
||||||
this->poolManager.initializeAfterTaskCreation();
|
this->poolManager.initializeAfterTaskCreation();
|
||||||
|
|
||||||
|
if (thermalStateCfg.has_value()) {
|
||||||
|
ThermalStateCfg& cfg = thermalStateCfg.value();
|
||||||
|
thermalSet = new DeviceHandlerThermalSet(this, cfg);
|
||||||
|
}
|
||||||
if (setStartupImmediately) {
|
if (setStartupImmediately) {
|
||||||
startTransition(MODE_ON, getInitialSubmode());
|
startTransition(MODE_ON, getInitialSubmode());
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
#define FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "DeviceCommunicationIF.h"
|
#include "DeviceCommunicationIF.h"
|
||||||
#include "DeviceHandlerFailureIsolation.h"
|
#include "DeviceHandlerFailureIsolation.h"
|
||||||
@ -163,13 +164,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
* The device handler will then take care of creating local pool entries
|
* The device handler will then take care of creating local pool entries
|
||||||
* for the device thermal state and device heating request.
|
* for the device thermal state and device heating request.
|
||||||
* Custom local pool IDs can be assigned as well.
|
* Custom local pool IDs can be assigned as well.
|
||||||
* @param thermalStatePoolId
|
|
||||||
* @param thermalRequestPoolId
|
|
||||||
*/
|
*/
|
||||||
void setThermalStateRequestPoolIds(
|
void enableThermalModule(ThermalStateCfg cfg);
|
||||||
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);
|
|
||||||
|
|
||||||
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF &parent) override;
|
||||||
ModeTreeChildIF &getModeTreeChildIF() override;
|
ModeTreeChildIF &getModeTreeChildIF() override;
|
||||||
@ -931,6 +927,8 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
//! Object which may be the root cause of an identified fault.
|
//! Object which may be the root cause of an identified fault.
|
||||||
static object_id_t defaultFdirParentId;
|
static object_id_t defaultFdirParentId;
|
||||||
|
|
||||||
|
std::optional<ThermalStateCfg> thermalStateCfg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a reply to a received device handler command.
|
* @brief Send a reply to a received device handler command.
|
||||||
*
|
*
|
||||||
|
@ -136,4 +136,10 @@ class DeviceHandlerIF {
|
|||||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
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_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERIF_H_ */
|
||||||
|
@ -7,27 +7,21 @@
|
|||||||
|
|
||||||
class DeviceHandlerThermalSet : public StaticLocalDataSet<2> {
|
class DeviceHandlerThermalSet : public StaticLocalDataSet<2> {
|
||||||
public:
|
public:
|
||||||
DeviceHandlerThermalSet(
|
DeviceHandlerThermalSet(HasLocalDataPoolIF* hkOwner, ThermalStateCfg cfg)
|
||||||
HasLocalDataPoolIF* hkOwner, uint32_t setId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID,
|
: DeviceHandlerThermalSet(hkOwner->getObjectId(), cfg) {}
|
||||||
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(
|
DeviceHandlerThermalSet(object_id_t deviceHandler, ThermalStateCfg cfg)
|
||||||
object_id_t deviceHandler, uint32_t setId = DeviceHandlerIF::DEFAULT_THERMAL_SET_ID,
|
: StaticLocalDataSet(sid_t(deviceHandler, cfg.thermalSetId)),
|
||||||
lp_id_t thermalStateId = DeviceHandlerIF::DEFAULT_THERMAL_STATE_POOL_ID,
|
thermalStatePoolId(cfg.thermalStatePoolId),
|
||||||
lp_id_t thermalStateRequestId = DeviceHandlerIF::DEFAULT_THERMAL_HEATING_REQUEST_POOL_ID)
|
heaterRequestPoolId(cfg.thermalRequestPoolId) {}
|
||||||
: StaticLocalDataSet(sid_t(deviceHandler, setId)),
|
|
||||||
thermalStatePoolId(thermalStateId),
|
|
||||||
heaterRequestPoolId(thermalStateRequestId) {}
|
|
||||||
|
|
||||||
const lp_id_t thermalStatePoolId;
|
const lp_id_t thermalStatePoolId;
|
||||||
const lp_id_t heaterRequestPoolId;
|
const lp_id_t heaterRequestPoolId;
|
||||||
|
|
||||||
lp_var_t<DeviceHandlerIF::dh_thermal_state_t> thermalState =
|
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> 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_ */
|
#endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERTHERMALSET_H_ */
|
||||||
|
@ -41,6 +41,7 @@ int TcpIpBase::closeSocket(socket_t socket) {
|
|||||||
#elif defined(PLATFORM_UNIX)
|
#elif defined(PLATFORM_UNIX)
|
||||||
return close(socket);
|
return close(socket);
|
||||||
#endif
|
#endif
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TcpIpBase::getLastSocketError() {
|
int TcpIpBase::getLastSocketError() {
|
||||||
@ -49,4 +50,5 @@ int TcpIpBase::getLastSocketError() {
|
|||||||
#elif defined(PLATFORM_UNIX)
|
#elif defined(PLATFORM_UNIX)
|
||||||
return errno;
|
return errno;
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) {
|
|||||||
switch (subservice) {
|
switch (subservice) {
|
||||||
case (Subservice::COMMAND_MODE_COMMAND):
|
case (Subservice::COMMAND_MODE_COMMAND):
|
||||||
case (Subservice::COMMAND_MODE_READ):
|
case (Subservice::COMMAND_MODE_READ):
|
||||||
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
case (Subservice::COMMAND_MODE_ANNOUNCE):
|
||||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
|
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
default:
|
default:
|
||||||
@ -54,6 +54,7 @@ ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue(
|
|||||||
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message, uint8_t subservice,
|
||||||
const uint8_t *tcData, size_t tcDataLen,
|
const uint8_t *tcData, size_t tcDataLen,
|
||||||
uint32_t *state, object_id_t objectId) {
|
uint32_t *state, object_id_t objectId) {
|
||||||
|
bool recursive = false;
|
||||||
switch (subservice) {
|
switch (subservice) {
|
||||||
case (Subservice::COMMAND_MODE_COMMAND): {
|
case (Subservice::COMMAND_MODE_COMMAND): {
|
||||||
ModePacket modeCommandPacket;
|
ModePacket modeCommandPacket;
|
||||||
@ -67,22 +68,17 @@ ReturnValue_t CService200ModeCommanding::prepareCommand(CommandMessage *message,
|
|||||||
modeCommandPacket.getMode(), modeCommandPacket.getSubmode());
|
modeCommandPacket.getMode(), modeCommandPacket.getSubmode());
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
case (Subservice::COMMAND_MODE_ANNCOUNCE):
|
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY):
|
||||||
case (Subservice::COMMAND_MODE_ANNOUNCE_RECURSIVELY): {
|
recursive = true;
|
||||||
bool recursive = true;
|
[[fallthrough]];
|
||||||
if (subservice == Subservice::COMMAND_MODE_ANNCOUNCE) {
|
case (Subservice::COMMAND_MODE_ANNOUNCE):
|
||||||
recursive = false;
|
|
||||||
}
|
|
||||||
ModeMessage::setModeAnnounceMessage(*message, recursive);
|
ModeMessage::setModeAnnounceMessage(*message, recursive);
|
||||||
return EXECUTION_COMPLETE;
|
return EXECUTION_COMPLETE;
|
||||||
}
|
case (Subservice::COMMAND_MODE_READ):
|
||||||
case (Subservice::COMMAND_MODE_READ): {
|
|
||||||
ModeMessage::setModeReadMessage(*message);
|
ModeMessage::setModeReadMessage(*message);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
default:
|
||||||
default: {
|
|
||||||
return CommandingServiceBase::INVALID_SUBSERVICE;
|
return CommandingServiceBase::INVALID_SUBSERVICE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class CService200ModeCommanding : public CommandingServiceBase {
|
|||||||
COMMAND_MODE_READ = 3,
|
COMMAND_MODE_READ = 3,
|
||||||
//!< [EXPORT] : [COMMAND] Trigger an ModeInfo Event.
|
//!< [EXPORT] : [COMMAND] Trigger an ModeInfo Event.
|
||||||
//! This command does NOT have a reply
|
//! 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
|
//!< [EXPORT] : [COMMAND] Trigger a ModeInfo Event and to send this
|
||||||
//! command to every child. This command does NOT have a reply.
|
//! command to every child. This command does NOT have a reply.
|
||||||
COMMAND_MODE_ANNOUNCE_RECURSIVELY = 5,
|
COMMAND_MODE_ANNOUNCE_RECURSIVELY = 5,
|
||||||
|
@ -160,7 +160,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
|
|||||||
// (See requirement for Time margin)
|
// (See requirement for Time margin)
|
||||||
timeval tNow = {};
|
timeval tNow = {};
|
||||||
Clock::getClock_timeval(&tNow);
|
Clock::getClock_timeval(&tNow);
|
||||||
if (timestamp - tNow.tv_sec <= RELEASE_TIME_MARGIN_SECONDS) {
|
if (timestamp < tNow.tv_sec + RELEASE_TIME_MARGIN_SECONDS) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Service11TelecommandScheduling::doInsertActivity: Release time too close to "
|
sif::warning << "Service11TelecommandScheduling::doInsertActivity: Release time too close to "
|
||||||
"current time"
|
"current time"
|
||||||
|
@ -145,13 +145,17 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
|||||||
#endif /* FSFW_VERBOSE_LEVEL >= 3 */
|
#endif /* FSFW_VERBOSE_LEVEL >= 3 */
|
||||||
|
|
||||||
if (communicationLinkUp == false or packetSentCounter >= sentPacketsPerCycle) {
|
if (communicationLinkUp == false or packetSentCounter >= sentPacketsPerCycle) {
|
||||||
storeDownlinkData(&message);
|
ReturnValue_t result = storeDownlinkData(&message);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
tmStore->deleteData(message.getStorageId());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = tmStore->getData(message.getStorageId(), &data, &size);
|
result = tmStore->getData(message.getStorageId(), &data, &size);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
status = result;
|
status = result;
|
||||||
|
tmStore->deleteData(message.getStorageId());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,9 +163,9 @@ ReturnValue_t TmTcBridge::handleTmQueue() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
status = result;
|
status = result;
|
||||||
} else {
|
} else {
|
||||||
tmStore->deleteData(message.getStorageId());
|
|
||||||
packetSentCounter++;
|
packetSentCounter++;
|
||||||
}
|
}
|
||||||
|
tmStore->deleteData(message.getStorageId());
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
|||||||
public:
|
public:
|
||||||
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
|
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
|
||||||
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
|
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_STORED_DATA_SENT_PER_CYCLE = 5;
|
||||||
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include "fsfw/FSFWVersion.h"
|
#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 {
|
void fsfw::Version::getVersion(char* str, size_t maxLen) const {
|
||||||
size_t len = snprintf(str, maxLen, "%d.%d.%d", major, minor, revision);
|
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);
|
snprintf(str + len, maxLen - len, "-%s", addInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,7 +31,7 @@ namespace fsfw {
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
std::ostream& operator<<(std::ostream& os, const Version& v) {
|
std::ostream& operator<<(std::ostream& os, const Version& v) {
|
||||||
os << v.major << "." << v.minor << "." << v.revision;
|
os << v.major << "." << v.minor << "." << v.revision;
|
||||||
if (v.addInfo != nullptr) {
|
if (v.addInfo != nullptr and std::strcmp(v.addInfo, "") != 0) {
|
||||||
os << "-" << v.addInfo;
|
os << "-" << v.addInfo;
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
|
@ -179,12 +179,11 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
uint32_t spiSpeed = 0;
|
uint32_t spiSpeed = 0;
|
||||||
spiCookie->getSpiParameters(spiMode, spiSpeed, nullptr);
|
spiCookie->getSpiParameters(spiMode, spiSpeed, nullptr);
|
||||||
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||||
spiCookie->assignWriteBuffer(sendData);
|
|
||||||
spiCookie->setTransferSize(sendLen);
|
|
||||||
|
|
||||||
bool fullDuplex = spiCookie->isFullDuplex();
|
bool fullDuplex = spiCookie->isFullDuplex();
|
||||||
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
gpioId_t gpioId = spiCookie->getChipSelectPin();
|
||||||
bool csLockManual = spiCookie->getCsLockManual();
|
bool csLockManual = spiCookie->getCsLockManual();
|
||||||
|
spiCookie->setTransferSize(0);
|
||||||
|
|
||||||
MutexIF::TimeoutType csType;
|
MutexIF::TimeoutType csType;
|
||||||
dur_millis_t csTimeout = 0;
|
dur_millis_t csTimeout = 0;
|
||||||
@ -195,9 +194,13 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
|
if (result == MutexIF::MUTEX_TIMEOUT) {
|
||||||
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
|
sif::error << "SpiComIF::sendMessage: Lock timeout" << std::endl;
|
||||||
<< 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
|
#else
|
||||||
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
sif::printError("SpiComIF::sendMessage: Failed to lock mutex with code %d\n", result);
|
||||||
#endif
|
#endif
|
||||||
@ -214,17 +217,22 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
sif::printWarning("SpiComIF::sendMessage: Pulling low CS pin failed");
|
sif::printWarning("SpiComIF::sendMessage: Pulling low CS pin failed");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
csMutex->unlockMutex();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
updateLinePolarity(fileDescriptor);
|
updateLinePolarity(fileDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spiCookie->assignWriteBuffer(sendData);
|
||||||
|
spiCookie->setTransferSize(sendLen);
|
||||||
|
|
||||||
/* Execute transfer */
|
/* Execute transfer */
|
||||||
if (fullDuplex) {
|
if (fullDuplex) {
|
||||||
/* Initiate a full duplex SPI transfer. */
|
/* Initiate a full duplex SPI transfer. */
|
||||||
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle());
|
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle());
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
|
spiCookie->setTransferSize(0);
|
||||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||||
result = FULL_DUPLEX_TRANSFER_FAILED;
|
result = FULL_DUPLEX_TRANSFER_FAILED;
|
||||||
}
|
}
|
||||||
@ -234,6 +242,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
|
|||||||
} else {
|
} else {
|
||||||
/* We write with a blocking half-duplex transfer here */
|
/* We write with a blocking half-duplex transfer here */
|
||||||
if (write(fileDescriptor, sendData, sendLen) != static_cast<ssize_t>(sendLen)) {
|
if (write(fileDescriptor, sendData, sendLen) != static_cast<ssize_t>(sendLen)) {
|
||||||
|
spiCookie->setTransferSize(0);
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << std::endl;
|
sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << std::endl;
|
||||||
|
Loading…
Reference in New Issue
Block a user