Compare commits

...

87 Commits

Author SHA1 Message Date
a8167f5431 added another helper function 2021-09-08 17:02:08 +02:00
41f3d7cf9a better name for function 2021-09-08 16:58:30 +02:00
e6e1936293 Merge remote-tracking branch 'origin/mueller/dhb-periodoc-reply-fix' into mueller/master 2021-09-08 16:21:13 +02:00
15f35f200a Merge remote-tracking branch 'origin/mueller/dhb-bugfixes-improvements' into mueller/master 2021-09-08 16:20:42 +02:00
6b20bb197a Merge branch 'development' into mueller/dhb-bugfixes-improvements 2021-09-08 16:20:04 +02:00
215d01b3ca Merge branch 'mueller/dhb-bugfixes-improvements' into mueller/master 2021-09-08 16:09:03 +02:00
dfe49cc1e5 DHB improvements 2021-09-08 16:08:13 +02:00
73eb11f4f1 bugfixes and improvements 2021-09-08 16:01:46 +02:00
0a56441510 Merge branch 'development' into mueller/dhb-periodoc-reply-fix 2021-09-06 18:51:58 +02:00
e226f19ca8 Merge pull request 'Make FSFW tests accessable from outside' (#461) from KSat/fsfw:mueller/tests-accessible-from-outside-squashed into development
Reviewed-on: fsfw/fsfw#461
2021-09-06 18:50:12 +02:00
7bf66dc401 Merge remote-tracking branch 'upstream/development' into mueller/dhb-periodoc-reply-fix 2021-09-06 12:10:12 +02:00
a6d744c9c8 Possible bugfix in DHB
The delayCycles variables needs to be initialized differently
for periodic replies.
It is initialized to the maxDelayCycles value now
2021-09-06 12:08:54 +02:00
924c150af2 Possible bugfix in DHB
The delayCycles variables needs to be initialized differently
for periodic replies.
It is initialized to the maxDelayCycles value now
2021-09-06 12:05:30 +02:00
469eba3ce2 raised limit 2021-09-06 11:35:14 +02:00
fd2916af11 moved TCP cfg 2021-08-23 09:40:02 +02:00
afd375a7f8 minor fix for canonical read handling 2021-08-22 20:24:50 +02:00
5454169e20 UartComIF: set O_NONBLOCK in canonical mode
When using the non-canonical mode, the file descriptor can be opened
in blocking mode because the VTIME and VMIN termios parameters are
used to configure non-blocking mode. However, in canonical mode, the fd needs to be opened with O_NONBLOCK
2021-08-22 19:48:35 +02:00
7d0377845b printout for unknown command 2021-08-20 15:46:34 +02:00
882da68a2f Merge branch 'mueller/unix-file-guard-fix' into mueller/master 2021-08-19 17:17:03 +02:00
b6aebb3061 format adapted 2021-08-19 17:08:35 +02:00
04a1fe7f10 Merge pull request 'Update FSFW' (#12) from mueller/update-fsfw into eive/develop
Reviewed-on: #12
2021-08-18 12:47:31 +02:00
845c00044e printout fixes for UnixFileGuard 2021-08-18 11:27:39 +02:00
5f79f987ae Merge branch 'eive/develop' into mueller/update-fsfw 2021-08-18 11:27:02 +02:00
1183e5739d using upstream action helper
Will be merged upstream soon
2021-08-18 11:23:45 +02:00
e3697d6d8c fixed printout 2021-08-17 19:50:01 +02:00
406b77ea81 moved SPI wiretapping cfg 2021-08-17 16:34:25 +02:00
92d3f0743b moved change to another PR 2021-08-16 15:26:28 +02:00
a18706ec53 Make FSFW tests accessible from outside
1. Further reduces the amount of code the user needs to copy and paste
2. Makes FSFW tests more accessible. This can be used to simplify moving mission unit tests
   to the FSFW
3. A lot of include improvements
2021-08-16 10:49:07 +02:00
8a9eb27458 Merge pull request 'FSFW Update' (#11) from mueller/master into eive/develop
Reviewed-on: #11
2021-08-11 13:13:11 +02:00
1ac372cb89 getter function for UDP port 2021-08-09 18:22:22 +02:00
fb36dc4501 More improvements for TCP/UDP port definition 2021-08-09 18:12:25 +02:00
ba5e2ad8bb Cleaning up TCP and UDP code
Same port number used as before, but some inconsistencies fixed
2021-08-09 16:57:24 +02:00
5a6c81130d Merge remote-tracking branch 'upstream/development' into mueller/master 2021-08-09 16:18:38 +02:00
d92a796705 Merge pull request 'FSFW Restructuring' (#445) from mueller/restructuring into development
Reviewed-on: fsfw/fsfw#445
2021-08-09 16:00:26 +02:00
1fa59c5cae Merge pull request 'Linux HAL updates' (#456) from mueller/hal-linux-spi-uart-update into mueller/restructuring
Reviewed-on: fsfw/fsfw#456
2021-08-09 15:39:18 +02:00
83b5ade6b7 Merge branch 'mueller/hal-linux-spi-uart-update' of https://egit.irs.uni-stuttgart.de/fsfw/fsfw into mueller/hal-linux-spi-uart-update 2021-08-09 15:38:07 +02:00
62873c3118 UartComIF check iter validity 2021-08-09 15:37:12 +02:00
1301988892 Merge branch 'mueller/restructuring' into mueller/hal-linux-spi-uart-update 2021-08-09 15:31:56 +02:00
1c3770ce96 Merge pull request 'Printer updates' (#453) from mueller/updated-serviceinterface into mueller/restructuring
Reviewed-on: fsfw/fsfw#453
2021-08-09 15:24:44 +02:00
22e29144b6 Merge remote-tracking branch 'origin/eive/develop' into mueller/master 2021-08-09 11:12:37 +02:00
52bff3985f Merge pull request 'set sequence flags in space packet base' (#9) from meier/spacePacketFlag into eive/develop
Reviewed-on: #9
2021-08-09 11:11:46 +02:00
133820f463 Merge branch 'eive/develop' into meier/spacePacketFlag 2021-08-08 15:32:24 +02:00
8d3fceea8f set sequence flags in space packet base 2021-08-08 15:26:18 +02:00
90a1571707 Linux HAL updates
1. The type correction was merged as part of
   #7 in the
   EIVE project. Quotation of PR

definition of getSpiParameters is `void getSpiParameters(spi::SpiModes& spiMode, uint32_t& spiSpeed, UncommonParameters* parameters = nullptr) const;`.

Here, size_t spiSpeed is passed, which implicitely gets converted to a temporary, which can not be bound to uint32_t& and, at least in gcc 9.3.0, leads to a compiler error.

2. Allow flushing the UART buffers
2021-08-06 11:23:31 +02:00
2706b8fa24 Printer updates
1. Only prefix is colored now
2. Minor formatting change
2021-08-06 11:06:33 +02:00
3704d2b829 bugfix 2021-08-05 18:24:56 +02:00
6073abb12d added some utility to timer module 2021-08-05 18:13:01 +02:00
47bec654a0 Merge pull request 'Update EIVE FSFW' (#8) from mueller/master into eive/develop
Reviewed-on: #8
2021-08-05 16:35:23 +02:00
b2c102b2c1 Service Interface and Bugfix
1. Service Interface looks better now
2. Bugfix in CommandExecutor blocking mode
2021-08-05 16:13:22 +02:00
4202205182 getter function for current state 2021-08-05 16:02:17 +02:00
c8472beb5f added new command executor 2021-08-05 15:42:47 +02:00
8b39248a33 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/fsfw/fsfw into mueller/master 2021-08-03 18:46:59 +02:00
ec00a84b29 update README for moved logo 2021-08-03 18:46:50 +02:00
1a4a85ceb2 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/eive/fsfw into mueller/master 2021-08-03 18:38:27 +02:00
7922bf76da corrected README 2021-08-03 18:38:18 +02:00
bb88490cc6 Merge remote-tracking branch 'upstream/mueller/restructuring' into mueller/master 2021-08-03 15:55:38 +02:00
296c587e3d additional nullptr check 2021-08-03 15:29:22 +02:00
4d9c07a1ec wrong path for sgp4 include 2021-08-02 21:22:56 +02:00
c3fbe04fc6 all include corrections 2021-08-02 20:58:56 +02:00
466f1e000f Merge branch 'mueller/master' into mueller/restructuring 2021-08-02 20:55:28 +02:00
f1f167c2d1 using _ instead of - now 2021-08-02 20:55:03 +02:00
6f816b2592 Merge branch 'mueller/master' into mueller/restructuring 2021-08-02 20:48:57 +02:00
0e5cfcf28f minor improvement for printout 2021-08-02 16:19:37 +02:00
dee063e259 Merge branch 'mueller/master' of https://egit.irs.uni-stuttgart.de/fsfw/fsfw into mueller/master 2021-08-02 15:47:49 +02:00
aabc729e77 include changes 2021-08-02 15:47:12 +02:00
c0591c3d24 renamed some folders 2021-08-02 15:31:13 +02:00
0ff81294e7 Merge branch 'eive/develop' of https://egit.irs.uni-stuttgart.de/eive/fsfw into eive/develop 2021-08-02 12:49:50 +02:00
b6e243b8b3 var name clarification 2021-08-02 12:49:40 +02:00
5bbe16081f added missing CMakeLists.txt 2021-07-30 14:38:20 +02:00
490ab440e5 smaller tweaks in CMakelists files 2021-07-30 14:21:37 +02:00
0b207b2b1a updated user folder 2021-07-30 14:18:47 +02:00
e1f92b3da4 various fixes and improvements 2021-07-30 13:47:29 +02:00
b75c815361 Merge remote-tracking branch 'origin/development' into mueller/master 2021-07-27 13:12:00 +02:00
a94725c423 Merge remote-tracking branch 'origin/development' into mueller/restructuring 2021-07-27 13:07:58 +02:00
2d667cfb95 Merge pull request 'Colored prefix option only if colored output is enabled' (#449) from meier/ColeredDebugOutput into development
Reviewed-on: fsfw/fsfw#449
2021-07-27 13:07:16 +02:00
3d80d5d036 added proposed changes 2021-07-27 12:59:21 +02:00
ebc9d99022 Merge branch 'meier/ColeredDebugOutput' of https://egit.irs.uni-stuttgart.de/fsfw/fsfw into meier/ColeredDebugOutput 2021-07-27 10:10:25 +02:00
2489276350 removed double include 2021-07-27 10:05:56 +02:00
3895806a2b Merge branch 'development' into meier/ColeredDebugOutput 2021-07-27 10:03:35 +02:00
3bbcc42d39 Merge pull request 'type missmatch' (#7) from mohr-patch-1 into eive/develop
Reviewed-on: #7
2021-07-26 19:04:06 +02:00
fc4324a2fa type missmatch 2021-07-26 18:35:53 +02:00
7b500eb0ed Merge pull request 'EventManager printout fixes and tweaks' (#447) from KSat/fsfw:mueller/event-manager-tweaks-printf-fix into development
Reviewed-on: fsfw/fsfw#447
2021-07-26 15:25:54 +02:00
54c028f913 naming adaptions 2021-07-26 13:50:45 +02:00
1f6a5e635f naming fixes 2021-07-26 11:46:58 +02:00
a918c672a5 fixed merge conflicts 2021-07-24 07:15:24 +02:00
1515d59432 EventManager fixes and tweaks
1. Using sif::info consistently now
2. Fix for printf support: Event translation is printed now as well
2021-07-21 09:45:36 +02:00
5e960f118f renamed freertos includes 2021-07-06 18:17:24 +02:00
193 changed files with 956 additions and 859 deletions

View File

@ -10,6 +10,8 @@ endif()
option(FSFW_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON) option(FSFW_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON)
# Options to exclude parts of the FSFW from compilation. # Options to exclude parts of the FSFW from compilation.
option(FSFW_ADD_INTERNAL_TESTS "Add internal unit tests" ON) option(FSFW_ADD_INTERNAL_TESTS "Add internal unit tests" ON)
option(FSFW_ADD_UNITTESTS "Add regular unittests. Requires Catch2" OFF)
option(FSFW_ADD_HAL "Add Hardware Abstraction Layer" ON)
# Optional sources # Optional sources
option(FSFW_ADD_PUS "Compile with PUS sources" ON) option(FSFW_ADD_PUS "Compile with PUS sources" ON)
@ -21,7 +23,7 @@ option(FSFW_ADD_COORDINATES "Compile with coordinate components" OFF)
option(FSFW_ADD_TMSTORAGE "Compile with tm storage components" OFF) option(FSFW_ADD_TMSTORAGE "Compile with tm storage components" OFF)
# Contrib sources # Contrib sources
option(FSFW_ADD_SPG4_PROPAGATOR "Add SPG4 propagator code" OFF) option(FSFW_ADD_SGP4_PROPAGATOR "Add SGP4 propagator code" OFF)
set(LIB_FSFW_NAME fsfw) set(LIB_FSFW_NAME fsfw)
add_library(${LIB_FSFW_NAME}) add_library(${LIB_FSFW_NAME})
@ -94,7 +96,9 @@ message(STATUS "Compiling FSFW for the ${OS_FSFW_NAME} operating system.")
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(tests) add_subdirectory(tests)
add_subdirectory(hal) if(FSFW_ADD_HAL)
add_subdirectory(hal)
endif()
add_subdirectory(contrib) add_subdirectory(contrib)
# The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it. # The project CMakeLists file has to set the FSFW_CONFIG_PATH and add it.

View File

@ -1,4 +1,4 @@
![FSFW Logo](logo/FSFW_Logo_V3_bw.png) ![FSFW Logo](misc/logo/FSFW_Logo_V3_bw.png)
# Flight Software Framework (FSFW) # Flight Software Framework (FSFW)

View File

@ -1,11 +1,9 @@
if(FSFW_ADD_SPG4_PROPAGATOR) target_include_directories(${LIB_FSFW_NAME} PRIVATE
target_sources(${LIB_FSFW_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
sgp4/sgp4unit.cpp )
)
target_include_directories(${LIB_FSFW_NAME} PRIVATE target_include_directories(${LIB_FSFW_NAME} INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/sgp4 ${CMAKE_CURRENT_SOURCE_DIR}
) )
target_include_directories(${LIB_FSFW_NAME} INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/sgp4 add_subdirectory(fsfw_contrib)
)
endif()

View File

@ -0,0 +1,11 @@
if(FSFW_ADD_SGP4_PROPAGATOR)
target_sources(${LIB_FSFW_NAME} PRIVATE
sgp4/sgp4unit.cpp
)
target_include_directories(${LIB_FSFW_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/sgp4
)
target_include_directories(${LIB_FSFW_NAME} INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/sgp4
)
endif()

View File

@ -6,4 +6,4 @@ target_include_directories(${LIB_FSFW_NAME} INTERFACE
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
) )
add_subdirectory(fsfw) add_subdirectory(fsfw_hal)

View File

@ -1 +0,0 @@
add_subdirectory(hal)

View File

@ -1,4 +1,4 @@
#include "fsfw/hal/common/gpio/GpioCookie.h" #include "fsfw_hal/common/gpio/GpioCookie.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
GpioCookie::GpioCookie() { GpioCookie::GpioCookie() {

View File

@ -1,4 +1,4 @@
#include "fsfw/hal/devicehandlers/GyroL3GD20Handler.h" #include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h"
#include "fsfw/datapool/PoolReadGuard.h" #include "fsfw/datapool/PoolReadGuard.h"

View File

@ -1,14 +1,14 @@
#ifndef MISSION_DEVICES_GYROL3GD20HANDLER_H_ #ifndef MISSION_DEVICES_GYROL3GD20HANDLER_H_
#define MISSION_DEVICES_GYROL3GD20HANDLER_H_ #define MISSION_DEVICES_GYROL3GD20HANDLER_H_
#include "OBSWConfig.h" #include "fsfw/FSFW.h"
#include "devicedefinitions/GyroL3GD20Definitions.h" #include "devicedefinitions/GyroL3GD20Definitions.h"
#include <fsfw/devicehandlers/DeviceHandlerBase.h> #include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <fsfw/globalfunctions/PeriodicOperationDivider.h> #include <fsfw/globalfunctions/PeriodicOperationDivider.h>
#ifndef FSFW_HAL_L3GD20_GYRO_DEBUG #ifndef FSFW_HAL_L3GD20_GYRO_DEBUG
#define FSFW_HAL_L3GD20_GYRO_DEBUG 1 #define FSFW_HAL_L3GD20_GYRO_DEBUG 0
#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */ #endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */
/** /**

View File

@ -1,4 +1,9 @@
#include "fsfw/hal/linux/UnixFileGuard.h" #include "fsfw/FSFW.h"
#include "fsfw/serviceinterface.h"
#include "fsfw_hal/linux/UnixFileGuard.h"
#include <cerrno>
#include <cstring>
UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int flags, UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int flags,
std::string diagnosticPrefix): std::string diagnosticPrefix):
@ -10,12 +15,11 @@ UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int flags,
if (*fileDescriptor < 0) { 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 " <<
"." << std::endl; errno << ": " << strerror(errno) << std::endl;
sif::warning << "Error description: " << strerror(errno) << std::endl;
#else #else
sif::printError("%sOpening device failed with error code %d.\n", diagnosticPrefix); sif::printWarning("%s: Opening device failed with error code %d: %s\n",
sif::printWarning("Error description: %s\n", strerror(errno)); diagnosticPrefix, errno, strerror(errno));
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FSFW_VERBOSE_LEVEL >= 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */
openStatus = OPEN_FILE_FAILED; openStatus = OPEN_FILE_FAILED;

View File

@ -1,6 +1,6 @@
#include "fsfw/hal/linux/gpio/LinuxLibgpioIF.h" #include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
#include "fsfw/hal/common/gpio/gpioDefinitions.h" #include "fsfw_hal/common/gpio/gpioDefinitions.h"
#include "fsfw/hal/common/gpio/GpioCookie.h" #include "fsfw_hal/common/gpio/GpioCookie.h"
#include <fsfw/serviceinterface/ServiceInterface.h> #include <fsfw/serviceinterface/ServiceInterface.h>

View File

@ -1,6 +1,6 @@
#include "fsfw/hal/linux/i2c/I2cComIF.h" #include "fsfw_hal/linux/i2c/I2cComIF.h"
#include "fsfw/hal/linux/utility.h" #include "fsfw_hal/linux/utility.h"
#include "fsfw/hal/linux/UnixFileGuard.h" #include "fsfw_hal/linux/UnixFileGuard.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"

View File

@ -1,4 +1,4 @@
#include "fsfw/hal/linux/i2c/I2cCookie.h" #include "fsfw_hal/linux/i2c/I2cCookie.h"
I2cCookie::I2cCookie(address_t i2cAddress_, size_t maxReplyLen_, I2cCookie::I2cCookie(address_t i2cAddress_, size_t maxReplyLen_,
std::string deviceFile_) : std::string deviceFile_) :

View File

@ -1,7 +1,7 @@
#include "fsfw/FSFW.h" #include "fsfw/FSFW.h"
#include "fsfw/hal/linux/rpi/GpioRPi.h" #include "fsfw_hal/linux/rpi/GpioRPi.h"
#include "fsfw/hal/common/gpio/GpioCookie.h" #include "fsfw_hal/common/gpio/GpioCookie.h"
#include <fsfw/serviceinterface/ServiceInterface.h> #include <fsfw/serviceinterface/ServiceInterface.h>

View File

@ -1,8 +1,8 @@
#include "fsfw/FSFW.h" #include "fsfw/FSFW.h"
#include "fsfw/hal/linux/spi/SpiComIF.h" #include "fsfw_hal/linux/spi/SpiComIF.h"
#include "fsfw/hal/linux/spi/SpiCookie.h" #include "fsfw_hal/linux/spi/SpiCookie.h"
#include "fsfw/hal/linux/utility.h" #include "fsfw_hal/linux/utility.h"
#include "fsfw/hal/linux/UnixFileGuard.h" #include "fsfw_hal/linux/UnixFileGuard.h"
#include <fsfw/ipc/MutexFactory.h> #include <fsfw/ipc/MutexFactory.h>
#include <fsfw/globalfunctions/arrayprinter.h> #include <fsfw/globalfunctions/arrayprinter.h>
@ -15,11 +15,6 @@
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
/* Can be used for low-level debugging of the SPI bus */
#ifndef FSFW_HAL_LINUX_SPI_WIRETAPPING
#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0
#endif
SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF):
SystemObject(objectId), gpioComIF(gpioComIF) { SystemObject(objectId), gpioComIF(gpioComIF) {
if(gpioComIF == nullptr) { if(gpioComIF == nullptr) {
@ -82,7 +77,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) {
gpioComIF->pullHigh(gpioId); gpioComIF->pullHigh(gpioId);
} }
size_t spiSpeed = 0; uint32_t spiSpeed = 0;
spi::SpiModes spiMode = spi::SpiModes::MODE_0; spi::SpiModes spiMode = spi::SpiModes::MODE_0;
SpiCookie::UncommonParameters params; SpiCookie::UncommonParameters params;
@ -90,7 +85,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) {
int fileDescriptor = 0; int fileDescriptor = 0;
UnixFileGuard fileHelper(spiCookie->getSpiDevice(), &fileDescriptor, O_RDWR, UnixFileGuard fileHelper(spiCookie->getSpiDevice(), &fileDescriptor, O_RDWR,
"SpiComIF::initializeInterface: "); "SpiComIF::initializeInterface");
if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
return fileHelper.getOpenResult(); return fileHelper.getOpenResult();
} }
@ -184,7 +179,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie *spiCookie, const
/* Prepare transfer */ /* Prepare transfer */
int fileDescriptor = 0; int fileDescriptor = 0;
std::string device = spiCookie->getSpiDevice(); std::string device = spiCookie->getSpiDevice();
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage: "); UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
return OPENING_FILE_FAILED; return OPENING_FILE_FAILED;
} }
@ -273,7 +268,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) {
std::string device = spiCookie->getSpiDevice(); std::string device = spiCookie->getSpiDevice();
int fileDescriptor = 0; int fileDescriptor = 0;
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR,
"SpiComIF::requestReceiveMessage: "); "SpiComIF::requestReceiveMessage");
if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
return OPENING_FILE_FAILED; return OPENING_FILE_FAILED;
} }

View File

@ -1,9 +1,10 @@
#ifndef LINUX_SPI_SPICOMIF_H_ #ifndef LINUX_SPI_SPICOMIF_H_
#define LINUX_SPI_SPICOMIF_H_ #define LINUX_SPI_SPICOMIF_H_
#include "fsfw/FSFW.h"
#include "spiDefinitions.h" #include "spiDefinitions.h"
#include "returnvalues/classIds.h" #include "returnvalues/classIds.h"
#include "fsfw/hal/common/gpio/GpioIF.h" #include "fsfw_hal/common/gpio/GpioIF.h"
#include "fsfw/devicehandlers/DeviceCommunicationIF.h" #include "fsfw/devicehandlers/DeviceCommunicationIF.h"
#include "fsfw/objectmanager/SystemObject.h" #include "fsfw/objectmanager/SystemObject.h"

View File

@ -1,4 +1,4 @@
#include "fsfw/hal/linux/spi/SpiCookie.h" #include "fsfw_hal/linux/spi/SpiCookie.h"
SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev,
const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed): const size_t maxSize, spi::SpiModes spiMode, uint32_t spiSpeed):

View File

@ -1,6 +1,7 @@
#include "fsfw/hal/linux/uart/UartComIF.h" #include "UartComIF.h"
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "fsfw_hal/linux/utility.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
#include <cstring> #include <cstring>
@ -60,7 +61,13 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
struct termios options = {}; struct termios options = {};
std::string deviceFile = uartCookie->getDeviceFile(); std::string deviceFile = uartCookie->getDeviceFile();
int fd = open(deviceFile.c_str(), O_RDWR); int flags = O_RDWR;
if(uartCookie->getUartMode() == UartModes::CANONICAL) {
// In non-canonical mode, don't specify O_NONBLOCK because these properties will be
// controlled by the VTIME and VMIN parameters and O_NONBLOCK would override this
flags |= O_NONBLOCK;
}
int fd = open(deviceFile.c_str(), flags);
if (fd < 0) { if (fd < 0) {
sif::warning << "UartComIF::configureUartPort: Failed to open uart " << deviceFile << sif::warning << "UartComIF::configureUartPort: Failed to open uart " << deviceFile <<
@ -259,23 +266,22 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki
ReturnValue_t UartComIF::sendMessage(CookieIF *cookie, ReturnValue_t UartComIF::sendMessage(CookieIF *cookie,
const uint8_t *sendData, size_t sendLen) { const uint8_t *sendData, size_t sendLen) {
int fd = 0; int fd = 0;
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; UartDeviceMapIter uartDeviceMapIter;
if(sendData == nullptr) {
sif::debug << "UartComIF::sendMessage: Send Data is nullptr" << std::endl;
return RETURN_FAILED;
}
if(sendLen == 0) { if(sendLen == 0) {
return RETURN_OK; return RETURN_OK;
} }
if(sendData == nullptr) {
sif::warning << "UartComIF::sendMessage: Send data is nullptr" << std::endl;
return RETURN_FAILED;
}
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie); UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
if(uartCookie == nullptr) { if(uartCookie == nullptr) {
sif::debug << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl; sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl;
return NULLPOINTER; return NULLPOINTER;
} }
@ -347,12 +353,13 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM
size_t maxReplySize = uartCookie.getMaxReplyLen(); size_t maxReplySize = uartCookie.getMaxReplyLen();
int fd = iter->second.fileDescriptor; int fd = iter->second.fileDescriptor;
auto bufferPtr = iter->second.replyBuffer.data(); auto bufferPtr = iter->second.replyBuffer.data();
iter->second.replyLen = 0;
do { do {
size_t allowedReadSize = 0; size_t allowedReadSize = 0;
if(currentBytesRead >= maxReplySize) { if(currentBytesRead >= maxReplySize) {
// Overflow risk. Emit warning, trigger event and break. If this happens, // Overflow risk. Emit warning, trigger event and break. If this happens,
// the reception buffer is not large enough or data is not polled often enough. // the reception buffer is not large enough or data is not polled often enough.
#if OBSW_VERBOSE_LEVEL >= 1 #if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!" sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!"
<< std::endl; << std::endl;
@ -370,7 +377,20 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM
bytesRead = read(fd, bufferPtr, allowedReadSize); bytesRead = read(fd, bufferPtr, allowedReadSize);
if (bytesRead < 0) { if (bytesRead < 0) {
return RETURN_FAILED; // EAGAIN: No data available in non-blocking mode
if(errno != EAGAIN) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::handleCanonicalRead: read failed with code" <<
errno << ": " << strerror(errno) << std::endl;
#else
sif::printWarning("UartComIF::handleCanonicalRead: read failed with code %d: %s\n",
errno, strerror(errno));
#endif
#endif
return RETURN_FAILED;
}
} }
else if(bytesRead > 0) { else if(bytesRead > 0) {
iter->second.replyLen += bytesRead; iter->second.replyLen += bytesRead;
@ -453,9 +473,12 @@ ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF *cookie) {
} }
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); uartDeviceMapIter = uartDeviceMap.find(deviceFile);
int fd = uartDeviceMapIter->second.fileDescriptor; if(uartDeviceMapIter != uartDeviceMap.end()) {
tcflush(fd, TCIFLUSH); int fd = uartDeviceMapIter->second.fileDescriptor;
return RETURN_OK; tcflush(fd, TCIFLUSH);
return RETURN_OK;
}
return RETURN_FAILED;
} }
ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF *cookie) { ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF *cookie) {
@ -468,9 +491,12 @@ ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF *cookie) {
} }
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); uartDeviceMapIter = uartDeviceMap.find(deviceFile);
int fd = uartDeviceMapIter->second.fileDescriptor; if(uartDeviceMapIter != uartDeviceMap.end()) {
tcflush(fd, TCOFLUSH); int fd = uartDeviceMapIter->second.fileDescriptor;
return RETURN_OK; tcflush(fd, TCOFLUSH);
return RETURN_OK;
}
return RETURN_FAILED;
} }
ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF *cookie) { ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF *cookie) {
@ -483,9 +509,12 @@ ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF *cookie) {
} }
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); uartDeviceMapIter = uartDeviceMap.find(deviceFile);
int fd = uartDeviceMapIter->second.fileDescriptor; if(uartDeviceMapIter != uartDeviceMap.end()) {
tcflush(fd, TCIOFLUSH); int fd = uartDeviceMapIter->second.fileDescriptor;
return RETURN_OK; tcflush(fd, TCIOFLUSH);
return RETURN_OK;
}
return RETURN_FAILED;
} }
void UartComIF::setUartMode(struct termios *options, UartCookie &uartCookie) { void UartComIF::setUartMode(struct termios *options, UartCookie &uartCookie) {

View File

@ -1,11 +1,11 @@
#include "fsfw/hal/linux/uart/UartCookie.h" #include "fsfw_hal/linux/uart/UartCookie.h"
#include <fsfw/serviceinterface/ServiceInterface.h> #include <fsfw/serviceinterface/ServiceInterface.h>
UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
uint32_t baudrate, size_t maxReplyLen): uint32_t baudrate, size_t maxReplyLen):
handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate), handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode),
maxReplyLen(maxReplyLen) { baudrate(baudrate), maxReplyLen(maxReplyLen) {
} }
UartCookie::~UartCookie() {} UartCookie::~UartCookie() {}

