Compare commits

..

60 Commits

Author SHA1 Message Date
a274d6598e Merge pull request 'Release v4.0.0' (#554) from development into master
Reviewed-on: fsfw/fsfw#554
2022-02-14 16:49:15 +01:00
c3d78120ea preparing 4.0.0 2022-02-14 16:42:40 +01:00
f24de22e9b Merge pull request 'Some DHB docs' (#551) from eive/fsfw:mueller/dhb-docs into development
Reviewed-on: fsfw/fsfw#551
2022-02-14 16:35:10 +01:00
918783774f Merge branch 'development' into mueller/dhb-docs 2022-02-14 16:34:47 +01:00
6744a55b9b docs update 2022-02-14 16:31:13 +01:00
a612fb446c added two links 2022-02-14 16:23:21 +01:00
a5adeb333c Merge pull request 'Fixed valgrind python script' (#553) from gaisser/fsfw:gaisser_build_script into development
Reviewed-on: fsfw/fsfw#553
2022-02-14 15:27:04 +01:00
7788cada54 Merge branch 'development' into gaisser_build_script 2022-02-14 15:26:06 +01:00
074ef29b86 Fixed valgrind python script 2022-02-14 15:19:47 +01:00
d4f059d639 Merge pull request 'increase test limit' (#552) from eive/fsfw:mueller/increase-test-limit into development
Reviewed-on: fsfw/fsfw#552
2022-02-14 15:18:17 +01:00
22bc300902 increase other limits 2022-02-14 16:14:14 +01:00
0d38ac62d8 this should work an ALL systems 2022-02-14 16:12:48 +01:00
d81257a91c Merge branch 'mueller/increase-test-limit' of https://egit.irs.uni-stuttgart.de/eive/fsfw into mueller/increase-test-limit 2022-02-14 16:01:02 +01:00
d53c7e1190 increase test limit 2022-02-14 16:00:43 +01:00
e312cd094a Merge branch 'development' into mueller/increase-test-limit 2022-02-14 14:55:19 +01:00
9e958e752e applied clang format 2022-02-14 14:54:20 +01:00
3bcd71598d Merge branch 'development' into mueller/increase-test-limit 2022-02-14 14:51:35 +01:00
2602d4fed1 Merge branch 'development' into mueller/dhb-docs 2022-02-14 14:51:16 +01:00
805538ec6e Merge pull request 'meier/uioMapper' (#543) from meier/uioMapper into development
Reviewed-on: fsfw/fsfw#543
2022-02-14 14:50:52 +01:00
Jakob Meier
120750f22a removed one fclose 2022-02-14 08:51:53 +01:00
Jakob Meier
9897f51307 added flose and changed warning message to error message 2022-02-14 08:43:10 +01:00
4f87e24f60 increase test limit 2022-02-10 14:08:52 +01:00
2dcf896cca this sounds better 2022-02-10 14:04:23 +01:00
cdf2a90f90 fixed up cross-ref 2022-02-10 14:02:30 +01:00
b25555a533 started DHB docs 2022-02-10 13:53:59 +01:00
bc0100ee08 Merge pull request 'Update CHANGELOG' (#539) from mueller/update-changelog into development
Reviewed-on: fsfw/fsfw#539
2022-02-07 17:13:41 +01:00
c6d152a01d updated changelog 2022-02-07 17:11:04 +01:00
f4f1174849 Merge branch 'development' into mueller/update-changelog 2022-02-07 17:06:16 +01:00
9df8722c10 Merge pull request 'Switching to a static docker image' (#549) from mohr/static_docker into development
Reviewed-on: fsfw/fsfw#549
2022-02-07 17:02:00 +01:00
7208139630 Jenkinsfile another typo 2022-02-07 16:50:59 +01:00
54f3d7bd2d Jenkinsfile typo 2022-02-07 16:49:42 +01:00
7a83289b3d using prebuild, static docker image 2022-02-07 16:48:41 +01:00
136524424f Merge pull request 'Fix for Catch2 build regression' (#548) from mohr/catch2workaround into development
Reviewed-on: fsfw/fsfw#548
2022-02-07 16:45:47 +01:00
793b97f651 Merge branch 'development' into mohr/catch2workaround 2022-02-07 16:40:13 +01:00
2e4cd80556 workaround for build regression catch2-v3.0.0-preview4 2022-02-07 15:51:06 +01:00
a4f57a38fa Merge branch 'mueller/update-changelog' of egit.irs.uni-stuttgart.de:fsfw/fsfw into mueller/update-changelog 2022-02-07 15:42:00 +01:00
6dc34fc1f0 removed cmake warning as I have a workaround 2022-02-07 15:41:10 +01:00
9e6948a8d7 Merge pull request 'virtual function to print datasets' (#544) from meier/printDataSet into development
Reviewed-on: fsfw/fsfw#544
2022-02-07 14:42:17 +01:00
9b17b282c6 Merge pull request 'do send read hook' (#545) from meier/doSendReadHook into development
Reviewed-on: fsfw/fsfw#545
2022-02-07 14:42:05 +01:00
5f48d77c64 Merge branch 'development' into meier/printDataSet 2022-02-07 14:17:26 +01:00
8ab8c57f9c Merge branch 'development' into meier/doSendReadHook 2022-02-07 14:17:03 +01:00
c7b9df5e40 Merge branch 'development' into mueller/update-changelog 2022-02-07 14:16:52 +01:00
7b8019c621 Merge branch 'development' into meier/uioMapper 2022-02-07 14:09:13 +01:00
baddbf7340 Updated changelog for v4.0.0 2022-02-07 13:44:25 +01:00
80a610141a added v3.0.1 to changelog 2022-02-04 13:45:09 +01:00
f93c173715 Merge pull request 'Update development to master v3.0.1' (#546) from master into development
Reviewed-on: fsfw/fsfw#546
2022-02-04 13:29:59 +01:00
620841a9e5 Merge pull request 'bump version' (#542) from mueller/bump-version into master
Reviewed-on: fsfw/fsfw#542
2022-02-04 13:23:24 +01:00
bd29688307 bump revision 2022-02-04 13:11:27 +01:00
43b7a314b6 bump version 2022-02-04 13:11:27 +01:00
1b41153ee6 add uio subdirectory 2022-02-04 10:16:37 +01:00
Jakob Meier
f08d291e3e fix to remove compiler warning 2022-02-03 11:07:51 +01:00
Jakob Meier
06ffe27fcc do send read hook 2022-02-03 10:46:14 +01:00
Jakob Meier
e9b0951a95 virtual function to print datasets 2022-02-03 10:37:07 +01:00
Jakob Meier
348274c145 merged develop 2022-02-03 10:31:15 +01:00
Jakob Meier
40329a33b2 prepared for proper pr 2022-02-03 10:19:33 +01:00
Jakob Meier
2d52042ed6 add uio subdir 2022-02-03 10:16:06 +01:00
Jakob Meier
79936a3335 uio mapper 2022-02-03 10:14:47 +01:00
51add8a8ad Merge remote-tracking branch 'origin/development' into mueller/update-changelog 2022-02-02 10:40:25 +01:00
ad5bb4c694 update changelog.md 2022-02-02 10:40:00 +01:00
2a268e14d1 Merge pull request 'Release v3.0.0' (#532) from development into master
Reviewed-on: fsfw/fsfw#532
2022-01-10 14:52:31 +01:00
48 changed files with 700 additions and 304 deletions

View File

@@ -1,4 +1,214 @@
# Changed from ASTP 1.1.0 to 1.2.0 Change Log
=======
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
# [v4.0.0]
## Additions
- CFDP Packet Stack and related tests added. It also refactors the existing TMTC infastructure to
allow sending of CFDP packets to the CCSDS handlers.
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/528
- added virtual function to print datasets
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/544
- doSendRead Hook
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/545
- Dockumentation for DHB
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/551
### HAL additions
- Linux Command Executor, which can execute shell commands in blocking and non-blocking mode
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/536
- uio Mapper
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/543
## Changes
- Applied the `clang-format` auto-formatter to all source code
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/534
- Updated Catch2 to v3.0.0-preview4
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/538
- Changed CI to use prebuilt docker image
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/549
## Bugfix
- CMake fixes in PR https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/533 , was problematic
if the uppermost user `CMakeLists.txt` did not have the include paths set up properly, which
could lead to compile errors that `#include "fsfw/FSFW.h"` was not found.
- Fix for build regression in Catch2 v3.0.0-preview4
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/548
- Fix in unittest which failed on CI
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/552
- Fix in helper script
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/553
## API Changes
- Aforementioned changes to existing TMTC stack
## Known bugs
-
# [v3.0.1]
## API Changes
*
## Bugfixes
* Version number was not updated for v3.0.0 #542
## Enhancement
*
## Known bugs
*
# [v3.0.0]
## API Changes
#### TCP Socket Changes
* Keep Open TCP Implementation #496
* The socket will now kept open after disconnect. This allows reconnecting.
* Only one connection is allowed
* No internal influence but clients need to change their Code.
### GPIO IF
* Add feature to open GPIO by line name #506
### Bitutil
* Unittests for Op Divider and Bitutility #510
### Filesystem IF changed
* Filesystem Base Interface: Use IF instead of void pointer #511
### STM32
* STM32 SPI Updates #518
## Bugfixes
* Small bugfix for LIS3 handler #504
* Spelling fixed for function names #509
* CMakeLists fixes #517
* Out of bound reads and writes in unittests #519
* Bug in TmPacketStoredPusC (#478)
* Windows ifdef fixed #529
## Enhancement
* FSFW.h.in more default values #491
* Minor updates for PUS services #498
* HasReturnvaluesIF naming for parameter #499
* Tests can now be built as part of FSFW and versioning moved to CMake #500
* Added integration test code #508
* More printouts for rejected TC packets #505
* Arrayprinter format improvements #514
* Adding code for CI with docker and jenkins #520
* Added new function in SerializeAdapter #513
* Enables simple deSerialize if you keep track of the buffer position yourself
* `` static ReturnValue_t deSerialize(T *object, const uint8_t* buffer,
size_t* deserSize, SerializeIF::Endianness streamEndianness) ``
* Unittest helper scripts has a new Parameter to open the coverage html in the webrowser #525
* ``'-o', '--open', Open coverage data in webbrowser``
* Documentation updated. Sphinx Documentation can now be build with python script #526
## Known bugs
* Version number was not updated for v3.0.0 #542
All Pull Requests:
Milestone: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/milestone/19
# [v2.0.0]
## API Changes
### File Structure changed to fit more common structure
* See pull request (#445)
* HAL is now part of the main project
* **See Instructions below:**
#### Instruction how to update existing / user code
* Changes in `#include`:
* Rename `internalError` in includes to `internalerror`
* Rename `fsfw/hal` to `fsfw_hal`
* Rename `fsfw/tests` to `fsfw_tests`
* Rename `osal/FreeRTOS` to `osal/freertos`
* Changes in `CMakeLists.txt`:
* Rename `OS_FSFW` to `FSFW_OSAL`
* Changes in `DleEncoder.cpp`
* Create an instance of the `DleEncoder` first before calling the `encode` and `decode` functions
### Removed osal/linux/Timer (#486)
* Was redundant to timemanager/Countdown
#### Instruction how to update existing / user code
* Use timemanager/Countdown instead
## Bugfixes
### TM Stack
* Increased TM stack robustness by introducing `nullptr` checks and more printouts (#483)
#### Host OSAL / FreeRTOS
* QueueMapManager Bugfix (NO_QUEUE was used as MessageQueueId) (#444)
#### Events
* Event output is now consistent (#447)
#### DLE Encoder
* Fixed possible out of bounds access in DLE Encoder (#492)
## Enhancment
* HAL as major new feature, also includes three MEMS devicehandlers as part of #481
* Linux HAL updates (#456)
* FreeRTOS Header cleaning update and Cmake tweaks (#442)
* Printer updates (#453)
* New returnvalue for for empty PST (#485)
* TMTC Bridge: Increase limit of packets stored (#484)
## Known bugs
* Bug in TmPacketStoredPusC (#478)
All Pull Requests:
Milestone: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/milestone/5
# [v1.2.0]
## API Changes ## API Changes
@@ -27,7 +237,7 @@
- See API changes chapter. This change will keep the internal API consistent in the future - See API changes chapter. This change will keep the internal API consistent in the future
# Changes from ASTP 1.0.0 to 1.1.0 # [v1.1.0]
## API Changes ## API Changes

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(FSFW_VERSION 2) set(FSFW_VERSION 4)
set(FSFW_SUBVERSION 0) set(FSFW_SUBVERSION 0)
set(FSFW_REVISION 0) set(FSFW_REVISION 0)
@@ -60,6 +60,8 @@ if(FSFW_BUILD_UNITTESTS)
) )
FetchContent_MakeAvailable(Catch2) FetchContent_MakeAvailable(Catch2)
#fixes regression -preview4, to be confirmed in later releases
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
endif() endif()
set(FSFW_CONFIG_PATH tests/src/fsfw_tests/unit/testcfg) set(FSFW_CONFIG_PATH tests/src/fsfw_tests/unit/testcfg)

View File

@@ -107,6 +107,42 @@ cmake --build . -- fsfw-tests_coverage -j
The `coverage.py` script located in the `script` folder can also be used to do this conveniently. The `coverage.py` script located in the `script` folder can also be used to do this conveniently.
## Building the documentations
The FSFW documentation is built using the tools Sphinx, doxygen and breathe based on the
instructions provided in [this blogpost](https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/). If you
want to do this locally, set up the prerequisites first. This requires a ``python3``
installation as well. Example here is for Ubuntu.
```sh
sudo apt-get install doxygen graphviz
```
And the following Python packages
```sh
python3 -m pip install sphinx breathe
```
You can set up a documentation build system using the following commands
```sh
mkdir build-docs && cd build-docs
cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..
```
Then you can generate the documentation using
```sh
cmake --build . -j
```
You can find the generated documentation inside the `docs/sphinx` folder inside the build
folder. Simply open the `index.html` in the webbrowser of your choice.
The `helper.py` script located in the script` folder can also be used to create, build
and open the documentation conveniently. Try `helper.py -h for more information.
## Formatting the sources ## Formatting the sources
The formatting is done by the `clang-format` tool. The configuration is contained within the The formatting is done by the `clang-format` tool. The configuration is contained within the

View File

@@ -6,9 +6,3 @@ RUN apt-get --yes upgrade
#tzdata is a dependency, won't install otherwise #tzdata is a dependency, won't install otherwise
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping RUN apt-get --yes install gcc g++ cmake make lcov git valgrind nano iputils-ping
RUN git clone https://github.com/catchorg/Catch2.git && \
cd Catch2 && \
git checkout v3.0.0-preview4 && \
cmake -Bbuild -H. -DBUILD_TESTING=OFF && \
cmake --build build/ --target install

View File

@@ -3,13 +3,7 @@ pipeline {
BUILDDIR = 'build-tests' BUILDDIR = 'build-tests'
} }
agent { agent {
dockerfile { docker { image 'fsfw-ci:d1'}
dir 'automation'
//force docker to redownload base image and rebuild all steps instead of caching them
//this way, we always get an up to date docker image one each build
additionalBuildArgs '--no-cache --pull'
reuseNode true
}
} }
stages { stages {
stage('Clean') { stage('Clean') {

View File

@@ -1,3 +1,110 @@
.. _dhb-prim-doc:
Device Handlers Device Handlers
================== ==================
Device handler components represent, control and monitor equipment, for example sensors or actuators
of a spacecraft or the payload.
Most device handlers have the same common functionality or
requirements, which are fulfilled by implementing certain interfaces:
- The handler/device needs to be commandable: :cpp:class:`HasActionsIF`
- The handler needs to communicate with the physical device via a dedicated
communication bus, for example SpaceWire, UART or SPI: :cpp:class:`DeviceCommunicationIF`
- The handler has housekeeping data which has to be exposed to the operator and/or other software
components: :cpp:class:`HasLocalDataPoolIF`
- The handler has configurable parameters: :cpp:class:`ReceivesParameterMessagesIF` which
also implements :cpp:class:`HasParametersIF`
- The handler has health states, for example to indicate a broken device:
:cpp:class:`HasHealthIF`
- The handler has modes. For example there are the core modes `MODE_ON`, `MODE_OFF`
and `MODE_NORMAL` provided by the FSFW. `MODE_ON` means that a device is physically powered
but that it is not periodically polling data from the
physical device, `MODE_NORMAL` means that it is able to do that: :cpp:class:`HasModesIF`
The device handler base therefore provides abstractions for a lot of common
functionality, which can potentially avoid high amounts or logic and code duplication.
Template Device Handler Base File
----------------------------------
This is an example template device handler header file with all necessary
functions implemented:
.. code-block:: cpp
#ifndef __TESTDEVICEHANDLER_H_
#define __TESTDEVICEHANDLER_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
class TestDeviceHandler: DeviceHandlerBase {
public:
TestDeviceHandler(object_id_t objectId, object_id_t comIF, CookieIF* cookie);
private:
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
void fillCommandAndReplyMap() override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
size_t commandDataLen) override;
ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId,
size_t* foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
};
#endif /* __TESTDEVICEHANDLER_H_ */
and the respective source file with sensible default return values:
.. code-block:: cpp
#include "TestDeviceHandler.h"
TestDeviceHandler::TestDeviceHandler(object_id_t objectId, object_id_t comIF, CookieIF* cookie)
: DeviceHandlerBase(objectId, comIF, cookie) {}
void TestDeviceHandler::doStartUp() {}
void TestDeviceHandler::doShutDown() {}
ReturnValue_t TestDeviceHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TestDeviceHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
return HasReturnvaluesIF::RETURN_OK;
}
void TestDeviceHandler::fillCommandAndReplyMap() {}
ReturnValue_t TestDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData,
size_t commandDataLen) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TestDeviceHandler::scanForReply(const uint8_t* start, size_t remainingSize,
DeviceCommandId_t* foundId, size_t* foundLen) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TestDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
const uint8_t* packet) {
return HasReturnvaluesIF::RETURN_OK;
}
uint32_t TestDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) {
return 10000;
}
ReturnValue_t TestDeviceHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
return HasReturnvaluesIF::RETURN_OK;
}

View File

@@ -90,8 +90,21 @@ Building the documentation
---------------------------- ----------------------------
The FSFW documentation is built using the tools Sphinx, doxygen and breathe based on the The FSFW documentation is built using the tools Sphinx, doxygen and breathe based on the
instructions provided in `this blogpost <https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/>`_. You can set up a instructions provided in `this blogpost <https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/>`_. If you
documentation build system using the following commands want to do this locally, set up the prerequisites first. This requires a ``python3``
installation as well. Example here is for Ubuntu.
.. code-block:: console
sudo apt-get install doxygen graphviz
And the following Python packages
.. code-block:: console
python3 -m pip install sphinx breathe
You can set up a documentation build system using the following commands
.. code-block:: bash .. code-block:: bash
@@ -110,6 +123,14 @@ folder. Simply open the ``index.html`` in the webbrowser of your choice.
The ``helper.py`` script located in the ``script`` folder can also be used to create, build The ``helper.py`` script located in the ``script`` folder can also be used to create, build
and open the documentation conveniently. Try ``helper.py -h`` for more information. and open the documentation conveniently. Try ``helper.py -h`` for more information.
Formatting the source
-----------------------
The formatting is done by the ``clang-format`` tool. The configuration is contained within the
``.clang-format`` file in the repository root. As long as ``clang-format`` is installed, you
can run the ``apply-clang-format.sh`` helper script to format all source files consistently.
.. _`Hosted FSFW example`: https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-hosted .. _`Hosted FSFW example`: https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-hosted
.. _`Catch2 library`: https://github.com/catchorg/Catch2 .. _`Catch2 library`: https://github.com/catchorg/Catch2
.. _`Code coverage`: https://github.com/bilke/cmake-modules/tree/master .. _`Code coverage`: https://github.com/bilke/cmake-modules/tree/master

View File

@@ -118,7 +118,7 @@ The DH has mechanisms to monitor the communication with the physical device whic
for FDIR reaction. Device Handlers can be created by implementing ``DeviceHandlerBase``. for FDIR reaction. Device Handlers can be created by implementing ``DeviceHandlerBase``.
A standard FDIR component for the DH will be created automatically but can A standard FDIR component for the DH will be created automatically but can
be overwritten by the user. More information on DeviceHandlers can be found in the be overwritten by the user. More information on DeviceHandlers can be found in the
related [documentation section](doc/README-devicehandlers.md#top). related :ref:`documentation section <dhb-prim-doc>`.
Modes and Health Modes and Health
-------------------- --------------------

View File

@@ -9,7 +9,6 @@ option(FSFW_HAL_ADD_LINUX "Add the Linux HAL to the sources. Requires gpiod libr
# Linux. The only exception from this is the gpiod library which requires a dedicated installation, # Linux. The only exception from this is the gpiod library which requires a dedicated installation,
# but CMake is able to determine whether this library is installed with find_library. # but CMake is able to determine whether this library is installed with find_library.
option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add peripheral drivers for embedded Linux" ON) option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add peripheral drivers for embedded Linux" ON)
option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Target implements libgpiod" ON)
option(FSFW_HAL_ADD_RASPBERRY_PI "Add Raspberry Pi specific code to the sources" OFF) option(FSFW_HAL_ADD_RASPBERRY_PI "Add Raspberry Pi specific code to the sources" OFF)
option(FSFW_HAL_ADD_STM32H7 "Add the STM32H7 HAL to the sources" OFF) option(FSFW_HAL_ADD_STM32H7 "Add the STM32H7 HAL to the sources" OFF)

View File

@@ -11,7 +11,7 @@ namespace gpio {
enum Levels : uint8_t { LOW = 0, HIGH = 1, NONE = 99 }; enum Levels : uint8_t { LOW = 0, HIGH = 1, NONE = 99 };
enum Direction : uint8_t { DIR_IN = 0, DIR_OUT = 1 }; enum Direction : uint8_t { IN = 0, OUT = 1 };
enum GpioOperation { READ, WRITE }; enum GpioOperation { READ, WRITE };
@@ -20,7 +20,7 @@ enum class GpioTypes {
GPIO_REGULAR_BY_CHIP, GPIO_REGULAR_BY_CHIP,
GPIO_REGULAR_BY_LABEL, GPIO_REGULAR_BY_LABEL,
GPIO_REGULAR_BY_LINE_NAME, GPIO_REGULAR_BY_LINE_NAME,
TYPE_CALLBACK CALLBACK
}; };
static constexpr gpioId_t NO_GPIO = -1; static constexpr gpioId_t NO_GPIO = -1;
@@ -57,7 +57,7 @@ class GpioBase {
// Can be used to cast GpioBase to a concrete child implementation // Can be used to cast GpioBase to a concrete child implementation
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE; gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
std::string consumer; std::string consumer;
gpio::Direction direction = gpio::Direction::DIR_IN; gpio::Direction direction = gpio::Direction::IN;
gpio::Levels initValue = gpio::Levels::NONE; gpio::Levels initValue = gpio::Levels::NONE;
}; };
@@ -79,8 +79,8 @@ class GpiodRegularBase : public GpioBase {
class GpiodRegularByChip : public GpiodRegularBase { class GpiodRegularByChip : public GpiodRegularBase {
public: public:
GpiodRegularByChip() GpiodRegularByChip()
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, std::string(), : GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, std::string(), gpio::Direction::IN,
gpio::Direction::DIR_IN, gpio::LOW, 0) {} gpio::LOW, 0) {}
GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_, GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_,
gpio::Direction direction_, gpio::Levels initValue_) gpio::Direction direction_, gpio::Levels initValue_)
@@ -89,7 +89,7 @@ class GpiodRegularByChip : public GpiodRegularBase {
chipname(chipname_) {} chipname(chipname_) {}
GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_) GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_)
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, consumer_, gpio::Direction::DIR_IN, : GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, consumer_, gpio::Direction::IN,
gpio::LOW, lineNum_), gpio::LOW, lineNum_),
chipname(chipname_) {} chipname(chipname_) {}
@@ -105,7 +105,7 @@ class GpiodRegularByLabel : public GpiodRegularBase {
label(label_) {} label(label_) {}
GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_) GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_)
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_, gpio::Direction::DIR_IN, : GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_, gpio::Direction::IN,
gpio::LOW, lineNum_), gpio::LOW, lineNum_),
label(label_) {} label(label_) {}
@@ -126,8 +126,8 @@ class GpiodRegularByLineName : public GpiodRegularBase {
lineName(lineName_) {} lineName(lineName_) {}
GpiodRegularByLineName(std::string lineName_, std::string consumer_) GpiodRegularByLineName(std::string lineName_, std::string consumer_)
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, : GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, gpio::Direction::IN,
gpio::Direction::DIR_IN, gpio::LOW), gpio::LOW),
lineName(lineName_) {} lineName(lineName_) {}
std::string lineName; std::string lineName;
@@ -137,7 +137,7 @@ class GpioCallback : public GpioBase {
public: public:
GpioCallback(std::string consumer, gpio::Direction direction_, gpio::Levels initValue_, GpioCallback(std::string consumer, gpio::Direction direction_, gpio::Levels initValue_,
gpio::gpio_cb_t callback, void* callbackArgs) gpio::gpio_cb_t callback, void* callbackArgs)
: GpioBase(gpio::GpioTypes::TYPE_CALLBACK, consumer, direction_, initValue_), : GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_),
callback(callback), callback(callback),
callbackArgs(callbackArgs) {} callbackArgs(callbackArgs) {}

View File

@@ -10,7 +10,7 @@ GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceC
transitionDelayMs(transitionDelayMs), transitionDelayMs(transitionDelayMs),
dataset(this) { dataset(this) {
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1 #if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
debugDivider = new PeriodicOperationDivider(10); debugDivider = new PeriodicOperationDivider(3);
#endif #endif
} }

View File

@@ -13,7 +13,7 @@ MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCom
dataset(this), dataset(this),
transitionDelay(transitionDelay) { transitionDelay(transitionDelay) {
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1 #if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
debugDivider = new PeriodicOperationDivider(10); debugDivider = new PeriodicOperationDivider(3);
#endif #endif
// Set to default values right away // Set to default values right away
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT; registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
@@ -264,7 +264,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
int16_t mgmMeasurementRawZ = int16_t mgmMeasurementRawZ =
packet[MGMLIS3MDL::Z_HIGHBYTE_IDX] << 8 | packet[MGMLIS3MDL::Z_LOWBYTE_IDX]; packet[MGMLIS3MDL::Z_HIGHBYTE_IDX] << 8 | packet[MGMLIS3MDL::Z_LOWBYTE_IDX];
// Target value in microtesla /* Target value in microtesla */
float mgmX = static_cast<float>(mgmMeasurementRawX) * sensitivityFactor * float mgmX = static_cast<float>(mgmMeasurementRawX) * sensitivityFactor *
MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR; MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
float mgmY = static_cast<float>(mgmMeasurementRawY) * sensitivityFactor * float mgmY = static_cast<float>(mgmMeasurementRawY) * sensitivityFactor *
@@ -462,9 +462,7 @@ ReturnValue_t MgmLIS3MDLHandler::prepareCtrlRegisterWrite() {
return RETURN_OK; return RETURN_OK;
} }
void MgmLIS3MDLHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { void MgmLIS3MDLHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {}
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
}
uint32_t MgmLIS3MDLHandler::getTransitionDelayMs(Mode_t from, Mode_t to) { return transitionDelay; } uint32_t MgmLIS3MDLHandler::getTransitionDelayMs(Mode_t from, Mode_t to) { return transitionDelay; }

View File

@@ -12,7 +12,7 @@ MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, object_id_t deviceCommu
primaryDataset(this), primaryDataset(this),
transitionDelay(transitionDelay) { transitionDelay(transitionDelay) {
#if FSFW_HAL_RM3100_MGM_DEBUG == 1 #if FSFW_HAL_RM3100_MGM_DEBUG == 1
debugDivider = new PeriodicOperationDivider(10); debugDivider = new PeriodicOperationDivider(3);
#endif #endif
} }

View File

@@ -9,9 +9,7 @@ target_sources(${LIB_FSFW_NAME} PRIVATE
) )
if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS) if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
add_subdirectory(gpio) add_subdirectory(gpio)
endif()
add_subdirectory(spi) add_subdirectory(spi)
add_subdirectory(i2c) add_subdirectory(i2c)
add_subdirectory(uart) add_subdirectory(uart)

View File

@@ -74,7 +74,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
configureGpioByLineName(gpioConfig.first, *regularGpio); configureGpioByLineName(gpioConfig.first, *regularGpio);
break; break;
} }
case (gpio::GpioTypes::TYPE_CALLBACK): { case (gpio::GpioTypes::CALLBACK): {
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioConfig.second); auto gpioCallback = dynamic_cast<GpioCallback*>(gpioConfig.second);
if (gpioCallback->callback == nullptr) { if (gpioCallback->callback == nullptr) {
return GPIO_INVALID_INSTANCE; return GPIO_INVALID_INSTANCE;
@@ -161,11 +161,11 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, struct gpiod
consumer = regularGpio.consumer; consumer = regularGpio.consumer;
/* Configure direction and add a description to the GPIO */ /* Configure direction and add a description to the GPIO */
switch (direction) { switch (direction) {
case (gpio::DIR_OUT): { case (gpio::OUT): {
result = gpiod_line_request_output(lineHandle, consumer.c_str(), regularGpio.initValue); result = gpiod_line_request_output(lineHandle, consumer.c_str(), regularGpio.initValue);
break; break;
} }
case (gpio::DIR_IN): { case (gpio::IN): {
result = gpiod_line_request_input(lineHandle, consumer.c_str()); result = gpiod_line_request_input(lineHandle, consumer.c_str());
break; break;
} }
@@ -326,7 +326,7 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd) {
} }
break; break;
} }
case (gpio::GpioTypes::TYPE_CALLBACK): { case (gpio::GpioTypes::CALLBACK): {
auto callbackGpio = dynamic_cast<GpioCallback*>(gpioConfig.second); auto callbackGpio = dynamic_cast<GpioCallback*>(gpioConfig.second);
if (callbackGpio == nullptr) { if (callbackGpio == nullptr) {
return GPIO_TYPE_FAILURE; return GPIO_TYPE_FAILURE;
@@ -366,13 +366,13 @@ ReturnValue_t LinuxLibgpioIF::checkForConflictsById(gpioId_t gpioIdToCheck,
case (gpio::GpioTypes::GPIO_REGULAR_BY_CHIP): case (gpio::GpioTypes::GPIO_REGULAR_BY_CHIP):
case (gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): case (gpio::GpioTypes::GPIO_REGULAR_BY_LABEL):
case (gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME): { case (gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME): {
if (gpioType == gpio::GpioTypes::NONE or gpioType == gpio::GpioTypes::TYPE_CALLBACK) { if (gpioType == gpio::GpioTypes::NONE or gpioType == gpio::GpioTypes::CALLBACK) {
eraseDuplicateDifferentType = true; eraseDuplicateDifferentType = true;
} }
break; break;
} }
case (gpio::GpioTypes::TYPE_CALLBACK): { case (gpio::GpioTypes::CALLBACK): {
if (gpioType != gpio::GpioTypes::TYPE_CALLBACK) { if (gpioType != gpio::GpioTypes::CALLBACK) {
eraseDuplicateDifferentType = true; eraseDuplicateDifferentType = true;
} }
} }

View File

@@ -1,13 +1,4 @@
#include "I2cComIF.h" #include "fsfw_hal/linux/i2c/I2cComIF.h"
#include "fsfw/FSFW.h"
#include "fsfw/serviceinterface.h"
#include "fsfw_hal/linux/UnixFileGuard.h"
#include "fsfw_hal/linux/utility.h"
#if FSFW_HAL_I2C_WIRETAPPING == 1
#include "fsfw/globalfunctions/arrayprinter.h"
#endif
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@@ -17,6 +8,11 @@
#include <cstring> #include <cstring>
#include "fsfw/FSFW.h"
#include "fsfw/serviceinterface.h"
#include "fsfw_hal/linux/UnixFileGuard.h"
#include "fsfw_hal/linux/utility.h"
I2cComIF::I2cComIF(object_id_t objectId) : SystemObject(objectId) {} I2cComIF::I2cComIF(object_id_t objectId) : SystemObject(objectId) {}
I2cComIF::~I2cComIF() {} I2cComIF::~I2cComIF() {}
@@ -116,11 +112,6 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
#endif #endif
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
#if FSFW_HAL_I2C_WIRETAPPING == 1
sif::info << "Sent I2C data to bus " << deviceFile << ":" << std::endl;
arrayprinter::print(sendData, sendLen);
#endif
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@@ -185,11 +176,6 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
#if FSFW_HAL_I2C_WIRETAPPING == 1
sif::info << "I2C read bytes from bus " << deviceFile << ":" << std::endl;
arrayprinter::print(replyBuffer, requestLen);
#endif
i2cDeviceMapIter->second.replyLen = requestLen; i2cDeviceMapIter->second.replyLen = requestLen;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@@ -7,7 +7,7 @@
ReturnValue_t gpio::createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin, ReturnValue_t gpio::createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin,
std::string consumer, gpio::Direction direction, std::string consumer, gpio::Direction direction,
gpio::Levels initValue) { int initValue) {
if (cookie == nullptr) { if (cookie == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }

View File

@@ -21,8 +21,7 @@ namespace gpio {
* @return * @return
*/ */
ReturnValue_t createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin, ReturnValue_t createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin,
std::string consumer, gpio::Direction direction, std::string consumer, gpio::Direction direction, int initValue);
gpio::Levels initValue);
} // namespace gpio } // namespace gpio
#endif /* BSP_RPI_GPIO_GPIORPI_H_ */ #endif /* BSP_RPI_GPIO_GPIORPI_H_ */

View File

@@ -269,50 +269,6 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki
cfsetispeed(options, B460800); cfsetispeed(options, B460800);
cfsetospeed(options, B460800); cfsetospeed(options, B460800);
break; break;
case 500000:
cfsetispeed(options, B500000);
cfsetospeed(options, B500000);
break;
case 576000:
cfsetispeed(options, B576000);
cfsetospeed(options, B576000);
break;
case 921600:
cfsetispeed(options, B921600);
cfsetospeed(options, B921600);
break;
case 1000000:
cfsetispeed(options, B1000000);
cfsetospeed(options, B1000000);
break;
case 1152000:
cfsetispeed(options, B1152000);
cfsetospeed(options, B1152000);
break;
case 1500000:
cfsetispeed(options, B1500000);
cfsetospeed(options, B1500000);
break;
case 2000000:
cfsetispeed(options, B2000000);
cfsetospeed(options, B2000000);
break;
case 2500000:
cfsetispeed(options, B2500000);
cfsetospeed(options, B2500000);
break;
case 3000000:
cfsetispeed(options, B3000000);
cfsetospeed(options, B3000000);
break;
case 3500000:
cfsetispeed(options, B3500000);
cfsetospeed(options, B3500000);
break;
case 4000000:
cfsetispeed(options, B4000000);
cfsetospeed(options, B4000000);
break;
default: default:
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl; sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;

View File

@@ -1,4 +1,4 @@
#include "UartCookie.h" #include "fsfw_hal/linux/uart/UartCookie.h"
#include <fsfw/serviceinterface.h> #include <fsfw/serviceinterface.h>

View File

@@ -22,7 +22,7 @@ ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permiss
int fd = open(uioFile.c_str(), O_RDWR); int fd = open(uioFile.c_str(), O_RDWR);
if (fd < 1) { if (fd < 1) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "PtmeAxiConfig::initialize: Invalid UIO device file" << std::endl; sif::error << "PtmeAxiConfig::initialize: Invalid UIO device file" << std::endl;
#endif #endif
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@@ -36,8 +36,8 @@ ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permiss
if (*address == MAP_FAILED) { if (*address == MAP_FAILED) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UioMapper::getMappedAdress: Failed to map physical address of uio device " sif::error << "UioMapper::getMappedAdress: Failed to map physical address of uio device "
<< uioFile.c_str() << " and map" << static_cast<int>(mapNum) << std::endl; << uioFile.c_str() << " and map" << static_cast<int>(mapNum) << std::endl;
#endif #endif
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@@ -52,7 +52,7 @@ ReturnValue_t UioMapper::getMapSize(size_t* size) {
fp = fopen(namestream.str().c_str(), "r"); fp = fopen(namestream.str().c_str(), "r");
if (fp == nullptr) { if (fp == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UioMapper::getMapSize: Failed to open file " << namestream.str() << std::endl; sif::error << "UioMapper::getMapSize: Failed to open file " << namestream.str() << std::endl;
#endif #endif
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@@ -60,11 +60,12 @@ ReturnValue_t UioMapper::getMapSize(size_t* size) {
int items = fscanf(fp, "%s", hexstring); int items = fscanf(fp, "%s", hexstring);
if (items != 1) { if (items != 1) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UioMapper::getMapSize: Failed with error code " << errno sif::error << "UioMapper::getMapSize: Failed with error code " << errno
<< " to read size " << " to read size "
"string from file " "string from file "
<< namestream.str() << std::endl; << namestream.str() << std::endl;
#endif #endif
fclose(fp);
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
uint32_t sizeTmp = 0; uint32_t sizeTmp = 0;
@@ -74,9 +75,10 @@ ReturnValue_t UioMapper::getMapSize(size_t* size) {
} }
if (items != 1) { if (items != 1) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UioMapper::getMapSize: Failed with error code " << errno << "to convert " sif::error << "UioMapper::getMapSize: Failed with error code " << errno << "to convert "
<< "size of map" << mapNum << " to integer" << std::endl; << "size of map" << mapNum << " to integer" << std::endl;
#endif #endif
fclose(fp);
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
fclose(fp); fclose(fp);

View File

@@ -143,7 +143,10 @@ def handle_tests_type(args, build_dir_list: list):
if which("valgrind") is None: if which("valgrind") is None:
print("Please install valgrind first") print("Please install valgrind first")
sys.exit(1) sys.exit(1)
os.chdir(UNITTEST_FOLDER_NAME) if os.path.split(os.getcwd())[1] != UNITTEST_FOLDER_NAME:
# If we are in a different directory we try to switch into it but
# this might fail
os.chdir(UNITTEST_FOLDER_NAME)
os.system("valgrind --leak-check=full ./fsfw-tests") os.system("valgrind --leak-check=full ./fsfw-tests")
os.chdir("..") os.chdir("..")

View File

@@ -57,11 +57,6 @@
#define FSFW_HAL_SPI_WIRETAPPING 0 #define FSFW_HAL_SPI_WIRETAPPING 0
#endif #endif
// Can be used for low-level debugging of the I2C bus
#ifndef FSFW_HAL_I2C_WIRETAPPING
#define FSFW_HAL_I2C_WIRETAPPING 0
#endif
#ifndef FSFW_HAL_L3GD20_GYRO_DEBUG #ifndef FSFW_HAL_L3GD20_GYRO_DEBUG
#define FSFW_HAL_L3GD20_GYRO_DEBUG 0 #define FSFW_HAL_L3GD20_GYRO_DEBUG 0
#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */ #endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */

View File

@@ -1,6 +1,7 @@
#ifndef FSFW_CONTROLLER_CONTROLLERBASE_H_ #ifndef FSFW_CONTROLLER_CONTROLLERBASE_H_
#define FSFW_CONTROLLER_CONTROLLERBASE_H_ #define FSFW_CONTROLLER_CONTROLLERBASE_H_
#include "fsfw/datapool/HkSwitchHelper.h"
#include "fsfw/health/HasHealthIF.h" #include "fsfw/health/HasHealthIF.h"
#include "fsfw/health/HealthHelper.h" #include "fsfw/health/HealthHelper.h"
#include "fsfw/modes/HasModesIF.h" #include "fsfw/modes/HasModesIF.h"

View File

@@ -1,4 +1,6 @@
target_sources(${LIB_FSFW_NAME} PRIVATE target_sources(${LIB_FSFW_NAME}
PoolDataSetBase.cpp PRIVATE
PoolEntry.cpp HkSwitchHelper.cpp
PoolDataSetBase.cpp
PoolEntry.cpp
) )

View File

@@ -0,0 +1,67 @@
#include "fsfw/datapool/HkSwitchHelper.h"
#include "fsfw/ipc/QueueFactory.h"
HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy)
: commandActionHelper(this), eventProxy(eventProxy) {
actionQueue = QueueFactory::instance()->createMessageQueue();
}
HkSwitchHelper::~HkSwitchHelper() { QueueFactory::instance()->deleteMessageQueue(actionQueue); }
ReturnValue_t HkSwitchHelper::initialize() {
ReturnValue_t result = commandActionHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return result;
}
ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) {
CommandMessage command;
while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) {
ReturnValue_t result = commandActionHelper.handleReply(&command);
if (result == HasReturnvaluesIF::RETURN_OK) {
continue;
}
command.setToUnknownCommand();
actionQueue->reply(&command);
}
return HasReturnvaluesIF::RETURN_OK;
}
void HkSwitchHelper::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) {}
void HkSwitchHelper::stepFailedReceived(ActionId_t actionId, uint8_t step,
ReturnValue_t returnCode) {
eventProxy->forwardEvent(SWITCHING_TM_FAILED, returnCode, actionId);
}
void HkSwitchHelper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {}
void HkSwitchHelper::completionSuccessfulReceived(ActionId_t actionId) {}
void HkSwitchHelper::completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) {
eventProxy->forwardEvent(SWITCHING_TM_FAILED, returnCode, actionId);
}
ReturnValue_t HkSwitchHelper::switchHK(SerializeIF* sids, bool enable) {
// ActionId_t action = HKService::DISABLE_HK;
// if (enable) {
// action = HKService::ENABLE_HK;
// }
//
// ReturnValue_t result = commandActionHelper.commandAction(
// objects::PUS_HK_SERVICE, action, sids);
//
// if (result != HasReturnvaluesIF::RETURN_OK) {
// eventProxy->forwardEvent(SWITCHING_TM_FAILED, result);
// }
// return result;
return HasReturnvaluesIF::RETURN_OK;
}
MessageQueueIF* HkSwitchHelper::getCommandQueuePtr() { return actionQueue; }

View File

@@ -0,0 +1,44 @@
#ifndef FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_
#define FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_
#include "fsfw/action/CommandsActionsIF.h"
#include "fsfw/events/EventReportingProxyIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
// TODO this class violations separation between mission and framework
// but it is only a transitional solution until the Datapool is
// implemented decentrally
class HkSwitchHelper : public ExecutableObjectIF, public CommandsActionsIF {
public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::HK;
static const Event SWITCHING_TM_FAILED =
MAKE_EVENT(1, severity::LOW); //!< Commanding the HK Service failed, p1: error code, p2
//!< action: 0 disable / 1 enable
HkSwitchHelper(EventReportingProxyIF* eventProxy);
virtual ~HkSwitchHelper();
ReturnValue_t initialize();
virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
ReturnValue_t switchHK(SerializeIF* sids, bool enable);
virtual void setTaskIF(PeriodicTaskIF* task_){};
protected:
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step);
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode);
virtual void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size);
virtual void completionSuccessfulReceived(ActionId_t actionId);
virtual void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode);
virtual MessageQueueIF* getCommandQueuePtr();
private:
CommandActionHelper commandActionHelper;
MessageQueueIF* actionQueue;
EventReportingProxyIF* eventProxy;
};
#endif /* FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_ */

View File

@@ -47,14 +47,13 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner); HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner);
if (hkOwner == nullptr) { if (hkOwner == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalPoolVariable: The supplied pool owner 0x" << std::hex << poolOwner sif::error << "LocalPoolVariable: The supplied pool owner did not implement the correct "
<< std::dec << " did not implement the correct interface " "interface HasLocalDataPoolIF!"
<< "HasLocalDataPoolIF" << std::endl; << std::endl;
#else #else
sif::printError( sif::printError(
"LocalPoolVariable: The supplied pool owner 0x%08x did not implement the correct " "LocalPoolVariable: The supplied pool owner did not implement the correct "
"interface HasLocalDataPoolIF\n", "interface HasLocalDataPoolIF!\n");
poolOwner);
#endif #endif
return; return;
} }

View File

@@ -46,7 +46,7 @@ class StaticLocalDataSet : public LocalPoolDataSetBase {
} }
private: private:
std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList = {}; std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList;
}; };
#endif /* FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */ #endif /* FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */

View File

@@ -29,7 +29,6 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
switch (event->getEvent()) { switch (event->getEvent()) {
case HasModesIF::MODE_TRANSITION_FAILED: case HasModesIF::MODE_TRANSITION_FAILED:
case HasModesIF::OBJECT_IN_INVALID_MODE: case HasModesIF::OBJECT_IN_INVALID_MODE:
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
// We'll try a recovery as long as defined in MAX_REBOOT. // We'll try a recovery as long as defined in MAX_REBOOT.
// Might cause some AssemblyBase cycles, so keep number low. // Might cause some AssemblyBase cycles, so keep number low.
handleRecovery(event->getEvent()); handleRecovery(event->getEvent());

View File

@@ -109,7 +109,6 @@ class DeviceHandlerIF {
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW); static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, severity::LOW);
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW); static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, severity::LOW);
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH); static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, severity::HIGH);
static const Event DEVICE_WANTS_HARD_REBOOT = MAKE_EVENT(11, severity::HIGH);
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF; static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;

View File

@@ -14,12 +14,13 @@ class FailureIsolationBase : public HasReturnvaluesIF,
public HasParametersIF { public HasParametersIF {
public: public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FDIR_1;
//! FDIR has an internal state, which changed from par2 (oldState) to par1 (newState). static const Event FDIR_CHANGED_STATE =
static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, severity::INFO); MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2
//! FDIR tries to restart device. Par1: event that caused recovery. //!< (oldState) to par1 (newState).
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM); static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(
//! FDIR turns off device. Par1: event that caused recovery. 2, severity::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery.
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM); static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(
3, severity::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery.
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT, FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0); uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);

View File

@@ -117,7 +117,7 @@ uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t starti
// { // {
// if (xor_out[i] == true) // if (xor_out[i] == true)
// crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before // crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before
// Final XOR //Final XOR
// } // }
// //
// crc_value = 0;// for debug mode // crc_value = 0;// for debug mode

View File

@@ -23,15 +23,19 @@ class HasHealthIF {
static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO); static const Event HEALTH_INFO = MAKE_EVENT(6, severity::INFO);
static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO); static const Event CHILD_CHANGED_HEALTH = MAKE_EVENT(7, severity::INFO);
static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW); static const Event CHILD_PROBLEMS = MAKE_EVENT(8, severity::LOW);
//! Assembly overwrites health information of children to keep satellite alive. static const Event OVERWRITING_HEALTH =
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW); MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
//! Someone starts a recovery of a component (typically power-cycle). No parameters. //!< satellite alive.
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM); static const Event TRYING_RECOVERY =
//! Recovery is ongoing. Comes twice during recovery. MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
//! P1: 0 for the first, 1 for the second event. P2: 0 //!< power-cycle). No parameters.
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM); static const Event RECOVERY_STEP =
//! Recovery was completed. Not necessarily successful. No parameters. MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM); //!< 0 for the first, 1 for the second event. P2: 0
static const Event RECOVERY_DONE = MAKE_EVENT(
12,
severity::MEDIUM); //!< Recovery was completed. Not necessarily successful. No parameters.
virtual ~HasHealthIF() {} virtual ~HasHealthIF() {}
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;

