Compare commits

...

55 Commits

Author SHA1 Message Date
2efff4d2c5 missing include 2023-02-21 02:59:13 +01:00
c327985222 printout tweak 2023-02-20 15:02:00 +01:00
c8469ca647 a lot of bug potential here 2023-02-18 14:03:19 +01:00
2d6622b8b8 wtf is this interface 2023-02-18 13:51:24 +01:00
5f9eb01d94 better naming 2023-02-18 13:46:51 +01:00
3568bdbecf lets see if this fixes the issue 2023-02-18 13:45:49 +01:00
fcd84b59ae how the hell does this break anything 2023-02-18 13:37:39 +01:00
e3c968096b i2c small improvements 2023-02-18 13:07:38 +01:00
be015b4c66 service 11: cast to fix warning 2023-02-17 12:07:50 +01:00
a6d707a7db SubsystemBase: Add function to update child modes 2023-02-17 02:04:17 +01:00
fe41d73895 remove obsolete mode 2023-02-16 17:57:03 +01:00
9de6c4b3aa printout corrections 2023-02-14 14:33:02 +01:00
d256ede8c1 fix cppcheck lint 2023-02-14 10:33:22 +01:00
f0b8457ba2 bugfix for SPI
- Set transfer length to 0 for failed transfers
2023-02-13 13:51:52 +01:00
dac2d210b5 updates for thermal module in DHB 2023-02-13 00:36:54 +01:00
8b4f73a97b better error msg 2023-02-12 21:07:11 +01:00
7fae6cbd6d added missing CS unlock 2023-02-12 20:06:32 +01:00
d302ba7185 afmt 2023-02-10 13:51:16 +01:00
14a92b3d89 typo 2023-02-09 18:28:16 +01:00
e4fd424d66 Merge branch 'possible_tc_sched_fixes' into develop 2023-02-09 18:25:44 +01:00
341a66c265 changelog 2023-02-09 18:22:00 +01:00
b9b076aa4c logic error 2023-02-09 18:18:25 +01:00
d93486a340 that time margin check is possible broken 2023-02-09 18:18:05 +01:00
820a7f059c logic error 2023-02-09 18:13:58 +01:00
f4d188c36f that time margin check is possible broken 2023-02-09 18:12:43 +01:00
1841f92944 important bugfix for thermal set 2023-02-09 17:17:42 +01:00
b279985859 refactor DHB: Bugfix for thermal module 2023-02-09 16:42:38 +01:00
fa7675897d Merge pull request 'Mode Service Bugfixes' (#736) from eive/fsfw:mode_service_fixes into development
Reviewed-on: fsfw/fsfw#736
2023-02-09 15:56:26 +01:00
3a2393885f more style 2023-02-09 15:44:39 +01:00
c752b6d143 Merge pull request 'Generic TMTC Bridge Update' (#734) from eive/fsfw:tmtcbridge_tweaks into development
Reviewed-on: fsfw/fsfw#734
2023-02-09 15:37:35 +01:00
b676040c7c Merge pull request 'CMakeLists file updates' (#731) from eive/fsfw:cmakelists_update into development
Reviewed-on: fsfw/fsfw#731
2023-02-09 15:29:46 +01:00
010509efb4 removed unneeded find_package parameter for etl 2023-02-09 13:50:16 +01:00
dfb1633f00 Merge branch 'development' into mode_service_fixes 2023-02-09 13:46:19 +01:00
5f7172e130 Merge pull request 'TCP/IP TMTC bridge memory leak fixes' (#737) from eive/fsfw:possible_tcpip_bridge_fixes into development
Reviewed-on: fsfw/fsfw#737
2023-02-09 12:15:45 +01:00
0c6465cd95 Merge pull request 'time stamper empty ctor' (#730) from eive/fsfw:empty_cds_short_ctor into development
Reviewed-on: fsfw/fsfw#730
2023-02-09 11:45:49 +01:00
f94987c46d Merge pull request 'RM3100 important bugfix' (#733) from eive/fsfw:rm3100_fixes into development
Reviewed-on: fsfw/fsfw#733
2023-02-09 11:41:53 +01:00
1809ce359b Merge pull request 'comment tweak to event parser can read everything' (#732) from eive/fsfw:health_if_update into development
Reviewed-on: fsfw/fsfw#732
2023-02-09 11:39:53 +01:00
8c712441ab Making fetch Catch2 quiet as well. 2023-02-09 11:34:58 +01:00
6ce80ea6c5 Merge branch 'possible_tcpip_bridge_fixes' into develop 2023-02-08 21:27:26 +01:00
f1b0ca7cff add PR link 2023-02-08 21:26:37 +01:00
000df85556 bump changelog 2023-02-08 21:24:00 +01:00
1fffcc2229 possiible leak fixes 2023-02-08 21:23:21 +01:00
a419806a05 Merge remote-tracking branch 'upstream/development' into mode_service_fixes 2023-02-08 09:33:13 +01:00
134d908f26 that stuff is not in upstream yet.. 2023-02-07 12:52:18 +01:00
40a9e12416 1000 is a bit much 2023-02-07 12:47:40 +01:00
f39054edd4 introduce warning switch 2023-02-07 12:45:29 +01:00
5adf89b911 changelog update 2023-02-07 12:41:42 +01:00
c2e6a22dec important bugfix for RM3100 2023-02-07 12:39:43 +01:00
c8e065a713 comment tweak to event parser can read everything 2023-02-07 12:36:42 +01:00
3ed49dbae3 Merge remote-tracking branch 'upstream/development' into empty_cds_short_ctor 2023-02-07 12:24:02 +01:00
4cf52d5dfe Merge pull request 'Time Service 9 update' (#726) from eive/fsfw:updates_fixes_pus_time_service into development
Reviewed-on: fsfw/fsfw#726
2023-02-07 12:19:45 +01:00
46230e6c6d Merge remote-tracking branch 'upstream/development' into updates_fixes_pus_time_service 2023-02-07 12:11:29 +01:00
b22d439300 bump changelog 2023-02-07 12:10:11 +01:00
7e7b3bbbc9 time stamper empty ctor 2023-02-07 12:07:41 +01:00
b1e9dd9e4a Merge remote-tracking branch 'upstream/development' into updates_fixes_pus_time_service 2023-02-06 14:24:38 +01:00
25 changed files with 136 additions and 116 deletions

View File

@@ -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

View File

@@ -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(

View File

@@ -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();
} }
} }
@@ -382,7 +376,7 @@ void DeviceHandlerBase::doStateMachine() {
} }
ReturnValue_t switchState = getStateOfSwitches(); ReturnValue_t switchState = getStateOfSwitches();
if ((switchState == PowerSwitchIF::SWITCH_OFF) || (switchState == NO_SWITCH)) { if ((switchState == PowerSwitchIF::SWITCH_OFF) || (switchState == NO_SWITCH)) {
setMode(_MODE_SWITCH_IS_OFF); setMode(MODE_OFF, SUBMODE_NONE);
} }
} break; } break;
case MODE_OFF: case MODE_OFF:
@@ -395,9 +389,6 @@ void DeviceHandlerBase::doStateMachine() {
case MODE_NORMAL: case MODE_NORMAL:
case MODE_ERROR_ON: case MODE_ERROR_ON:
break; break;
case _MODE_SWITCH_IS_OFF:
setMode(MODE_OFF, SUBMODE_NONE);
break;
default: default:
triggerEvent(OBJECT_IN_INVALID_MODE, mode, submode); triggerEvent(OBJECT_IN_INVALID_MODE, mode, submode);
setMode(_MODE_POWER_DOWN, 0); setMode(_MODE_POWER_DOWN, 0);
@@ -594,12 +585,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 +1079,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 +1141,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 +1467,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 +1484,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());
} }