View File

@ -1,6 +1,6 @@
#include "fsfw/FSFW.h" #include "fsfw/FSFW.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/hal/linux/utility.h" #include "fsfw_hal/linux/utility.h"
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>

View File

@ -1,10 +1,10 @@
#include "fsfw/hal/stm32h7/devicetest/GyroL3GD20H.h" #include "fsfw_hal/stm32h7/devicetest/GyroL3GD20H.h"
#include "fsfw/hal/stm32h7/spi/mspInit.h" #include "fsfw_hal/stm32h7/spi/mspInit.h"
#include "fsfw/hal/stm32h7/spi/spiDefinitions.h" #include "fsfw_hal/stm32h7/spi/spiDefinitions.h"
#include "fsfw/hal/stm32h7/spi/spiCore.h" #include "fsfw_hal/stm32h7/spi/spiCore.h"
#include "fsfw/hal/stm32h7/spi/spiInterrupts.h" #include "fsfw_hal/stm32h7/spi/spiInterrupts.h"
#include "fsfw/hal/stm32h7/spi/stm32h743ziSpi.h" #include "fsfw_hal/stm32h7/spi/stm32h743ziSpi.h"
#include "fsfw/tasks/TaskFactory.h" #include "fsfw/tasks/TaskFactory.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"

View File