View File

@@ -19,29 +19,32 @@ class HasModesIF {
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04); static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYSTEM_MANAGER;
//! An object announces changing the mode. p1: target mode. p2: target submode static const Event CHANGING_MODE =
static const Event CHANGING_MODE = MAKE_EVENT(0, severity::INFO); MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode.
//! An Object announces its mode; parameter1 is mode, parameter2 is submode //!< p2: target submode
static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO); static const Event MODE_INFO = MAKE_EVENT(
1,
severity::INFO); //!< An Object announces its mode; parameter1 is mode, parameter2 is submode
static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH); static const Event FALLBACK_FAILED = MAKE_EVENT(2, severity::HIGH);
static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW); static const Event MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH); static const Event CANT_KEEP_MODE = MAKE_EVENT(4, severity::HIGH);
//! Indicates a bug or configuration failure: Object is in a mode it should never be in. static const Event OBJECT_IN_INVALID_MODE =
static const Event OBJECT_IN_INVALID_MODE = MAKE_EVENT(5, severity::LOW); MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a
//! The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored. //!< mode it should never be in.
//! p1: target mode. p2: target submode static const Event FORCING_MODE = MAKE_EVENT(
static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM); 6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced,
//! A mode command was rejected by the called object. Par1: called object id, Par2: return code. //!< i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode
static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW); static const Event MODE_CMD_REJECTED =
MAKE_EVENT(7, severity::LOW); //!< A mode command was rejected by the called object. Par1:
//!< called object id, Par2: return code.
//! The device is powered and ready to perform operations. In this mode, no commands are static const Mode_t MODE_ON =
//! sent by the device handler itself, but direct commands van be commanded and will be 1; //!< The device is powered and ready to perform operations. In this mode, no commands are
//! interpreted //!< sent by the device handler itself, but direct commands van be commanded and will be
static const Mode_t MODE_ON = 1; //!< interpreted
//! The device is powered off. The only command accepted in this mode is a mode change to on. static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in
static const Mode_t MODE_OFF = 0; //!< this mode is a mode change to on.
//! To avoid checks against magic number "0". static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0".
static const Submode_t SUBMODE_NONE = 0;
virtual ~HasModesIF() {} virtual ~HasModesIF() {}
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;