View File

@@ -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"
@@ -149,11 +150,6 @@ class DeviceHandlerBase : public DeviceHandlerIF,
//! has been commanded on and the handler waits for it to be on. //! 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. //! 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; 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); 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 * 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 +922,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.
* *

View File

@@ -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_ */

View File

@@ -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_ */

View File

@@ -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;
} }

View File

@@ -126,10 +126,7 @@ ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL); tcpip::handleError(tcpip::Protocol::UDP, tcpip::ErrorSources::SENDTO_CALL);
} }
#if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 && FSFW_UDP_SEND_WIRETAPPING_ENABLED == 1
sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent sif::debug << "TmTcUdpBridge::sendTm: " << bytesSent << " bytes were sent" << std::endl;
<< " bytes were"
" sent."
<< std::endl;
#endif #endif
return returnvalue::OK; return returnvalue::OK;
} }

View File

@@ -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,24 +68,19 @@ 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;
} }
} }
}
ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply, ReturnValue_t CService200ModeCommanding::handleReply(const CommandMessage *reply,
Command_t previousCommand, uint32_t *state, Command_t previousCommand, uint32_t *state,

View File

@@ -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,

View File

@@ -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 < static_cast<uint32_t>(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"

View File

@@ -117,6 +117,20 @@ ReturnValue_t SubsystemBase::updateChildMode(MessageQueueId_t queue, Mode_t mode
return CHILD_NOT_FOUND; 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) { ReturnValue_t SubsystemBase::updateChildChangedHealth(MessageQueueId_t queue, bool changedHealth) {
for (auto iter = childrenMap.begin(); iter != childrenMap.end(); iter++) { for (auto iter = childrenMap.begin(); iter != childrenMap.end(); iter++) {
if (iter->second.commandQueue == queue) { if (iter->second.commandQueue == queue) {

View File

@@ -115,6 +115,7 @@ class SubsystemBase : public SystemObject,
Submode_t targetSubmode = SUBMODE_NONE); Submode_t targetSubmode = SUBMODE_NONE);
ReturnValue_t updateChildMode(MessageQueueId_t queue, Mode_t mode, Submode_t submode); 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); ReturnValue_t updateChildChangedHealth(MessageQueueId_t queue, bool changedHealth = true);

View File

@@ -4,6 +4,8 @@
#include "fsfw/timemanager/Clock.h" #include "fsfw/timemanager/Clock.h"
CdsShortTimeStamper::CdsShortTimeStamper() : SystemObject(0, false) {}
CdsShortTimeStamper::CdsShortTimeStamper(object_id_t objectId) : SystemObject(objectId) {} CdsShortTimeStamper::CdsShortTimeStamper(object_id_t objectId) : SystemObject(objectId) {}
ReturnValue_t CdsShortTimeStamper::serialize(uint8_t **buffer, size_t *size, size_t maxSize, ReturnValue_t CdsShortTimeStamper::serialize(uint8_t **buffer, size_t *size, size_t maxSize,

View File

@@ -18,6 +18,7 @@
class CdsShortTimeStamper : public TimeWriterIF, public TimeReaderIF, public SystemObject { class CdsShortTimeStamper : public TimeWriterIF, public TimeReaderIF, public SystemObject {
public: public:
static constexpr size_t TIMESTAMP_LEN = 7; static constexpr size_t TIMESTAMP_LEN = 7;
CdsShortTimeStamper();
/** /**
* @brief Default constructor which also registers the time stamper as a * @brief Default constructor which also registers the time stamper as a
* system object so it can be found with the #objectManager. * system object so it can be found with the #objectManager.

View File

@@ -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;

View File

@@ -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;

View File

@@ -6,14 +6,11 @@
#include "fsfw/FSFW.h" #include "fsfw/FSFW.h"
#include "fsfw/serviceinterface.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) std::string diagnosticPrefix)
: fileDescriptor(fileDescriptor) { : fdRef(fileDescriptor) {
if (fileDescriptor == nullptr) { fileDescriptor = open(device.c_str(), flags);
return; if (fileDescriptor < 0) {
}
*fileDescriptor = open(device.c_str(), flags);
if (*fileDescriptor < 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 << diagnosticPrefix << ": Opening device failed with error code " << errno << ": " 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() { UnixFileGuard::~UnixFileGuard() { close(fdRef); }
if (fileDescriptor != nullptr) {
close(*fileDescriptor);
}
}
ReturnValue_t UnixFileGuard::getOpenResult() const { return openStatus; } ReturnValue_t UnixFileGuard::getOpenResult() const { return openStatus; }

View File

@@ -15,7 +15,15 @@ class UnixFileGuard {
static constexpr ReturnValue_t OPEN_FILE_FAILED = 1; 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 = ""); std::string diagnosticPrefix = "");
virtual ~UnixFileGuard(); virtual ~UnixFileGuard();
@@ -23,7 +31,7 @@ class UnixFileGuard {
ReturnValue_t getOpenResult() const; ReturnValue_t getOpenResult() const;
private: private:
int* fileDescriptor = nullptr; int& fdRef;
ReturnValue_t openStatus = returnvalue::OK; ReturnValue_t openStatus = returnvalue::OK;
}; };

View File

@@ -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 I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
ReturnValue_t result; ReturnValue_t result;
int fd; int fd = 0;
std::string deviceFile;
if (sendData == nullptr) { if (sendData == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
@@ -98,12 +97,12 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
return returnvalue::FAILED; return returnvalue::FAILED;
} }
deviceFile = i2cCookie->getDeviceFile(); const auto& deviceFile = i2cCookie->getDeviceFile();
UnixFileGuard fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::sendMessage"); UnixFileGuard fileHelper(deviceFile, fd, O_RDWR, "I2cComIF::sendMessage");
if (fileHelper.getOpenResult() != returnvalue::OK) { if (fileHelper.getOpenResult() != returnvalue::OK) {
return fileHelper.getOpenResult(); return fileHelper.getOpenResult();
} }
result = openDevice(deviceFile, i2cAddress, &fd); result = openI2cSlave(deviceFile, i2cAddress, fd);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; 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 I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
ReturnValue_t result; ReturnValue_t result;
int fd; int fd = 0;
std::string deviceFile;
if (requestLen == 0) { if (requestLen == 0) {
return returnvalue::OK; return returnvalue::OK;
@@ -157,12 +155,12 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
} }
i2cDeviceMapIter->second.replyLen = 0; i2cDeviceMapIter->second.replyLen = 0;
deviceFile = i2cCookie->getDeviceFile(); auto& deviceFile = i2cCookie->getDeviceFile();
UnixFileGuard fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::requestReceiveMessage"); UnixFileGuard fileHelper(deviceFile, fd, O_RDWR, "I2cComIF::requestReceiveMessage");
if (fileHelper.getOpenResult() != returnvalue::OK) { if (fileHelper.getOpenResult() != returnvalue::OK) {
return fileHelper.getOpenResult(); return fileHelper.getOpenResult();
} }
result = openDevice(deviceFile, i2cAddress, &fd); result = openI2cSlave(deviceFile, i2cAddress, fd);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@@ -220,9 +218,9 @@ ReturnValue_t I2cComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t I2cComIF::openDevice(std::string deviceFile, address_t i2cAddress, ReturnValue_t I2cComIF::openI2cSlave(const std::string& deviceFile, address_t i2cAddress,
int* fileDescriptor) { int& fileDescriptor) {
if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) { if (ioctl(fileDescriptor, I2C_SLAVE, i2cAddress) < 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 << "I2cComIF: Specifying target device failed with error code " << errno << "." sif::warning << "I2cComIF: Specifying target device failed with error code " << errno << "."

View File

@@ -49,7 +49,8 @@ class I2cComIF : public DeviceCommunicationIF, public SystemObject {
* @param fileDescriptor Pointer to device descriptor. * @param fileDescriptor Pointer to device descriptor.
* @return returnvalue::OK if successful, otherwise returnvalue::FAILED. * @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_ */ #endif /* LINUX_I2C_I2COMIF_H_ */

View File

@@ -1,12 +1,12 @@
#include "fsfw_hal/linux/i2c/I2cCookie.h" #include "fsfw_hal/linux/i2c/I2cCookie.h"
I2cCookie::I2cCookie(address_t i2cAddress_, size_t maxReplyLen_, std::string deviceFile_) 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; } address_t I2cCookie::getAddress() const { return i2cAddress; }
size_t I2cCookie::getMaxReplyLen() const { return maxReplyLen; } size_t I2cCookie::getMaxReplyLen() const { return maxReplyLen; }
std::string I2cCookie::getDeviceFile() const { return deviceFile; } const std::string& I2cCookie::getDeviceFile() const { return deviceFile; }
I2cCookie::~I2cCookie() {} I2cCookie::~I2cCookie() {}

View File

@@ -25,7 +25,7 @@ class I2cCookie : public CookieIF {
address_t getAddress() const; address_t getAddress() const;
size_t getMaxReplyLen() const; size_t getMaxReplyLen() const;
std::string getDeviceFile() const; const std::string& getDeviceFile() const;
uint8_t errorCounter = 0; uint8_t errorCounter = 0;

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <fsfw_hal/linux/spi/SpiCookie.h>
#include "fsfw/ipc/MutexIF.h" #include "fsfw/ipc/MutexIF.h"
#include "fsfw/returnvalues/returnvalue.h" #include "fsfw/returnvalues/returnvalue.h"
#include "fsfw_hal/common/gpio/GpioIF.h" #include "fsfw_hal/common/gpio/GpioIF.h"

View File

@@ -75,7 +75,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF* cookie) {
spiCookie->getSpiParameters(spiMode, spiSpeed, &params); spiCookie->getSpiParameters(spiMode, spiSpeed, &params);
int fileDescriptor = 0; int fileDescriptor = 0;
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface"); UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
if (fileHelper.getOpenResult() != returnvalue::OK) { if (fileHelper.getOpenResult() != returnvalue::OK) {
return fileHelper.getOpenResult(); return fileHelper.getOpenResult();
} }
@@ -171,7 +171,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie* spiCookie, const
int retval = 0; int retval = 0;
/* Prepare transfer */ /* Prepare transfer */
int fileDescriptor = 0; int fileDescriptor = 0;
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage"); UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
if (fileHelper.getOpenResult() != returnvalue::OK) { if (fileHelper.getOpenResult() != returnvalue::OK) {
return OPENING_FILE_FAILED; return OPENING_FILE_FAILED;
} }
@@ -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
if (result == MutexIF::MUTEX_TIMEOUT) {
sif::error << "SpiComIF::sendMessage: Lock timeout" << std::endl;
} else {
sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code " sif::error << "SpiComIF::sendMessage: Failed to lock mutex with code "
<< "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec << "0x" << std::hex << std::setfill('0') << std::setw(4) << result << std::dec
<< std::endl; << 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;
@@ -276,7 +285,7 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) { ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
int fileDescriptor = 0; int fileDescriptor = 0;
UnixFileGuard fileHelper(dev, &fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage"); UnixFileGuard fileHelper(dev, fileDescriptor, O_RDWR, "SpiComIF::requestReceiveMessage");
if (fileHelper.getOpenResult() != returnvalue::OK) { if (fileHelper.getOpenResult() != returnvalue::OK) {
return OPENING_FILE_FAILED; return OPENING_FILE_FAILED;
} }