@ -1,4 +1,4 @@
#include <fsfw/hal/stm32h7/dma.h> #include <fsfw_hal/stm32h7/dma.h>
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>

View File

@ -1,4 +1,4 @@
#include "fsfw/hal/stm32h7/gpio/gpio.h" #include "fsfw_hal/stm32h7/gpio/gpio.h"
#include "stm32h7xx_hal_rcc.h" #include "stm32h7xx_hal_rcc.h"

View File

@ -1,11 +1,11 @@
#include "fsfw/hal/stm32h7/spi/SpiComIF.h" #include "fsfw_hal/stm32h7/spi/SpiComIF.h"
#include "fsfw/hal/stm32h7/spi/SpiCookie.h" #include "fsfw_hal/stm32h7/spi/SpiCookie.h"
#include "fsfw/tasks/SemaphoreFactory.h" #include "fsfw/tasks/SemaphoreFactory.h"
#include "fsfw/hal/stm32h7/spi/spiCore.h" #include "fsfw_hal/stm32h7/spi/spiCore.h"
#include "fsfw/hal/stm32h7/spi/spiInterrupts.h" #include "fsfw_hal/stm32h7/spi/spiInterrupts.h"
#include "fsfw/hal/stm32h7/spi/mspInit.h" #include "fsfw_hal/stm32h7/spi/mspInit.h"
#include "fsfw/hal/stm32h7/gpio/gpio.h" #include "fsfw_hal/stm32h7/gpio/gpio.h"
// FreeRTOS required special Semaphore handling from an ISR. Therefore, we use the concrete // FreeRTOS required special Semaphore handling from an ISR. Therefore, we use the concrete
// instance here, because RTEMS and FreeRTOS are the only relevant OSALs currently // instance here, because RTEMS and FreeRTOS are the only relevant OSALs currently