View File

@@ -1,29 +1,29 @@
target_sources(${LIB_FSFW_NAME} PRIVATE target_sources(${LIB_FSFW_NAME} PRIVATE
Clock.cpp Clock.cpp
BinarySemaphore.cpp BinarySemaphore.cpp
CountingSemaphore.cpp CountingSemaphore.cpp
FixedTimeslotTask.cpp FixedTimeslotTask.cpp
InternalErrorCodes.cpp InternalErrorCodes.cpp
MessageQueue.cpp MessageQueue.cpp
Mutex.cpp Mutex.cpp
MutexFactory.cpp MutexFactory.cpp
PeriodicPosixTask.cpp PeriodicPosixTask.cpp
PosixThread.cpp PosixThread.cpp
QueueFactory.cpp QueueFactory.cpp
SemaphoreFactory.cpp SemaphoreFactory.cpp
TaskFactory.cpp TaskFactory.cpp
tcpipHelpers.cpp tcpipHelpers.cpp
unixUtility.cpp unixUtility.cpp
) )
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
target_link_libraries(${LIB_FSFW_NAME} PRIVATE target_link_libraries(${LIB_FSFW_NAME} PRIVATE
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
rt rt
) )
target_link_libraries(${LIB_FSFW_NAME} INTERFACE target_link_libraries(${LIB_FSFW_NAME} INTERFACE
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
) )

View File

@@ -65,10 +65,9 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
/** /**
* @brief The function containing the actual functionality of the task. * @brief The function containing the actual functionality of the task.
* @details The method sets and starts * @details The method sets and starts
* the task's period, then enters a loop that is repeated indefinitely. Within * the task's period, then enters a loop that is repeated indefinitely. Within the
* the loop, all performOperation methods of the added objects are called. Afterwards the task * loop, all performOperation methods of the added objects are called. Afterwards the task will be
* will be blocked until the next period. On missing the deadline, the deadlineMissedFunction is * blocked until the next period. On missing the deadline, the deadlineMissedFunction is executed.
* executed.
*/ */
virtual void taskFunctionality(void); virtual void taskFunctionality(void);
/** /**

View File

@@ -13,8 +13,8 @@ class ExecutableObjectIF;
* @brief This class represents a specialized task for periodic activities of multiple objects. * @brief This class represents a specialized task for periodic activities of multiple objects.
* *
* @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute * @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute
* multiple objects that implement the ExecutableObjectIF interface. The * multiple objects that implement the ExecutableObjectIF interface. The objects
* objects must be added prior to starting the task. * must be added prior to starting the task.
* @author baetz * @author baetz
* @ingroup task_handling * @ingroup task_handling
*/ */