View File

@ -5,7 +5,7 @@
#include "fsfw/devicehandlers/DeviceCommunicationIF.h" #include "fsfw/devicehandlers/DeviceCommunicationIF.h"
#include "fsfw/objectmanager/SystemObject.h" #include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/hal/stm32h7/spi/spiDefinitions.h" #include "fsfw_hal/stm32h7/spi/spiDefinitions.h"
#include "stm32h7xx_hal_spi.h" #include "stm32h7xx_hal_spi.h"
#include "stm32h743xx.h" #include "stm32h743xx.h"

View File

@ -1,4 +1,4 @@
#include "fsfw/hal/stm32h7/spi/SpiCookie.h" #include "fsfw_hal/stm32h7/spi/SpiCookie.h"
SpiCookie::SpiCookie(address_t deviceAddress, spi::SpiBus spiIdx, spi::TransferModes transferMode, SpiCookie::SpiCookie(address_t deviceAddress, spi::SpiBus spiIdx, spi::TransferModes transferMode,

View File

@ -1,7 +1,7 @@
#include "fsfw/hal/stm32h7/dma.h" #include "fsfw_hal/stm32h7/dma.h"
#include "fsfw/hal/stm32h7/spi/mspInit.h" #include "fsfw_hal/stm32h7/spi/mspInit.h"
#include "fsfw/hal/stm32h7/spi/spiCore.h" #include "fsfw_hal/stm32h7/spi/spiCore.h"
#include "fsfw/hal/stm32h7/spi/spiInterrupts.h" #include "fsfw_hal/stm32h7/spi/spiInterrupts.h"
#include "stm32h743xx.h" #include "stm32h743xx.h"
#include "stm32h7xx_hal_spi.h" #include "stm32h7xx_hal_spi.h"

View File

@ -1,5 +1,5 @@
#include "fsfw/hal/stm32h7/spi/spiCore.h" #include "fsfw_hal/stm32h7/spi/spiCore.h"
#include "fsfw/hal/stm32h7/spi/spiDefinitions.h" #include "fsfw_hal/stm32h7/spi/spiDefinitions.h"
#include <cstdio> #include <cstdio>

View File

@ -1,8 +1,8 @@
#ifndef FSFW_HAL_STM32H7_SPI_SPICORE_H_ #ifndef FSFW_HAL_STM32H7_SPI_SPICORE_H_
#define FSFW_HAL_STM32H7_SPI_SPICORE_H_ #define FSFW_HAL_STM32H7_SPI_SPICORE_H_
#include "fsfw/hal/stm32h7/dma.h" #include "fsfw_hal/stm32h7/dma.h"
#include "fsfw/hal/stm32h7/spi/spiDefinitions.h" #include "fsfw_hal/stm32h7/spi/spiDefinitions.h"
#include "stm32h7xx_hal.h" #include "stm32h7xx_hal.h"
#include "stm32h7xx_hal_dma.h" #include "stm32h7xx_hal_dma.h"

View File

@ -1,4 +1,4 @@
#include "fsfw/hal/stm32h7/spi/spiDefinitions.h" #include "fsfw_hal/stm32h7/spi/spiDefinitions.h"
void spi::assignSpiMode(SpiModes spiMode, SPI_HandleTypeDef& spiHandle) { void spi::assignSpiMode(SpiModes spiMode, SPI_HandleTypeDef& spiHandle) {
switch(spiMode) { switch(spiMode) {

View File

@ -1,5 +1,5 @@
#include "fsfw/hal/stm32h7/spi/spiInterrupts.h" #include "fsfw_hal/stm32h7/spi/spiInterrupts.h"
#include "fsfw/hal/stm32h7/spi/spiCore.h" #include "fsfw_hal/stm32h7/spi/spiCore.h"
#include "stm32h7xx_hal.h" #include "stm32h7xx_hal.h"
#include "stm32h7xx_hal_dma.h" #include "stm32h7xx_hal_dma.h"

View File

@ -1,6 +1,6 @@
#include "fsfw/hal/stm32h7/spi/stm32h743ziSpi.h" #include "fsfw_hal/stm32h7/spi/stm32h743ziSpi.h"
#include "fsfw/hal/stm32h7/spi/spiCore.h" #include "fsfw_hal/stm32h7/spi/spiCore.h"
#include "fsfw/hal/stm32h7/spi/spiInterrupts.h" #include "fsfw_hal/stm32h7/spi/spiInterrupts.h"
#include "stm32h7xx_hal.h" #include "stm32h7xx_hal.h"
#include "stm32h7xx_hal_rcc.h" #include "stm32h7xx_hal_rcc.h"

View File

@ -4,7 +4,7 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h> #include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <fsfw/events/EventManager.h> #include <fsfw/events/EventManager.h>
#include <fsfw/health/HealthTable.h> #include <fsfw/health/HealthTable.h>
#include <fsfw/tmtcpacket/pus/TmPacketStored.h> #include <fsfw/tmtcpacket/pus/tm/TmPacketStored.h>
#include <fsfw/tmtcservices/CommandingServiceBase.h> #include <fsfw/tmtcservices/CommandingServiceBase.h>
#include <fsfw/tmtcservices/PusServiceBase.h> #include <fsfw/tmtcservices/PusServiceBase.h>
#include <fsfw/internalError/InternalErrorReporter.h> #include <fsfw/internalError/InternalErrorReporter.h>

View File

@ -9,5 +9,19 @@
#cmakedefine FSFW_ADD_COORDINATES #cmakedefine FSFW_ADD_COORDINATES
#cmakedefine FSFW_ADD_PUS #cmakedefine FSFW_ADD_PUS
#cmakedefine FSFW_ADD_MONITORING #cmakedefine FSFW_ADD_MONITORING
#cmakedefine FSFW_ADD_SGP4_PROPAGATOR
#ifndef FSFW_TCP_RECV_WIRETAPPING_ENABLED
#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0
#endif
/* Can be used for low-level debugging of the SPI bus */
#ifndef FSFW_HAL_LINUX_SPI_WIRETAPPING
#define FSFW_HAL_LINUX_SPI_WIRETAPPING 0
#endif
#ifndef FSFW_HAL_L3GD20_GYRO_DEBUG
#define FSFW_HAL_L3GD20_GYRO_DEBUG 0
#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */
#endif /* FSFW_FSFW_H_ */ #endif /* FSFW_FSFW_H_ */

View File

@ -7,7 +7,7 @@
#ifndef PLATFORM_WIN #ifndef PLATFORM_WIN
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "fsfw/contrib/sgp4/sgp4unit.h" #include "fsfw_contrib/sgp4/sgp4unit.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h"
class Sgp4Propagator { class Sgp4Propagator {

View File

@ -8,4 +8,9 @@
not enabled with FSFW_ADD_COORDINATES not enabled with FSFW_ADD_COORDINATES
#endif #endif
#ifndef FSFW_ADD_SGP4_PROPAGATOR
#warning Coordinates files were included but SGP4 contributed code compilation was \
not enabled with FSFW_ADD_SGP4_PROPAGATOR
#endif
#endif /* FSFW_SRC_FSFW_COORDINATES_COORDINATESCONF_H_ */ #endif /* FSFW_SRC_FSFW_COORDINATES_COORDINATESCONF_H_ */

View File

@ -85,9 +85,10 @@ public:
* Called by DHB in the GET_WRITE doGetWrite(). * Called by DHB in the GET_WRITE doGetWrite().
* Get send confirmation that the data in sendMessage() was sent successfully. * Get send confirmation that the data in sendMessage() was sent successfully.
* @param cookie * @param cookie
* @return - @c RETURN_OK if data was sent successfull * @return
* - Everything else triggers falure event with * - @c RETURN_OK if data was sent successfully but a reply is expected
* returnvalue as parameter 1 * - NO_REPLY_EXPECTED if data was sent successfully and no reply is expected
* - Everything else to indicate failure
*/ */
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0; virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0;

View File

@ -430,7 +430,12 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
DeviceReplyInfo info; DeviceReplyInfo info;
info.maxDelayCycles = maxDelayCycles; info.maxDelayCycles = maxDelayCycles;
info.periodic = periodic; info.periodic = periodic;
info.delayCycles = 0; if(info.periodic) {
info.delayCycles = info.maxDelayCycles;
}
else {
info.delayCycles = 0;
}
info.replyLen = replyLen; info.replyLen = replyLen;
info.dataSet = dataSet; info.dataSet = dataSet;
info.command = deviceCommandMap.end(); info.command = deviceCommandMap.end();
@ -648,11 +653,12 @@ void DeviceHandlerBase::doGetWrite() {
replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true); replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true);
} }
//We need to distinguish here, because a raw command never expects a reply. // We need to distinguish here, because a raw command never expects a reply.
//(Could be done in eRIRM, but then child implementations need to be careful. // This could be done in the #enableReplyInReplyMap call,
// but then child implementations would need to be careful.
result = enableReplyInReplyMap(cookieInfo.pendingCommand); result = enableReplyInReplyMap(cookieInfo.pendingCommand);
} else { } else if (result != NO_REPLY_EXPECTED) {
//always generate a failure event, so that FDIR knows what's up // always generate a failure event, so that FDIR knows what's up
triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result,
cookieInfo.pendingCommand->first); cookieInfo.pendingCommand->first);
} }
@ -1336,10 +1342,20 @@ void DeviceHandlerBase::buildInternalCommand(void) {
DeviceCommandMap::iterator iter = deviceCommandMap.find( DeviceCommandMap::iterator iter = deviceCommandMap.find(
deviceCommandId); deviceCommandId);
if (iter == deviceCommandMap.end()) { if (iter == deviceCommandMap.end()) {
#if FSFW_VERBOSE_LEVEL >= 1
char output[36];
sprintf(output, "Command 0x%08x unknown",
static_cast<unsigned int>(deviceCommandId));
// so we can track misconfigurations
printWarningOrError(sif::OutputTypes::OUT_WARNING,
"buildInternalCommand",
COMMAND_NOT_SUPPORTED,
output);
#endif
result = COMMAND_NOT_SUPPORTED; result = COMMAND_NOT_SUPPORTED;
} }
else if (iter->second.isExecuting) { else if (iter->second.isExecuting) {
#if FSFW_DISABLE_PRINTOUT == 0 #if FSFW_VERBOSE_LEVEL >= 1
char output[36]; char output[36];
sprintf(output, "Command 0x%08x is executing", sprintf(output, "Command 0x%08x is executing",
static_cast<unsigned int>(deviceCommandId)); static_cast<unsigned int>(deviceCommandId));
@ -1550,10 +1566,18 @@ LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() {
return &poolManager; return &poolManager;
} }
MessageQueueId_t DeviceHandlerBase::getCommanderId(DeviceCommandId_t replyId) const { MessageQueueId_t DeviceHandlerBase::getCommanderQueueId(DeviceCommandId_t replyId) const {
auto commandIter = deviceCommandMap.find(replyId); auto commandIter = deviceCommandMap.find(replyId);
if(commandIter == deviceCommandMap.end()) { if(commandIter == deviceCommandMap.end()) {
return MessageQueueIF::NO_QUEUE; return MessageQueueIF::NO_QUEUE;
} }
return commandIter->second.sendReplyTo; return commandIter->second.sendReplyTo;
} }
void DeviceHandlerBase::finishCommandExecution(DeviceCommandId_t replyId) {
auto commandIter = deviceCommandMap.find(replyId);
if(commandIter == deviceCommandMap.end()) {
return;
}
commandIter->second.isExecuting = false;
}

View File

@ -327,15 +327,20 @@ protected:
* The existence of the command in the command map and the command size check against 0 are * The existence of the command in the command map and the command size check against 0 are
* done by the base class. * done by the base class.
* *
* The base class will generate a finish reply or a step automatically as long as the
* send success is confirmed in the #getSendSuccess function call of the communication
* interface. NO_REPLY_EXPECTED should be returned for a finish reply, RETURN_OK should be
* returned for a step reply and everything else will trigger a step failure.
*
* If the commander ID is required for generating a finish reply immediately, it can be
* retrieved using the #getCommanderQueueId function.
*
* @param deviceCommand The command to build, already checked against deviceCommandMap * @param deviceCommand The command to build, already checked against deviceCommandMap
* @param commandData Pointer to the data from the direct command * @param commandData Pointer to the data from the direct command
* @param commandDataLen Length of commandData * @param commandDataLen Length of commandData
* @return * @return
* - @c RETURN_OK to send command after #rawPacket and #rawPacketLen * - @c RETURN_OK to send command after #rawPacket and #rawPacketLen
* have been set. * have been set.
* - @c HasActionsIF::EXECUTION_COMPLETE to generate a finish reply immediately. This can
* be used if no reply is expected. Otherwise, the developer can call #actionHelper.finish
* to finish the command handling.
* - Anything else triggers an event with the return code as a parameter as well as a * - Anything else triggers an event with the return code as a parameter as well as a
* step reply failed with the return code * step reply failed with the return code
*/ */
@ -399,7 +404,9 @@ protected:
*/ */
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) = 0; const uint8_t *packet) = 0;
MessageQueueId_t getCommanderId(DeviceCommandId_t replyId) const; MessageQueueId_t getCommanderQueueId(DeviceCommandId_t replyId) const;
void finishCommandExecution(DeviceCommandId_t replyId);
/** /**
* Helper function to get pending command. This is useful for devices * Helper function to get pending command. This is useful for devices
* like SPI sensors to identify the last sent command. * like SPI sensors to identify the last sent command.

View File

@ -120,7 +120,8 @@ public:
static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5); static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5);
static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6); static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6);
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7); static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7);
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command. //!< Used to indicate that this is a command-only command.
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8);
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9); static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA); static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);

View File

@ -12,119 +12,119 @@ MessageQueueId_t EventManagerIF::eventmanagerQueue = MessageQueueIF::NO_QUEUE;
// So a good guess is 75 to a max of 100 pools required for each, which fits well. // So a good guess is 75 to a max of 100 pools required for each, which fits well.
const LocalPool::LocalPoolConfig EventManager::poolConfig = { const LocalPool::LocalPoolConfig EventManager::poolConfig = {
{fsfwconfig::FSFW_EVENTMGMR_MATCHTREE_NODES, {fsfwconfig::FSFW_EVENTMGMR_MATCHTREE_NODES,
sizeof(EventMatchTree::Node)}, sizeof(EventMatchTree::Node)},
{fsfwconfig::FSFW_EVENTMGMT_EVENTIDMATCHERS, {fsfwconfig::FSFW_EVENTMGMT_EVENTIDMATCHERS,
sizeof(EventIdRangeMatcher)}, sizeof(EventIdRangeMatcher)},
{fsfwconfig::FSFW_EVENTMGMR_RANGEMATCHERS, {fsfwconfig::FSFW_EVENTMGMR_RANGEMATCHERS,
sizeof(ReporterRangeMatcher)} sizeof(ReporterRangeMatcher)}
}; };
EventManager::EventManager(object_id_t setObjectId) : EventManager::EventManager(object_id_t setObjectId) :
SystemObject(setObjectId), SystemObject(setObjectId),
factoryBackend(0, poolConfig, false, true) { factoryBackend(0, poolConfig, false, true) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
eventReportQueue = QueueFactory::instance()->createMessageQueue( eventReportQueue = QueueFactory::instance()->createMessageQueue(
MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE); MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE);
} }
EventManager::~EventManager() { EventManager::~EventManager() {
QueueFactory::instance()->deleteMessageQueue(eventReportQueue); QueueFactory::instance()->deleteMessageQueue(eventReportQueue);
MutexFactory::instance()->deleteMutex(mutex); MutexFactory::instance()->deleteMutex(mutex);
} }
MessageQueueId_t EventManager::getEventReportQueue() { MessageQueueId_t EventManager::getEventReportQueue() {
return eventReportQueue->getId(); return eventReportQueue->getId();
} }
ReturnValue_t EventManager::performOperation(uint8_t opCode) { ReturnValue_t EventManager::performOperation(uint8_t opCode) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
while (result == HasReturnvaluesIF::RETURN_OK) { while (result == HasReturnvaluesIF::RETURN_OK) {
EventMessage message; EventMessage message;
result = eventReportQueue->receiveMessage(&message); result = eventReportQueue->receiveMessage(&message);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
#if FSFW_OBJ_EVENT_TRANSLATION == 1 #if FSFW_OBJ_EVENT_TRANSLATION == 1
printEvent(&message); printEvent(&message);
#endif #endif
notifyListeners(&message); notifyListeners(&message);
} }
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void EventManager::notifyListeners(EventMessage* message) { void EventManager::notifyListeners(EventMessage* message) {
lockMutex(); lockMutex();
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) { for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
if (iter->second.match(message)) { if (iter->second.match(message)) {
MessageQueueSenderIF::sendMessage(iter->first, message, MessageQueueSenderIF::sendMessage(iter->first, message,
message->getSender()); message->getSender());
} }
} }
unlockMutex(); unlockMutex();
} }
ReturnValue_t EventManager::registerListener(MessageQueueId_t listener, ReturnValue_t EventManager::registerListener(MessageQueueId_t listener,
bool forwardAllButSelected) { bool forwardAllButSelected) {
auto result = listenerList.insert( auto result = listenerList.insert(
std::pair<MessageQueueId_t, EventMatchTree>(listener, std::pair<MessageQueueId_t, EventMatchTree>(listener,
EventMatchTree(&factoryBackend, forwardAllButSelected))); EventMatchTree(&factoryBackend, forwardAllButSelected)));
if (!result.second) { if (!result.second) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t EventManager::subscribeToEvent(MessageQueueId_t listener, ReturnValue_t EventManager::subscribeToEvent(MessageQueueId_t listener,
EventId_t event) { EventId_t event) {
return subscribeToEventRange(listener, event); return subscribeToEventRange(listener, event);
} }
ReturnValue_t EventManager::subscribeToAllEventsFrom(MessageQueueId_t listener, ReturnValue_t EventManager::subscribeToAllEventsFrom(MessageQueueId_t listener,
object_id_t object) { object_id_t object) {
return subscribeToEventRange(listener, 0, 0, true, object); return subscribeToEventRange(listener, 0, 0, true, object);
} }
ReturnValue_t EventManager::subscribeToEventRange(MessageQueueId_t listener, ReturnValue_t EventManager::subscribeToEventRange(MessageQueueId_t listener,
EventId_t idFrom, EventId_t idTo, bool idInverted, EventId_t idFrom, EventId_t idTo, bool idInverted,
object_id_t reporterFrom, object_id_t reporterTo, object_id_t reporterFrom, object_id_t reporterTo,
bool reporterInverted) { bool reporterInverted) {
auto iter = listenerList.find(listener); auto iter = listenerList.find(listener);
if (iter == listenerList.end()) { if (iter == listenerList.end()) {
return LISTENER_NOT_FOUND; return LISTENER_NOT_FOUND;
} }
lockMutex(); lockMutex();
ReturnValue_t result = iter->second.addMatch(idFrom, idTo, idInverted, ReturnValue_t result = iter->second.addMatch(idFrom, idTo, idInverted,
reporterFrom, reporterTo, reporterInverted); reporterFrom, reporterTo, reporterInverted);
unlockMutex(); unlockMutex();
return result; return result;
} }
ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener, ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener,
EventId_t idFrom, EventId_t idTo, bool idInverted, EventId_t idFrom, EventId_t idTo, bool idInverted,
object_id_t reporterFrom, object_id_t reporterTo, object_id_t reporterFrom, object_id_t reporterTo,
bool reporterInverted) { bool reporterInverted) {
auto iter = listenerList.find(listener); auto iter = listenerList.find(listener);
if (iter == listenerList.end()) { if (iter == listenerList.end()) {
return LISTENER_NOT_FOUND; return LISTENER_NOT_FOUND;
} }
lockMutex(); lockMutex();
ReturnValue_t result = iter->second.removeMatch(idFrom, idTo, idInverted, ReturnValue_t result = iter->second.removeMatch(idFrom, idTo, idInverted,
reporterFrom, reporterTo, reporterInverted); reporterFrom, reporterTo, reporterInverted);
unlockMutex(); unlockMutex();
return result; return result;
} }
void EventManager::lockMutex() { void EventManager::lockMutex() {
mutex->lockMutex(timeoutType, timeoutMs); mutex->lockMutex(timeoutType, timeoutMs);
} }
void EventManager::unlockMutex() { void EventManager::unlockMutex() {
mutex->unlockMutex(); mutex->unlockMutex();
} }
void EventManager::setMutexTimeout(MutexIF::TimeoutType timeoutType, void EventManager::setMutexTimeout(MutexIF::TimeoutType timeoutType,
uint32_t timeoutMs) { uint32_t timeoutMs) {
this->timeoutType = timeoutType; this->timeoutType = timeoutType;
this->timeoutMs = timeoutMs; this->timeoutMs = timeoutMs;
} }
#if FSFW_OBJ_EVENT_TRANSLATION == 1 #if FSFW_OBJ_EVENT_TRANSLATION == 1
@ -157,7 +157,7 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage *messag
message->getReporter() << std::setfill(' ') << std::dec; message->getReporter() << std::setfill(' ') << std::dec;
} }
sif::info << " reported event with ID " << message->getEventId() << std::endl; sif::info << " reported event with ID " << message->getEventId() << std::endl;
sif::debug << translateEvents(message->getEvent()) << " | " <<std::hex << "P1 Hex: 0x" << sif::info << translateEvents(message->getEvent()) << " | " <<std::hex << "P1 Hex: 0x" <<
message->getParameter1() << " | P1 Dec: " << std::dec << message->getParameter1() << message->getParameter1() << " | P1 Dec: " << std::dec << message->getParameter1() <<
std::hex << " | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " << std::hex << " | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " <<
std::dec << message->getParameter2() << std::endl; std::dec << message->getParameter2() << std::endl;
@ -170,9 +170,10 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage *messag
sif::printInfo("Event Manager: Reporter ID 0x%08x reported event with ID %d\n", sif::printInfo("Event Manager: Reporter ID 0x%08x reported event with ID %d\n",
message->getReporter(), message->getEventId()); message->getReporter(), message->getEventId());
} }
sif::printInfo("P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n",
message->getParameter1(), message->getParameter1(), sif::printInfo("%s | P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n",
message->getParameter2(), message->getParameter2()); translateEvents(message->getEvent()), message->getParameter1(),
message->getParameter1(), message->getParameter2(), message->getParameter2());
#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ #endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */
} }
else { else {

View File

@ -1,6 +1,5 @@
#include "fsfw/platform.h" #include "fsfw/platform.h"
#include "fsfw/osal/common/TcpTmTcBridge.h" #include "fsfw/osal/common/TcpTmTcBridge.h"
#include "fsfw/osal/common/tcpipHelpers.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/ipc/MutexGuard.h" #include "fsfw/ipc/MutexGuard.h"
@ -17,8 +16,6 @@
#endif #endif
const std::string TcpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
object_id_t tmStoreId, object_id_t tcStoreId): object_id_t tmStoreId, object_id_t tcStoreId):
TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {

View File

@ -2,7 +2,7 @@
#define FSFW_OSAL_COMMON_TCPTMTCBRIDGE_H_ #define FSFW_OSAL_COMMON_TCPTMTCBRIDGE_H_
#include "TcpIpBase.h" #include "TcpIpBase.h"
#include "../../tmtcservices/TmTcBridge.h" #include "fsfw/tmtcservices/TmTcBridge.h"
#ifdef _WIN32 #ifdef _WIN32
@ -29,8 +29,6 @@ class TcpTmTcBridge:
public TmTcBridge { public TmTcBridge {
friend class TcpTmTcServer; friend class TcpTmTcServer;
public: public:
/* The ports chosen here should not be used by any other process. */
static const std::string DEFAULT_UDP_SERVER_PORT;
/** /**
* Constructor * Constructor

View File

@ -1,8 +1,10 @@
#include "fsfw/osal/common/TcpTmTcServer.h"
#include "fsfw/osal/common/TcpTmTcBridge.h"
#include "fsfw/osal/common/tcpipHelpers.h"
#include "fsfw/platform.h" #include "fsfw/platform.h"
#include "fsfw/FSFW.h"
#include "TcpTmTcServer.h"
#include "TcpTmTcBridge.h"
#include "tcpipHelpers.h"
#include "fsfw/container/SharedRingBuffer.h" #include "fsfw/container/SharedRingBuffer.h"
#include "fsfw/ipc/MessageQueueSenderIF.h" #include "fsfw/ipc/MessageQueueSenderIF.h"
#include "fsfw/ipc/MutexGuard.h" #include "fsfw/ipc/MutexGuard.h"
@ -18,18 +20,14 @@
#include <netdb.h> #include <netdb.h>
#endif #endif
#ifndef FSFW_TCP_RECV_WIRETAPPING_ENABLED const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
#define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0
#endif
const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7303";
TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge,
size_t receptionBufferSize, std::string customTcpServerPort): size_t receptionBufferSize, std::string customTcpServerPort):
SystemObject(objectId), tmtcBridgeId(tmtcTcpBridge), SystemObject(objectId), tmtcBridgeId(tmtcTcpBridge),
tcpPort(customTcpServerPort), receptionBuffer(receptionBufferSize) { tcpPort(customTcpServerPort), receptionBuffer(receptionBufferSize) {
if(tcpPort == "") { if(tcpPort == "") {
tcpPort = DEFAULT_TCP_SERVER_PORT; tcpPort = DEFAULT_SERVER_PORT;
} }
} }
@ -200,6 +198,10 @@ void TcpTmTcServer::setTcpBacklog(uint8_t tcpBacklog) {
this->tcpBacklog = tcpBacklog; this->tcpBacklog = tcpBacklog;
} }
std::string TcpTmTcServer::getTcpPort() const {
return tcpPort;
}
ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket) { ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket) {
// Access to the FIFO is mutex protected because it is filled by the bridge // Access to the FIFO is mutex protected because it is filled by the bridge
MutexGuard(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs); MutexGuard(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs);

View File

@ -3,13 +3,14 @@
#include "TcpIpBase.h" #include "TcpIpBase.h"
#include "../../platform.h" #include "fsfw/platform.h"
#include "../../ipc/messageQueueDefinitions.h" #include "fsfw/osal/common/tcpipHelpers.h"
#include "../../ipc/MessageQueueIF.h" #include "fsfw/ipc/messageQueueDefinitions.h"
#include "../../objectmanager/frameworkObjects.h" #include "fsfw/ipc/MessageQueueIF.h"
#include "../../objectmanager/SystemObject.h" #include "fsfw/objectmanager/frameworkObjects.h"
#include "../../storagemanager/StorageManagerIF.h" #include "fsfw/objectmanager/SystemObject.h"
#include "../../tasks/ExecutableObjectIF.h" #include "fsfw/storagemanager/StorageManagerIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
#ifdef PLATFORM_UNIX #ifdef PLATFORM_UNIX
#include <sys/socket.h> #include <sys/socket.h>
@ -41,10 +42,9 @@ class TcpTmTcServer:
public TcpIpBase, public TcpIpBase,
public ExecutableObjectIF { public ExecutableObjectIF {
public: public:
/* The ports chosen here should not be used by any other process. */ static const std::string DEFAULT_SERVER_PORT;
static const std::string DEFAULT_TCP_SERVER_PORT;
static constexpr size_t ETHERNET_MTU_SIZE = 1500; static constexpr size_t ETHERNET_MTU_SIZE = 1500;
/** /**
* TCP Server Constructor * TCP Server Constructor
@ -65,6 +65,8 @@ public:
ReturnValue_t performOperation(uint8_t opCode) override; ReturnValue_t performOperation(uint8_t opCode) override;
ReturnValue_t initializeAfterTaskCreation() override; ReturnValue_t initializeAfterTaskCreation() override;
std::string getTcpPort() const;
protected: protected:
StorageManagerIF* tcStore = nullptr; StorageManagerIF* tcStore = nullptr;
StorageManagerIF* tmStore = nullptr; StorageManagerIF* tmStore = nullptr;

View File

@ -17,13 +17,13 @@
#define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0
#endif #endif
const std::string UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT;
UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
std::string udpServerPort, object_id_t tmStoreId, object_id_t tcStoreId): std::string udpServerPort, object_id_t tmStoreId, object_id_t tcStoreId):
TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
if(udpServerPort == "") { if(udpServerPort == "") {
this->udpServerPort = DEFAULT_UDP_SERVER_PORT; this->udpServerPort = DEFAULT_SERVER_PORT;
} }
else { else {
this->udpServerPort = udpServerPort; this->udpServerPort = udpServerPort;
@ -108,6 +108,10 @@ UdpTmTcBridge::~UdpTmTcBridge() {
} }
} }
std::string UdpTmTcBridge::getUdpPort() const {
return udpServerPort;
}
ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) {
int flags = 0; int flags = 0;

View File

@ -2,8 +2,8 @@
#define FSFW_OSAL_COMMON_TMTCUDPBRIDGE_H_ #define FSFW_OSAL_COMMON_TMTCUDPBRIDGE_H_
#include "TcpIpBase.h" #include "TcpIpBase.h"
#include "../../platform.h" #include "fsfw/platform.h"
#include "../../tmtcservices/TmTcBridge.h" #include "fsfw/tmtcservices/TmTcBridge.h"
#ifdef PLATFORM_WIN #ifdef PLATFORM_WIN
#include <ws2tcpip.h> #include <ws2tcpip.h>
@ -28,7 +28,7 @@ class UdpTmTcBridge:
friend class UdpTcPollingTask; friend class UdpTcPollingTask;
public: public:
/* The ports chosen here should not be used by any other process. */ /* The ports chosen here should not be used by any other process. */
static const std::string DEFAULT_UDP_SERVER_PORT; static const std::string DEFAULT_SERVER_PORT;
UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination,
std::string udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE, std::string udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE,
@ -44,6 +44,8 @@ public:
void checkAndSetClientAddress(sockaddr& clientAddress); void checkAndSetClientAddress(sockaddr& clientAddress);
std::string getUdpPort() const;
protected: protected:
virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override;

View File

@ -1,7 +1,7 @@
#ifndef FSFW_OSAL_COMMON_TCPIPCOMMON_H_ #ifndef FSFW_OSAL_COMMON_TCPIPCOMMON_H_
#define FSFW_OSAL_COMMON_TCPIPCOMMON_H_ #define FSFW_OSAL_COMMON_TCPIPCOMMON_H_
#include "../../timemanager/clockDefinitions.h" #include "fsfw/timemanager/clockDefinitions.h"
#include <string> #include <string>
#ifdef _WIN32 #ifdef _WIN32
@ -13,7 +13,7 @@
namespace tcpip { namespace tcpip {
const char* const DEFAULT_SERVER_PORT = "7301"; static constexpr char DEFAULT_SERVER_PORT[] = "7301";
enum class Protocol { enum class Protocol {
UDP, UDP,

View File

@ -11,7 +11,6 @@
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "queue.h" #include "queue.h"
/** /**
* @brief This class manages sending and receiving of * @brief This class manages sending and receiving of
* message queue messages. * message queue messages.

View File

@ -16,6 +16,7 @@ target_sources(${LIB_FSFW_NAME}
Timer.cpp Timer.cpp
tcpipHelpers.cpp tcpipHelpers.cpp
unixUtility.cpp unixUtility.cpp
CommandExecutor.cpp
) )
find_package(Threads REQUIRED) find_package(Threads REQUIRED)

View File

@ -0,0 +1,185 @@
#include "CommandExecutor.h"
#include "fsfw/serviceinterface.h"
#include "fsfw/container/SimpleRingBuffer.h"
#include "fsfw/container/DynamicFIFO.h"
#include <unistd.h>
#include <cstring>
CommandExecutor::CommandExecutor(const size_t maxSize):
readVec(maxSize) {
waiter.events = POLLIN;
}
ReturnValue_t CommandExecutor::load(std::string command, bool blocking, bool printOutput) {
if(state == States::PENDING) {
return COMMAND_PENDING;
}
currentCmd = command;
this->blocking = blocking;
this->printOutput = printOutput;
if(state == States::IDLE) {
state = States::COMMAND_LOADED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t CommandExecutor::execute() {
if(state == States::IDLE) {
return NO_COMMAND_LOADED_OR_PENDING;
}
else if(state == States::PENDING) {
return COMMAND_PENDING;
}
currentCmdFile = popen(currentCmd.c_str(), "r");
if(currentCmdFile == nullptr) {
lastError = errno;
return HasReturnvaluesIF::RETURN_FAILED;
}
if(blocking) {
return executeBlocking();
}
else {
currentFd = fileno(currentCmdFile);
waiter.fd = currentFd;
}
state = States::PENDING;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t CommandExecutor::close() {
if(state == States::PENDING) {
// Attempt to close process, irrespective of if it is running or not
if(currentCmdFile != nullptr) {
pclose(currentCmdFile);
}
}
return HasReturnvaluesIF::RETURN_OK;
}
void CommandExecutor::printLastError(std::string funcName) const {
if(lastError != 0) {
sif::error << funcName << " pclose failed with code " <<
lastError << ": " << strerror(lastError) << std::endl;
}
}
void CommandExecutor::setRingBuffer(SimpleRingBuffer *ringBuffer,
DynamicFIFO<uint16_t>* sizesFifo) {
this->ringBuffer = ringBuffer;
this->sizesFifo = sizesFifo;
}
ReturnValue_t CommandExecutor::check(bool& bytesRead) {
if(blocking) {
return HasReturnvaluesIF::RETURN_OK;
}
switch(state) {
case(States::IDLE):
case(States::COMMAND_LOADED): {
return NO_COMMAND_LOADED_OR_PENDING;
}
case(States::PENDING): {
break;
}
}
int result = poll(&waiter, 1, 0);
switch(result) {
case(0): {
return HasReturnvaluesIF::RETURN_OK;
break;
}
case(1): {
if (waiter.revents & POLLIN) {
ssize_t readBytes = read(currentFd, readVec.data(), readVec.size());
if(readBytes == 0) {
// Should not happen
sif::warning << "CommandExecutor::check: "
"No bytes read after poll event.." << std::endl;
break;
}
else if(readBytes > 0) {
bytesRead = true;
if(printOutput) {
// It is assumed the command output is line terminated
sif::info << currentCmd << " | " << readVec.data();
}
if(ringBuffer != nullptr) {
ringBuffer->writeData(reinterpret_cast<const uint8_t*>(
readVec.data()), readBytes);
}
if(sizesFifo != nullptr) {
if(not sizesFifo->full()) {
sizesFifo->insert(readBytes);
}
}
return BYTES_READ;
}
else {
// Should also not happen
sif::warning << "CommandExecutor::check: Error " << errno << ": " <<
strerror(errno) << std::endl;
}
}
else if(waiter.revents & POLLERR) {
sif::warning << "CommandExecuter::check: Poll error" << std::endl;
return COMMAND_ERROR;
}
else if(waiter.revents & POLLHUP) {
int result = pclose(currentCmdFile);
if(result != 0) {
lastError = result;
return HasReturnvaluesIF::RETURN_FAILED;
}
state = States::IDLE;
currentCmdFile = nullptr;
currentFd = 0;
return EXECUTION_FINISHED;
}
break;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
void CommandExecutor::reset() {
CommandExecutor::close();
currentCmdFile = nullptr;
currentFd = 0;
state = States::IDLE;
}
int CommandExecutor::getLastError() const {
return this->lastError;
}
CommandExecutor::States CommandExecutor::getCurrentState() const {
return state;
}
ReturnValue_t CommandExecutor::executeBlocking() {
while(fgets(readVec.data(), readVec.size(), currentCmdFile) != nullptr) {
std::string output(readVec.data());
if(printOutput) {
sif::info << currentCmd << " | " << output;
}
if(ringBuffer != nullptr) {
ringBuffer->writeData(reinterpret_cast<const uint8_t*>(output.data()), output.size());
}
if(sizesFifo != nullptr) {
if(not sizesFifo->full()) {
sizesFifo->insert(output.size());
}
}
}
int result = pclose(currentCmdFile);
if(result != 0) {
lastError = result;
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,134 @@
#ifndef FSFW_SRC_FSFW_OSAL_LINUX_COMMANDEXECUTOR_H_
#define FSFW_SRC_FSFW_OSAL_LINUX_COMMANDEXECUTOR_H_
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
#include "fsfw/returnvalues/FwClassIds.h"
#include <poll.h>
#include <string>
#include <vector>
class SimpleRingBuffer;
template <typename T> class DynamicFIFO;
/**
* @brief Helper class to execute shell commands in blocking and non-blocking mode
* @details
* This class is able to execute processes by using the Linux popen call. It also has the
* capability of writing the read output of a process into a provided ring buffer.
*
* The executor works by first loading the command which should be executed and specifying
* whether it should be executed blocking or non-blocking. After that, execution can be started
* with the execute command. In blocking mode, the execute command will block until the command
* has finished
*/
class CommandExecutor {
public:
enum class States {
IDLE,
COMMAND_LOADED,
PENDING
};
static constexpr uint8_t CLASS_ID = CLASS_ID::LINUX_OSAL;
//! [EXPORT] : [COMMENT] Execution of the current command has finished
static constexpr ReturnValue_t EXECUTION_FINISHED =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 0);
//! [EXPORT] : [COMMENT] Command is pending. This will also be returned if the user tries
//! to load another command but a command is still pending
static constexpr ReturnValue_t COMMAND_PENDING =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 1);
//! [EXPORT] : [COMMENT] Some bytes have been read from the executing process
static constexpr ReturnValue_t BYTES_READ =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 2);
//! [EXPORT] : [COMMENT] Command execution failed
static constexpr ReturnValue_t COMMAND_ERROR =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 3);
//! [EXPORT] : [COMMENT]
static constexpr ReturnValue_t NO_COMMAND_LOADED_OR_PENDING =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 4);
static constexpr ReturnValue_t PCLOSE_CALL_ERROR =
HasReturnvaluesIF::makeReturnCode(CLASS_ID, 6);
/**
* Constructor. Is initialized with maximum size of internal buffer to read data from the
* executed process.
* @param maxSize
*/
CommandExecutor(const size_t maxSize);
/**
* Load a new command which should be executed
* @param command
* @param blocking
* @param printOutput
* @return
*/
ReturnValue_t load(std::string command, bool blocking, bool printOutput = true);
/**
* Execute the loaded command.
* @return
* - In blocking mode, it will return RETURN_FAILED if
* the result of the system call was not 0. The error value can be accessed using
* getLastError
* - In non-blocking mode, this call will start
* the execution and then return RETURN_OK
*/
ReturnValue_t execute();
/**
* Only used in non-blocking mode. Checks the currently running command.
* @param bytesRead Will be set to the number of bytes read, if bytes have been read
* @return
* - BYTES_READ if bytes have been read from the executing process. It is recommended to call
* check again after this
* - RETURN_OK execution is pending, but no bytes have been read from the executing process
* - RETURN_FAILED if execution has failed, error value can be accessed using getLastError
* - EXECUTION_FINISHED if the process was executed successfully
* - COMMAND_ERROR internal poll error
*/
ReturnValue_t check(bool& bytesRead);
/**
* Abort the current command. Should normally not be necessary, check can be used to find
* out whether command execution was successful
* @return RETURN_OK
*/
ReturnValue_t close();
States getCurrentState() const;
int getLastError() const;
void printLastError(std::string funcName) const;
/**
* Assign a ring buffer and a FIFO which will be filled by the executor with the output
* read from the started process
* @param ringBuffer
* @param sizesFifo
*/
void setRingBuffer(SimpleRingBuffer* ringBuffer, DynamicFIFO<uint16_t>* sizesFifo);
/**
* Reset the executor. This calls close internally and then reset the state machine so new
* commands can be loaded and executed
*/
void reset();
private:
std::string currentCmd;
bool blocking = true;
FILE* currentCmdFile = nullptr;
int currentFd = 0;
bool printOutput = true;
std::vector<char> readVec;
struct pollfd waiter {};
SimpleRingBuffer* ringBuffer = nullptr;
DynamicFIFO<uint16_t>* sizesFifo = nullptr;
States state = States::IDLE;
int lastError = 0;
ReturnValue_t executeBlocking();
};
#endif /* FSFW_SRC_FSFW_OSAL_LINUX_COMMANDEXECUTOR_H_ */

View File

@ -27,6 +27,7 @@ int Timer::setTimer(uint32_t intervalMs) {
timer.it_value.tv_nsec = (intervalMs * 1000000) % (1000000000); timer.it_value.tv_nsec = (intervalMs * 1000000) % (1000000000);
timer.it_interval.tv_sec = 0; timer.it_interval.tv_sec = 0;
timer.it_interval.tv_nsec = 0; timer.it_interval.tv_nsec = 0;
set = true;
return timer_settime(timerId, 0, &timer, NULL); return timer_settime(timerId, 0, &timer, NULL);
} }
@ -43,3 +44,14 @@ int Timer::getTimer(uint32_t* remainingTimeMs){
return status; return status;
} }
bool Timer::isSet() const {
return this->set;
}
void Timer::resetTimer() {
if(not this->set) {
set = false;
}
setTimer(0);
}