View File

@@ -34,14 +34,14 @@ class Fuse : public SystemObject,
}; };
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1;
//! PSS detected that current on a fuse is totally out of bounds. static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(1, severity::LOW); 1, severity::LOW); //!< PSS detected that current on a fuse is totally out of bounds.
//! PSS detected a fuse that went off. static const Event FUSE_WENT_OFF =
static const Event FUSE_WENT_OFF = MAKE_EVENT(2, severity::LOW); MAKE_EVENT(2, severity::LOW); //!< PSS detected a fuse that went off.
//! PSS detected a fuse that violates its limits. static const Event POWER_ABOVE_HIGH_LIMIT =
static const Event POWER_ABOVE_HIGH_LIMIT = MAKE_EVENT(4, severity::LOW); MAKE_EVENT(4, severity::LOW); //!< PSS detected a fuse that violates its limits.
//! PSS detected a fuse that violates its limits. static const Event POWER_BELOW_LOW_LIMIT =
static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, severity::LOW); MAKE_EVENT(5, severity::LOW); //!< PSS detected a fuse that violates its limits.
typedef std::list<PowerComponentIF *> DeviceList; typedef std::list<PowerComponentIF *> DeviceList;
Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids, Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,

View File

@@ -6,10 +6,10 @@
class Service9TimeManagement : public PusServiceBase { class Service9TimeManagement : public PusServiceBase {
public: public:
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_9;
//!< Clock has been set. P1: New Uptime. P2: Old Uptime static constexpr Event CLOCK_SET =
static constexpr Event CLOCK_SET = MAKE_EVENT(0, severity::INFO); MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime
//!< Clock could not be set. P1: Returncode. static constexpr Event CLOCK_SET_FAILURE =
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(1, severity::LOW); MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode.
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9; static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;

View File

@@ -169,8 +169,8 @@ class RMAP : public HasReturnvaluesIF {
* @param buffer the data to write * @param buffer the data to write
* @param length length of data * @param length length of data
* @return * @return
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in
* NULL in write command * write command
* - return codes of RMAPChannelIF::sendCommand() * - return codes of RMAPChannelIF::sendCommand()
*/ */
static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, const uint8_t *buffer, size_t length); static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, const uint8_t *buffer, size_t length);
@@ -205,8 +205,8 @@ class RMAP : public HasReturnvaluesIF {
* @param cookie to cookie to read from * @param cookie to cookie to read from
* @param expLength the expected maximum length of the reply * @param expLength the expected maximum length of the reply
* @return * @return
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == * - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in
* NULL in write command, or nullpointer in read command * write command, or nullpointer in read command
* - return codes of RMAPChannelIF::sendCommand() * - return codes of RMAPChannelIF::sendCommand()
*/ */
static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength); static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength);

View File

@@ -75,11 +75,11 @@ class RMAPChannelIF {
* - @c RETURN_OK * - @c RETURN_OK
* - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending * - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending
* command; command was not sent * command; command was not sent
* - @c COMMAND_BUFFER_FULL no receiver buffer available for * - @c COMMAND_BUFFER_FULL no receiver buffer available for expected len;
* expected len; command was not sent * command was not sent
* - @c COMMAND_TOO_BIG the data that was to be sent was too long * - @c COMMAND_TOO_BIG the data that was to be sent was too long for the hw
* for the hw to handle (write command) or the expected len was bigger than maximal expected len * to handle (write command) or the expected len was bigger than maximal expected len (read
* (read command) command was not sent * command) command was not sent
* - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set * - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set
* - @c NOT_SUPPORTED if you dont feel like * - @c NOT_SUPPORTED if you dont feel like
* implementing something... * implementing something...
@@ -97,8 +97,8 @@ class RMAPChannelIF {
* - @c REPLY_NO_REPLY no reply was received * - @c REPLY_NO_REPLY no reply was received
* - @c REPLY_NOT_SENT command was not sent, implies no reply * - @c REPLY_NOT_SENT command was not sent, implies no reply
* - @c REPLY_NOT_YET_SENT command is still waiting to be sent * - @c REPLY_NOT_YET_SENT command is still waiting to be sent
* - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission * - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer still
* buffer still being processed) * being processed)
* - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last * - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last
* operation, data could not be processed. (transmission error) * operation, data could not be processed. (transmission error)
* - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value) * - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value)