View File

@ -38,7 +38,11 @@ public:
*/ */
int getTimer(uint32_t* remainingTimeMs); int getTimer(uint32_t* remainingTimeMs);
bool isSet() const;
void resetTimer();
private: private:
bool set = true;
timer_t timerId; timer_t timerId;
}; };

View File

@ -14,7 +14,7 @@ void utility::printUnixErrorGeneric(const char* const className,
#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_VERBOSE_LEVEL >= 1
if(outputType == sif::OutputTypes::OUT_ERROR) { if(outputType == sif::OutputTypes::OUT_ERROR) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << className << "::" << function << ":" << failString << " error: " sif::error << className << "::" << function << ": " << failString << " error: "
<< strerror(errno) << std::endl; << strerror(errno) << std::endl;
#else #else
sif::printError("%s::%s: %s error: %s\n", className, function, failString, strerror(errno)); sif::printError("%s::%s: %s error: %s\n", className, function, failString, strerror(errno));
@ -22,7 +22,7 @@ void utility::printUnixErrorGeneric(const char* const className,
} }
else { else {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << className << "::" << function << ":" << failString << " error: " sif::warning << className << "::" << function << ": " << failString << " error: "
<< strerror(errno) << std::endl; << strerror(errno) << std::endl;
#else #else
sif::printWarning("%s::%s: %s error: %s\n", className, function, failString, strerror(errno)); sif::printWarning("%s::%s: %s error: %s\n", className, function, failString, strerror(errno));

View File

@ -33,8 +33,8 @@ ReturnValue_t Service8FunctionManagement::getMessageQueueAndObject(
if(tcDataLen < sizeof(object_id_t)) { if(tcDataLen < sizeof(object_id_t)) {
return CommandingServiceBase::INVALID_TC; return CommandingServiceBase::INVALID_TC;
} }
SerializeAdapter::deSerialize(objectId, &tcData, // Can't fail, size was checked before
&tcDataLen, SerializeIF::Endianness::BIG); SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::BIG);
return checkInterfaceAndAcquireMessageQueue(id,objectId); return checkInterfaceAndAcquireMessageQueue(id,objectId);
} }

Some files were not shown because too many files have changed in this diff Show More