View File

@@ -99,13 +99,6 @@ class Clock {
*/ */
static ReturnValue_t getDateAndTime(TimeOfDay_t *time); static ReturnValue_t getDateAndTime(TimeOfDay_t *time);
/**
* Convert to time of day struct given the POSIX timeval struct
* @param from
* @param to
* @return
*/
static ReturnValue_t convertTimevalToTimeOfDay(const timeval *from, TimeOfDay_t *to);
/** /**
* Converts a time of day struct to POSIX seconds. * Converts a time of day struct to POSIX seconds.
* @param time The time of day as input * @param time The time of day as input

View File

@@ -1,9 +1,7 @@
#include <ctime>
#include "fsfw/ipc/MutexGuard.h" #include "fsfw/ipc/MutexGuard.h"
#include "fsfw/timemanager/Clock.h" #include "fsfw/timemanager/Clock.h"
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval *tt) {
uint16_t leapSeconds; uint16_t leapSeconds;
ReturnValue_t result = getLeapSeconds(&leapSeconds); ReturnValue_t result = getLeapSeconds(&leapSeconds);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
@@ -33,7 +31,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { ReturnValue_t Clock::getLeapSeconds(uint16_t *leapSeconds_) {
if (timeMutex == nullptr) { if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@@ -44,22 +42,9 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t Clock::convertTimevalToTimeOfDay(const timeval* from, TimeOfDay_t* to) {
struct tm* timeInfo;
timeInfo = gmtime(&from->tv_sec);
to->year = timeInfo->tm_year + 1900;
to->month = timeInfo->tm_mon + 1;
to->day = timeInfo->tm_mday;
to->hour = timeInfo->tm_hour;
to->minute = timeInfo->tm_min;
to->second = timeInfo->tm_sec;
to->usecond = from->tv_usec;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Clock::checkOrCreateClockMutex() { ReturnValue_t Clock::checkOrCreateClockMutex() {
if (timeMutex == nullptr) { if (timeMutex == nullptr) {
MutexFactory* mutexFactory = MutexFactory::instance(); MutexFactory *mutexFactory = MutexFactory::instance();
if (mutexFactory == nullptr) { if (mutexFactory == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }

View File

@@ -33,47 +33,50 @@ class TmStoreBackendIF : public HasParametersIF {
static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15); static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY;
//! Initiating sending data to store failed. Low, par1: static const Event STORE_SEND_WRITE_FAILED =
//! returnCode, par2: integer (debug info) MAKE_EVENT(0, severity::LOW); //!< Initiating sending data to store failed. Low, par1:
static const Event STORE_SEND_WRITE_FAILED = MAKE_EVENT(0, severity::LOW); //!< returnCode, par2: integer (debug info)
//! Data was sent, but writing failed. Low, par1: returnCode, par2: 0 static const Event STORE_WRITE_FAILED = MAKE_EVENT(
static const Event STORE_WRITE_FAILED = MAKE_EVENT(1, severity::LOW); 1, severity::LOW); //!< Data was sent, but writing failed. Low, par1: returnCode, par2: 0
//! Initiating reading data from store failed. Low, par1: returnCode, par2: 0 static const Event STORE_SEND_READ_FAILED =
static const Event STORE_SEND_READ_FAILED = MAKE_EVENT(2, severity::LOW); MAKE_EVENT(2, severity::LOW); //!< Initiating reading data from store failed. Low, par1:
//! Data was requested, but access failed. Low, par1: returnCode, par2: 0 //!< returnCode, par2: 0
static const Event STORE_READ_FAILED = MAKE_EVENT(3, severity::LOW); static const Event STORE_READ_FAILED = MAKE_EVENT(
//! An unexpected TM packet or data message occurred. Low, par1: 0, par2: integer (debug info) 3, severity::LOW); //!< Data was requested, but access failed. Low, par1: returnCode, par2: 0
static const Event UNEXPECTED_MSG = MAKE_EVENT(4, severity::LOW); static const Event UNEXPECTED_MSG =
//! Storing data failed. May simply be a full store. Low, par1: returnCode, MAKE_EVENT(4, severity::LOW); //!< An unexpected TM packet or data message occurred. Low,
//! par2: integer (sequence count of failed packet). //!< par1: 0, par2: integer (debug info)
static const Event STORING_FAILED = MAKE_EVENT(5, severity::LOW); static const Event STORING_FAILED = MAKE_EVENT(
//! Dumping retrieved data failed. Low, par1: returnCode, 5, severity::LOW); //!< Storing data failed. May simply be a full store. Low, par1:
//! par2: integer (sequence count of failed packet). //!< returnCode, par2: integer (sequence count of failed packet).
static const Event TM_DUMP_FAILED = MAKE_EVENT(6, severity::LOW); static const Event TM_DUMP_FAILED =
//! Corrupted init data or read error. Low, par1: returnCode, par2: integer (debug info) MAKE_EVENT(6, severity::LOW); //!< Dumping retrieved data failed. Low, par1: returnCode,
//! Store was not initialized. Starts empty. Info, parameters both zero. //!< par2: integer (sequence count of failed packet).
static const Event STORE_INIT_FAILED = MAKE_EVENT(7, severity::LOW); static const Event STORE_INIT_FAILED =
//! Data was read out, but it is inconsistent. Low par1: MAKE_EVENT(7, severity::LOW); //!< Corrupted init data or read error. Low, par1: returnCode,
//! Memory address of corruption, par2: integer (debug info) //!< par2: integer (debug info)
static const Event STORE_INIT_EMPTY = MAKE_EVENT(8, severity::INFO); static const Event STORE_INIT_EMPTY = MAKE_EVENT(
8, severity::INFO); //!< Store was not initialized. Starts empty. Info, parameters both zero.
static const Event STORE_CONTENT_CORRUPTED = MAKE_EVENT(9, severity::LOW); static const Event STORE_CONTENT_CORRUPTED =
//! Info event indicating the store will be initialized, either at boot or after IOB switch. MAKE_EVENT(9, severity::LOW); //!< Data was read out, but it is inconsistent. Low par1:
//! Info. pars: 0 //!< Memory address of corruption, par2: integer (debug info)
static const Event STORE_INITIALIZE = MAKE_EVENT(10, severity::INFO); static const Event STORE_INITIALIZE =
//! Info event indicating the store was successfully initialized, either at boot or after MAKE_EVENT(10, severity::INFO); //!< Info event indicating the store will be initialized,
//! IOB switch. Info. pars: 0 //!< either at boot or after IOB switch. Info. pars: 0
static const Event INIT_DONE = MAKE_EVENT(11, severity::INFO); static const Event INIT_DONE = MAKE_EVENT(
//! Info event indicating that dumping finished successfully. 11, severity::INFO); //!< Info event indicating the store was successfully initialized,
//! par1: Number of dumped packets. par2: APID/SSC (16bits each) //!< either at boot or after IOB switch. Info. pars: 0
static const Event DUMP_FINISHED = MAKE_EVENT(12, severity::INFO); static const Event DUMP_FINISHED = MAKE_EVENT(
//! Info event indicating that deletion finished successfully. 12, severity::INFO); //!< Info event indicating that dumping finished successfully. par1:
//! par1:Number of deleted packets. par2: APID/SSC (16bits each) //!< Number of dumped packets. par2: APID/SSC (16bits each)
static const Event DELETION_FINISHED = MAKE_EVENT(13, severity::INFO); static const Event DELETION_FINISHED = MAKE_EVENT(
//! Info event indicating that something went wrong during deletion. pars: 0 13, severity::INFO); //!< Info event indicating that deletion finished successfully. par1:
static const Event DELETION_FAILED = MAKE_EVENT(14, severity::LOW); //!< Number of deleted packets. par2: APID/SSC (16bits each)
//! Info that the a auto catalog report failed static const Event DELETION_FAILED = MAKE_EVENT(
static const Event AUTO_CATALOGS_SENDING_FAILED = MAKE_EVENT(15, severity::INFO); 14,
severity::LOW); //!< Info event indicating that something went wrong during deletion. pars: 0
static const Event AUTO_CATALOGS_SENDING_FAILED =
MAKE_EVENT(15, severity::INFO); //!< Info that the a auto catalog report failed
virtual ~TmStoreBackendIF() {} virtual ~TmStoreBackendIF() {}

View File

@@ -172,18 +172,15 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage* message) {
} }
if (tmFifo->full()) { if (tmFifo->full()) {
if (warningSwitch) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number " sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!" "of stored packet IDs reached!"
<< std::endl; << std::endl;
#else #else
sif::printWarning( sif::printWarning(
"TmTcBridge::storeDownlinkData: TM downlink max. number " "TmTcBridge::storeDownlinkData: TM downlink max. number "
"of stored packet IDs reached!\n"); "of stored packet IDs reached!\n");
#endif #endif
warningSwitch = true;
}
if (overwriteOld) { if (overwriteOld) {
tmFifo->retrieve(&storeId); tmFifo->retrieve(&storeId);
tmStore->deleteData(storeId); tmStore->deleteData(storeId);

View File

@@ -72,8 +72,6 @@ class TmTcBridge : public AcceptsTelemetryIF,
virtual uint16_t getIdentifier() override; virtual uint16_t getIdentifier() override;
virtual MessageQueueId_t getRequestQueue() override; virtual MessageQueueId_t getRequestQueue() override;
bool warningSwitch = true;
protected: protected:
//! Cached for initialize function. //! Cached for initialize function.
object_id_t tmStoreId = objects::NO_OBJECT; object_id_t tmStoreId = objects::NO_OBJECT;

View File

@@ -45,7 +45,7 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
result = cmdExecutor.check(bytesHaveBeenRead); result = cmdExecutor.check(bytesHaveBeenRead);
REQUIRE(result != CommandExecutor::COMMAND_ERROR); REQUIRE(result != CommandExecutor::COMMAND_ERROR);
usleep(500); usleep(500);
REQUIRE(limitIdx < 5); REQUIRE(limitIdx < 500);
} }
limitIdx = 0; limitIdx = 0;
@@ -71,8 +71,9 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
limitIdx++; limitIdx++;
result = cmdExecutor.check(bytesHaveBeenRead); result = cmdExecutor.check(bytesHaveBeenRead);
REQUIRE(result != CommandExecutor::COMMAND_ERROR); REQUIRE(result != CommandExecutor::COMMAND_ERROR);
// This ensures that the tests do not block indefinitely
usleep(500); usleep(500);
REQUIRE(limitIdx < 20); REQUIRE(limitIdx < 500);
} }
limitIdx = 0; limitIdx = 0;
CHECK(bytesHaveBeenRead == true); CHECK(bytesHaveBeenRead == true);
@@ -89,7 +90,7 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
std::string allTheReply(reinterpret_cast<char*>(largerReadBuffer)); std::string allTheReply(reinterpret_cast<char*>(largerReadBuffer));
// I am just going to assume that this string is the same across ping implementations // I am just going to assume that this string is the same across ping implementations
// of different Linux systems // of different Linux systems
REQUIRE(allTheReply.find("localhost ping statistics") != std::string::npos); REQUIRE(allTheReply.find("PING localhost") != std::string::npos);
// Now check failing command // Now check failing command
result = cmdExecutor.load("false", false, false); result = cmdExecutor.load("false", false, false);
@@ -101,8 +102,9 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
limitIdx++; limitIdx++;
result = cmdExecutor.check(bytesHaveBeenRead); result = cmdExecutor.check(bytesHaveBeenRead);
REQUIRE(result != CommandExecutor::COMMAND_ERROR); REQUIRE(result != CommandExecutor::COMMAND_ERROR);
// This ensures that the tests do not block indefinitely
usleep(500); usleep(500);
REQUIRE(limitIdx < 20); REQUIRE(limitIdx < 500);
} }
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED); REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
REQUIRE(cmdExecutor.getLastError() == 1); REQUIRE(cmdExecutor.getLastError() == 1);