Update FSFW #33
@ -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
|
||||||
|
|
@ -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)
|
||||||
|
36
README.md
36
README.md
@ -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
|
||||||
|
@ -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
|
|
||||||
|
8
automation/Jenkinsfile
vendored
8
automation/Jenkinsfile
vendored
@ -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') {
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -9,9 +9,6 @@ GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceC
|
|||||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||||
transitionDelayMs(transitionDelayMs),
|
transitionDelayMs(transitionDelayMs),
|
||||||
dataset(this) {
|
dataset(this) {
|
||||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
|
||||||
debugDivider = new PeriodicOperationDivider(10);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GyroHandlerL3GD20H::~GyroHandlerL3GD20H() {}
|
GyroHandlerL3GD20H::~GyroHandlerL3GD20H() {}
|
||||||
@ -193,22 +190,23 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
|
|
||||||
int8_t temperaturOffset = (-1) * packet[L3GD20H::TEMPERATURE_IDX];
|
int8_t temperaturOffset = (-1) * packet[L3GD20H::TEMPERATURE_IDX];
|
||||||
float temperature = 25.0 + temperaturOffset;
|
float temperature = 25.0 + temperaturOffset;
|
||||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
if(periodicPrintout) {
|
||||||
if (debugDivider->checkAndIncrement()) {
|
if (debugDivider.checkAndIncrement()) {
|
||||||
/* Set terminal to utf-8 if there is an issue with micro printout. */
|
/* Set terminal to utf-8 if there is an issue with micro printout. */
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "GyroHandlerL3GD20H: Angular velocities (deg/s):" << std::endl;
|
sif::info << "GyroHandlerL3GD20H: Angular velocities (deg/s):" << std::endl;
|
||||||
sif::info << "X: " << angVelocX << std::endl;
|
sif::info << "X: " << angVelocX << std::endl;
|
||||||
sif::info << "Y: " << angVelocY << std::endl;
|
sif::info << "Y: " << angVelocY << std::endl;
|
||||||
sif::info << "Z: " << angVelocZ << std::endl;
|
sif::info << "Z: " << angVelocZ << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printInfo("GyroHandlerL3GD20H: Angular velocities (deg/s):\n");
|
sif::printInfo("GyroHandlerL3GD20H: Angular velocities (deg/s):\n");
|
||||||
sif::printInfo("X: %f\n", angVelocX);
|
sif::printInfo("X: %f\n", angVelocX);
|
||||||
sif::printInfo("Y: %f\n", angVelocY);
|
sif::printInfo("Y: %f\n", angVelocY);
|
||||||
sif::printInfo("Z: %f\n", angVelocZ);
|
sif::printInfo("Z: %f\n", angVelocZ);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
PoolReadGuard readSet(&dataset);
|
PoolReadGuard readSet(&dataset);
|
||||||
if (readSet.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
|
if (readSet.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
|
||||||
@ -272,3 +270,8 @@ void GyroHandlerL3GD20H::setAbsoluteLimits(float limitX, float limitY, float lim
|
|||||||
this->absLimitY = limitY;
|
this->absLimitY = limitY;
|
||||||
this->absLimitZ = limitZ;
|
this->absLimitZ = limitZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GyroHandlerL3GD20H::enablePeriodicPrintouts(bool enable, uint8_t divider) {
|
||||||
|
periodicPrintout = enable;
|
||||||
|
debugDivider.setDivider(divider);
|
||||||
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
#ifndef MISSION_DEVICES_GYROL3GD20HANDLER_H_
|
#ifndef MISSION_DEVICES_GYROL3GD20HANDLER_H_
|
||||||
#define MISSION_DEVICES_GYROL3GD20HANDLER_H_
|
#define MISSION_DEVICES_GYROL3GD20HANDLER_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>
|
||||||
|
|
||||||
#include "devicedefinitions/GyroL3GD20Definitions.h"
|
|
||||||
#include "fsfw/FSFW.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Device Handler for the L3GD20H gyroscope sensor
|
* @brief Device Handler for the L3GD20H gyroscope sensor
|
||||||
* (https://www.st.com/en/mems-and-sensors/l3gd20h.html)
|
* (https://www.st.com/en/mems-and-sensors/l3gd20h.html)
|
||||||
@ -22,6 +21,8 @@ class GyroHandlerL3GD20H : public DeviceHandlerBase {
|
|||||||
uint32_t transitionDelayMs);
|
uint32_t transitionDelayMs);
|
||||||
virtual ~GyroHandlerL3GD20H();
|
virtual ~GyroHandlerL3GD20H();
|
||||||
|
|
||||||
|
void enablePeriodicPrintouts(bool enable, uint8_t divider);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the absolute limit for the values on the axis in degrees per second.
|
* Set the absolute limit for the values on the axis in degrees per second.
|
||||||
* The dataset values will be marked as invalid if that limit is exceeded
|
* The dataset values will be marked as invalid if that limit is exceeded
|
||||||
@ -58,6 +59,7 @@ class GyroHandlerL3GD20H : public DeviceHandlerBase {
|
|||||||
uint32_t transitionDelayMs = 0;
|
uint32_t transitionDelayMs = 0;
|
||||||
GyroPrimaryDataset dataset;
|
GyroPrimaryDataset dataset;
|
||||||
|
|
||||||
|
|
||||||
float absLimitX = L3GD20H::RANGE_DPS_00;
|
float absLimitX = L3GD20H::RANGE_DPS_00;
|
||||||
float absLimitY = L3GD20H::RANGE_DPS_00;
|
float absLimitY = L3GD20H::RANGE_DPS_00;
|
||||||
float absLimitZ = L3GD20H::RANGE_DPS_00;
|
float absLimitZ = L3GD20H::RANGE_DPS_00;
|
||||||
@ -80,9 +82,8 @@ class GyroHandlerL3GD20H : public DeviceHandlerBase {
|
|||||||
// Set default value
|
// Set default value
|
||||||
float sensitivity = L3GD20H::SENSITIVITY_00;
|
float sensitivity = L3GD20H::SENSITIVITY_00;
|
||||||
|
|
||||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
bool periodicPrintout = false;
|
||||||
PeriodicOperationDivider *debugDivider = nullptr;
|
PeriodicOperationDivider debugDivider = PeriodicOperationDivider(3);
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_GYROL3GD20HANDLER_H_ */
|
#endif /* MISSION_DEVICES_GYROL3GD20HANDLER_H_ */
|
||||||
|
@ -12,9 +12,6 @@ MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCom
|
|||||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||||
dataset(this),
|
dataset(this),
|
||||||
transitionDelay(transitionDelay) {
|
transitionDelay(transitionDelay) {
|
||||||
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
|
||||||
debugDivider = new PeriodicOperationDivider(10);
|
|
||||||
#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;
|
||||||
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
|
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
|
||||||
@ -272,23 +269,25 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
|||||||
float mgmZ = static_cast<float>(mgmMeasurementRawZ) * sensitivityFactor *
|
float mgmZ = static_cast<float>(mgmMeasurementRawZ) * sensitivityFactor *
|
||||||
MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
|
MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
|
||||||
|
|
||||||
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
if(periodicPrintout) {
|
||||||
if (debugDivider->checkAndIncrement()) {
|
if (debugDivider.checkAndIncrement()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "MGMHandlerLIS3: Magnetic field strength in"
|
sif::info << "MGMHandlerLIS3: Magnetic field strength in"
|
||||||
" microtesla:"
|
" microtesla:"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
sif::info << "X: " << mgmX << " uT" << std::endl;
|
sif::info << "X: " << mgmX << " uT" << std::endl;
|
||||||
sif::info << "Y: " << mgmY << " uT" << std::endl;
|
sif::info << "Y: " << mgmY << " uT" << std::endl;
|
||||||
sif::info << "Z: " << mgmZ << " uT" << std::endl;
|
sif::info << "Z: " << mgmZ << " uT" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printInfo("MGMHandlerLIS3: Magnetic field strength in microtesla:\n");
|
sif::printInfo("MGMHandlerLIS3: Magnetic field strength in microtesla:\n");
|
||||||
sif::printInfo("X: %f uT\n", mgmX);
|
sif::printInfo("X: %f uT\n", mgmX);
|
||||||
sif::printInfo("Y: %f uT\n", mgmY);
|
sif::printInfo("Y: %f uT\n", mgmY);
|
||||||
sif::printInfo("Z: %f uT\n", mgmZ);
|
sif::printInfo("Z: %f uT\n", mgmZ);
|
||||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */
|
#endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* OBSW_VERBOSE_LEVEL >= 1 */
|
|
||||||
|
|
||||||
PoolReadGuard readHelper(&dataset);
|
PoolReadGuard readHelper(&dataset);
|
||||||
if (readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
|
if (readHelper.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
|
||||||
if (std::abs(mgmX) < absLimitX) {
|
if (std::abs(mgmX) < absLimitX) {
|
||||||
@ -318,15 +317,16 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
|||||||
case MGMLIS3MDL::READ_TEMPERATURE: {
|
case MGMLIS3MDL::READ_TEMPERATURE: {
|
||||||
int16_t tempValueRaw = packet[2] << 8 | packet[1];
|
int16_t tempValueRaw = packet[2] << 8 | packet[1];
|
||||||
float tempValue = 25.0 + ((static_cast<float>(tempValueRaw)) / 8.0);
|
float tempValue = 25.0 + ((static_cast<float>(tempValueRaw)) / 8.0);
|
||||||
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
if(periodicPrintout) {
|
||||||
if (debugDivider->check()) {
|
if (debugDivider.check()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " C" << std::endl;
|
sif::info << "MGMHandlerLIS3: Temperature: " << tempValue << " C" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printInfo("MGMHandlerLIS3: Temperature: %f C\n");
|
sif::printInfo("MGMHandlerLIS3: Temperature: %f C\n");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
ReturnValue_t result = dataset.read();
|
ReturnValue_t result = dataset.read();
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
dataset.temperature = tempValue;
|
dataset.temperature = tempValue;
|
||||||
@ -484,3 +484,9 @@ void MgmLIS3MDLHandler::setAbsoluteLimits(float xLimit, float yLimit, float zLim
|
|||||||
this->absLimitY = yLimit;
|
this->absLimitY = yLimit;
|
||||||
this->absLimitZ = zLimit;
|
this->absLimitZ = zLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MgmLIS3MDLHandler::enablePeriodicPrintouts(bool enable, uint8_t divider) {
|
||||||
|
periodicPrintout = enable;
|
||||||
|
debugDivider.setDivider(divider);
|
||||||
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#ifndef MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
#ifndef MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
||||||
#define MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
#define MISSION_DEVICES_MGMLIS3MDLHANDLER_H_
|
||||||
|
|
||||||
|
|
||||||
#include "devicedefinitions/MgmLIS3HandlerDefs.h"
|
#include "devicedefinitions/MgmLIS3HandlerDefs.h"
|
||||||
#include "events/subsystemIdRanges.h"
|
#include "events/subsystemIdRanges.h"
|
||||||
#include "fsfw/FSFW.h"
|
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||||
|
|
||||||
class PeriodicOperationDivider;
|
class PeriodicOperationDivider;
|
||||||
@ -30,6 +31,7 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
|||||||
uint32_t transitionDelay);
|
uint32_t transitionDelay);
|
||||||
virtual ~MgmLIS3MDLHandler();
|
virtual ~MgmLIS3MDLHandler();
|
||||||
|
|
||||||
|
void enablePeriodicPrintouts(bool enable, uint8_t divider);
|
||||||
/**
|
/**
|
||||||
* Set the absolute limit for the values on the axis in microtesla. The dataset values will
|
* Set the absolute limit for the values on the axis in microtesla. The dataset values will
|
||||||
* be marked as invalid if that limit is exceeded
|
* be marked as invalid if that limit is exceeded
|
||||||
@ -167,9 +169,8 @@ class MgmLIS3MDLHandler : public DeviceHandlerBase {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t prepareCtrlRegisterWrite();
|
ReturnValue_t prepareCtrlRegisterWrite();
|
||||||
|
|
||||||
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
bool periodicPrintout = false;
|
||||||
PeriodicOperationDivider *debugDivider;
|
PeriodicOperationDivider debugDivider = PeriodicOperationDivider(3);
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_MGMLIS3MDLHANDLER_H_ */
|
#endif /* MISSION_DEVICES_MGMLIS3MDLHANDLER_H_ */
|
||||||
|
@ -11,9 +11,6 @@ MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, object_id_t deviceCommu
|
|||||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||||
primaryDataset(this),
|
primaryDataset(this),
|
||||||
transitionDelay(transitionDelay) {
|
transitionDelay(transitionDelay) {
|
||||||
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
|
||||||
debugDivider = new PeriodicOperationDivider(10);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MgmRM3100Handler::~MgmRM3100Handler() {}
|
MgmRM3100Handler::~MgmRM3100Handler() {}
|
||||||
@ -337,23 +334,24 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
|
|||||||
float fieldStrengthY = fieldStrengthRawY * scaleFactorX;
|
float fieldStrengthY = fieldStrengthRawY * scaleFactorX;
|
||||||
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX;
|
float fieldStrengthZ = fieldStrengthRawZ * scaleFactorX;
|
||||||
|
|
||||||
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
if(periodicPrintout) {
|
||||||
if (debugDivider->checkAndIncrement()) {
|
if (debugDivider.checkAndIncrement()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "MgmRM3100Handler: Magnetic field strength in"
|
sif::info << "MgmRM3100Handler: Magnetic field strength in"
|
||||||
" microtesla:"
|
" microtesla:"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
sif::info << "X: " << fieldStrengthX << " uT" << std::endl;
|
sif::info << "X: " << fieldStrengthX << " uT" << std::endl;
|
||||||
sif::info << "Y: " << fieldStrengthY << " uT" << std::endl;
|
sif::info << "Y: " << fieldStrengthY << " uT" << std::endl;
|
||||||
sif::info << "Z: " << fieldStrengthZ << " uT" << std::endl;
|
sif::info << "Z: " << fieldStrengthZ << " uT" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printInfo("MgmRM3100Handler: Magnetic field strength in microtesla:\n");
|
sif::printInfo("MgmRM3100Handler: Magnetic field strength in microtesla:\n");
|
||||||
sif::printInfo("X: %f uT\n", fieldStrengthX);
|
sif::printInfo("X: %f uT\n", fieldStrengthX);
|
||||||
sif::printInfo("Y: %f uT\n", fieldStrengthY);
|
sif::printInfo("Y: %f uT\n", fieldStrengthY);
|
||||||
sif::printInfo("Z: %f uT\n", fieldStrengthZ);
|
sif::printInfo("Z: %f uT\n", fieldStrengthZ);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: Sanity check on values?
|
// TODO: Sanity check on values?
|
||||||
PoolReadGuard readGuard(&primaryDataset);
|
PoolReadGuard readGuard(&primaryDataset);
|
||||||
@ -365,3 +363,8 @@ ReturnValue_t MgmRM3100Handler::handleDataReadout(const uint8_t *packet) {
|
|||||||
}
|
}
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MgmRM3100Handler::enablePeriodicPrintouts(bool enable, uint8_t divider) {
|
||||||
|
periodicPrintout = enable;
|
||||||
|
debugDivider.setDivider(divider);
|
||||||
|
}
|
||||||
|
@ -2,12 +2,8 @@
|
|||||||
#define MISSION_DEVICES_MGMRM3100HANDLER_H_
|
#define MISSION_DEVICES_MGMRM3100HANDLER_H_
|
||||||
|
|
||||||
#include "devicedefinitions/MgmRM3100HandlerDefs.h"
|
#include "devicedefinitions/MgmRM3100HandlerDefs.h"
|
||||||
#include "fsfw/FSFW.h"
|
|
||||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||||
|
|
||||||
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
|
||||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Device Handler for the RM3100 geomagnetic magnetometer sensor
|
* @brief Device Handler for the RM3100 geomagnetic magnetometer sensor
|
||||||
@ -33,6 +29,7 @@ class MgmRM3100Handler : public DeviceHandlerBase {
|
|||||||
uint32_t transitionDelay);
|
uint32_t transitionDelay);
|
||||||
virtual ~MgmRM3100Handler();
|
virtual ~MgmRM3100Handler();
|
||||||
|
|
||||||
|
void enablePeriodicPrintouts(bool enable, uint8_t divider);
|
||||||
/**
|
/**
|
||||||
* Configure device handler to go to normal mode after startup immediately
|
* Configure device handler to go to normal mode after startup immediately
|
||||||
* @param enable
|
* @param enable
|
||||||
@ -98,9 +95,9 @@ class MgmRM3100Handler : public DeviceHandlerBase {
|
|||||||
size_t commandDataLen);
|
size_t commandDataLen);
|
||||||
|
|
||||||
ReturnValue_t handleDataReadout(const uint8_t *packet);
|
ReturnValue_t handleDataReadout(const uint8_t *packet);
|
||||||
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
|
||||||
PeriodicOperationDivider *debugDivider;
|
bool periodicPrintout = false;
|
||||||
#endif
|
PeriodicOperationDivider debugDivider = PeriodicOperationDivider(3);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_DEVICEHANDLING_MGMRM3100HANDLER_H_ */
|
#endif /* MISSION_DEVICEHANDLING_MGMRM3100HANDLER_H_ */
|
||||||
|
@ -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);
|
||||||
|
@ -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("..")
|
||||||
|
|
||||||
|
@ -62,16 +62,4 @@
|
|||||||
#define FSFW_HAL_I2C_WIRETAPPING 0
|
#define FSFW_HAL_I2C_WIRETAPPING 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FSFW_HAL_L3GD20_GYRO_DEBUG
|
|
||||||
#define FSFW_HAL_L3GD20_GYRO_DEBUG 0
|
|
||||||
#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */
|
|
||||||
|
|
||||||
#ifndef FSFW_HAL_RM3100_MGM_DEBUG
|
|
||||||
#define FSFW_HAL_RM3100_MGM_DEBUG 0
|
|
||||||
#endif /* FSFW_HAL_RM3100_MGM_DEBUG */
|
|
||||||
|
|
||||||
#ifndef FSFW_HAL_LIS3MDL_MGM_DEBUG
|
|
||||||
#define FSFW_HAL_LIS3MDL_MGM_DEBUG 0
|
|
||||||
#endif /* FSFW_HAL_LIS3MDL_MGM_DEBUG */
|
|
||||||
|
|
||||||
#endif /* FSFW_FSFW_H_ */
|
#endif /* FSFW_FSFW_H_ */
|
||||||
|
@ -12,7 +12,9 @@ object_id_t CFDPHandler::packetDestination = 0;
|
|||||||
|
|
||||||
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist)
|
||||||
: SystemObject(setObjectId) {
|
: SystemObject(setObjectId) {
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION);
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
|
requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION,
|
||||||
|
MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
distributor = dist;
|
distributor = dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@ ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
|
|||||||
submode(SUBMODE_NONE),
|
submode(SUBMODE_NONE),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
healthHelper(this, setObjectId) {
|
healthHelper(this, setObjectId) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth,
|
||||||
|
MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
ControllerBase::~ControllerBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@ -39,8 +39,9 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t device
|
|||||||
childTransitionDelay(5000),
|
childTransitionDelay(5000),
|
||||||
transitionSourceMode(_MODE_POWER_DOWN),
|
transitionSourceMode(_MODE_POWER_DOWN),
|
||||||
transitionSourceSubMode(SUBMODE_NONE) {
|
transitionSourceSubMode(SUBMODE_NONE) {
|
||||||
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
insertInCommandMap(RAW_COMMAND_ID);
|
insertInCommandMap(RAW_COMMAND_ID);
|
||||||
cookieInfo.state = COOKIE_UNUSED;
|
cookieInfo.state = COOKIE_UNUSED;
|
||||||
cookieInfo.pendingCommand = deviceCommandMap.end();
|
cookieInfo.pendingCommand = deviceCommandMap.end();
|
||||||
|
@ -8,7 +8,8 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue
|
|||||||
parentQueue(parentQueue),
|
parentQueue(parentQueue),
|
||||||
commandQueue(),
|
commandQueue(),
|
||||||
healthHelper(this, setObjectId) {
|
healthHelper(this, setObjectId) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(3);
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
HealthDevice::~HealthDevice() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@ -18,8 +18,10 @@ const LocalPool::LocalPoolConfig EventManager::poolConfig = {
|
|||||||
EventManager::EventManager(object_id_t setObjectId)
|
EventManager::EventManager(object_id_t setObjectId)
|
||||||
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
: SystemObject(setObjectId), factoryBackend(0, poolConfig, false, true) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE,
|
eventReportQueue = QueueFactory::instance()->createMessageQueue(MAX_EVENTS_PER_CYCLE,
|
||||||
EventMessage::EVENT_MESSAGE_SIZE);
|
EventMessage::EVENT_MESSAGE_SIZE,
|
||||||
|
&mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventManager::~EventManager() {
|
EventManager::~EventManager() {
|
||||||
@ -46,9 +48,20 @@ ReturnValue_t EventManager::performOperation(uint8_t opCode) {
|
|||||||
|
|
||||||
void EventManager::notifyListeners(EventMessage* message) {
|
void EventManager::notifyListeners(EventMessage* message) {
|
||||||
lockMutex();
|
lockMutex();
|
||||||
for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) {
|
for (auto& listener : listenerList) {
|
||||||
if (iter->second.match(message)) {
|
if (listener.second.match(message)) {
|
||||||
MessageQueueSenderIF::sendMessage(iter->first, message, message->getSender());
|
ReturnValue_t result =
|
||||||
|
MessageQueueSenderIF::sendMessage(listener.first, message, message->getSender());
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << std::hex << "EventManager::notifyListeners: MSG to 0x" << std::setfill('0')
|
||||||
|
<< std::setw(8) << listener.first << " failed with result 0x" << std::setw(4)
|
||||||
|
<< result << std::setfill(' ') << std::endl;
|
||||||
|
#else
|
||||||
|
sif::printError("Sending message to listener 0x%08x failed with result %04x\n",
|
||||||
|
listener.first, result);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unlockMutex();
|
unlockMutex();
|
||||||
@ -189,4 +202,19 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage* messag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventManager::printListeners() {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::info << "Event manager listener MQ IDs:" << std::setfill('0') << std::hex << std::endl;
|
||||||
|
for (auto& listener : listenerList) {
|
||||||
|
sif::info << "0x" << std::setw(8) << listener.first << std::endl;
|
||||||
|
}
|
||||||
|
sif::info << std::dec << std::setfill(' ');
|
||||||
|
#else
|
||||||
|
sif::printInfo("Event manager listener MQ IDs:\n");
|
||||||
|
for (auto& listener : listenerList) {
|
||||||
|
sif::printInfo("0x%08x\n", listener.first);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
#endif /* FSFW_OBJ_EVENT_TRANSLATION == 1 */
|
||||||
|
@ -42,6 +42,7 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
|
|||||||
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
|
||||||
bool reporterInverted = false);
|
bool reporterInverted = false);
|
||||||
ReturnValue_t performOperation(uint8_t opCode);
|
ReturnValue_t performOperation(uint8_t opCode);
|
||||||
|
void printListeners();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueIF* eventReportQueue = nullptr;
|
MessageQueueIF* eventReportQueue = nullptr;
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent,
|
||||||
uint8_t messageDepth, uint8_t parameterDomainBase)
|
uint8_t messageDepth, uint8_t parameterDomainBase)
|
||||||
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
: ownerId(owner), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) {
|
||||||
|
auto mqArgs = MqArgs(owner, static_cast<void*>(this));
|
||||||
eventQueue =
|
eventQueue =
|
||||||
QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE);
|
QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
FailureIsolationBase::~FailureIsolationBase() {
|
FailureIsolationBase::~FailureIsolationBase() {
|
||||||
|
@ -7,11 +7,12 @@
|
|||||||
|
|
||||||
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, uint32_t messageQueueDepth)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
commandQueue(QueueFactory::instance()->createMessageQueue(messageQueueDepth)),
|
|
||||||
poolManager(this, commandQueue),
|
poolManager(this, commandQueue),
|
||||||
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
|
||||||
internalErrorDataset(this) {
|
internalErrorDataset(this) {
|
||||||
mutex = MutexFactory::instance()->createMutex();
|
mutex = MutexFactory::instance()->createMutex();
|
||||||
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
InternalErrorReporter::~InternalErrorReporter() { MutexFactory::instance()->deleteMutex(mutex); }
|
||||||
@ -36,15 +37,14 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
|
|||||||
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
if ((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
sif::debug << "InternalErrorReporter::performOperation: Errors "
|
||||||
<< "occured!" << std::endl;
|
<< "occured: Queue | TM | Store : " << newQueueHits << " | " << newTmHits << " | "
|
||||||
sif::debug << "Queue errors: " << newQueueHits << std::endl;
|
<< newStoreHits << std::endl;
|
||||||
sif::debug << "TM errors: " << newTmHits << std::endl;
|
|
||||||
sif::debug << "Store errors: " << newStoreHits << std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printDebug("InternalErrorReporter::performOperation: Errors occured!\n");
|
sif::printDebug(
|
||||||
sif::printDebug("Queue errors: %lu\n", static_cast<unsigned int>(newQueueHits));
|
"InternalErrorReporter::performOperation: Errors occured: Queue | TM | Store: %lu | %lu "
|
||||||
sif::printDebug("TM errors: %lu\n", static_cast<unsigned int>(newTmHits));
|
"| %lu\n",
|
||||||
sif::printDebug("Store errors: %lu\n", static_cast<unsigned int>(newStoreHits));
|
static_cast<unsigned int>(newQueueHits), static_cast<unsigned int>(newTmHits),
|
||||||
|
static_cast<unsigned int>(newStoreHits));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "MessageQueueIF.h"
|
#include "MessageQueueIF.h"
|
||||||
#include "MessageQueueMessage.h"
|
#include "MessageQueueMessage.h"
|
||||||
|
#include "definitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates message queues.
|
* Creates message queues.
|
||||||
@ -22,7 +23,8 @@ class QueueFactory {
|
|||||||
static QueueFactory* instance();
|
static QueueFactory* instance();
|
||||||
|
|
||||||
MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3,
|
MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3,
|
||||||
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE);
|
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
|
||||||
|
MqArgs* args = nullptr);
|
||||||
|
|
||||||
void deleteMessageQueue(MessageQueueIF* queue);
|
void deleteMessageQueue(MessageQueueIF* queue);
|
||||||
|
|
||||||
|
12
src/fsfw/ipc/definitions.h
Normal file
12
src/fsfw/ipc/definitions.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef FSFW_SRC_FSFW_IPC_DEFINITIONS_H_
|
||||||
|
#define FSFW_SRC_FSFW_IPC_DEFINITIONS_H_
|
||||||
|
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||||
|
|
||||||
|
struct MqArgs {
|
||||||
|
MqArgs(){};
|
||||||
|
MqArgs(object_id_t objectId, void* args = nullptr) : objectId(objectId), args(args) {}
|
||||||
|
object_id_t objectId = 0;
|
||||||
|
void* args = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_SRC_FSFW_IPC_DEFINITIONS_H_ */
|
@ -4,7 +4,7 @@
|
|||||||
#include "fsfw/osal/freertos/QueueMapManager.h"
|
#include "fsfw/osal/freertos/QueueMapManager.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize)
|
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args)
|
||||||
: maxMessageSize(maxMessageSize) {
|
: maxMessageSize(maxMessageSize) {
|
||||||
handle = xQueueCreate(messageDepth, maxMessageSize);
|
handle = xQueueCreate(messageDepth, maxMessageSize);
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
#include "fsfw/ipc/MessageQueueMessageIF.h"
|
#include "fsfw/ipc/MessageQueueMessageIF.h"
|
||||||
|
#include "fsfw/ipc/definitions.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,7 +54,8 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
* This should be left default.
|
* This should be left default.
|
||||||
*/
|
*/
|
||||||
MessageQueue(size_t messageDepth = 3,
|
MessageQueue(size_t messageDepth = 3,
|
||||||
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE);
|
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
|
||||||
|
MqArgs* args = nullptr);
|
||||||
|
|
||||||
/** Copying message queues forbidden */
|
/** Copying message queues forbidden */
|
||||||
MessageQueue(const MessageQueue&) = delete;
|
MessageQueue(const MessageQueue&) = delete;
|
||||||
|
@ -22,8 +22,9 @@ QueueFactory::QueueFactory() {}
|
|||||||
|
|
||||||
QueueFactory::~QueueFactory() {}
|
QueueFactory::~QueueFactory() {}
|
||||||
|
|
||||||
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) {
|
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
|
||||||
return new MessageQueue(messageDepth, maxMessageSize);
|
MqArgs* args) {
|
||||||
|
return new MessageQueue(messageDepth, maxMessageSize, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }
|
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "fsfw/osal/host/QueueMapManager.h"
|
#include "fsfw/osal/host/QueueMapManager.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize)
|
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize, MqArgs* args)
|
||||||
: messageSize(maxMessageSize), messageDepth(messageDepth) {
|
: messageSize(maxMessageSize), messageDepth(messageDepth) {
|
||||||
queueLock = MutexFactory::instance()->createMutex();
|
queueLock = MutexFactory::instance()->createMutex();
|
||||||
auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId);
|
auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
#include "fsfw/ipc/MutexIF.h"
|
#include "fsfw/ipc/MutexIF.h"
|
||||||
|
#include "fsfw/ipc/definitions.h"
|
||||||
#include "fsfw/timemanager/Clock.h"
|
#include "fsfw/timemanager/Clock.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,7 +55,8 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
* This should be left default.
|
* This should be left default.
|
||||||
*/
|
*/
|
||||||
MessageQueue(size_t messageDepth = 3,
|
MessageQueue(size_t messageDepth = 3,
|
||||||
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE);
|
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
|
||||||
|
MqArgs* args = nullptr);
|
||||||
|
|
||||||
/** Copying message queues forbidden */
|
/** Copying message queues forbidden */
|
||||||
MessageQueue(const MessageQueue&) = delete;
|
MessageQueue(const MessageQueue&) = delete;
|
||||||
|
@ -27,12 +27,13 @@ QueueFactory::QueueFactory() {}
|
|||||||
|
|
||||||
QueueFactory::~QueueFactory() {}
|
QueueFactory::~QueueFactory() {}
|
||||||
|
|
||||||
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) {
|
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
|
||||||
|
MqArgs* args) {
|
||||||
// A thread-safe queue can be implemented by using a combination
|
// A thread-safe queue can be implemented by using a combination
|
||||||
// of std::queue and std::mutex. This uses dynamic memory allocation
|
// of std::queue and std::mutex. This uses dynamic memory allocation
|
||||||
// which could be alleviated by using a custom allocator, external library
|
// which could be alleviated by using a custom allocator, external library
|
||||||
// (etl::queue) or simply using std::queue, we're on a host machine anyway.
|
// (etl::queue) or simply using std::queue, we're on a host machine anyway.
|
||||||
return new MessageQueue(messageDepth, maxMessageSize);
|
return new MessageQueue(messageDepth, maxMessageSize, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }
|
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "fsfw/osal/linux/unixUtility.h"
|
#include "fsfw/osal/linux/unixUtility.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize)
|
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize, MqArgs* args)
|
||||||
: id(MessageQueueIF::NO_QUEUE),
|
: id(MessageQueueIF::NO_QUEUE),
|
||||||
lastPartner(MessageQueueIF::NO_QUEUE),
|
lastPartner(MessageQueueIF::NO_QUEUE),
|
||||||
defaultDestination(MessageQueueIF::NO_QUEUE),
|
defaultDestination(MessageQueueIF::NO_QUEUE),
|
||||||
@ -37,6 +37,9 @@ MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize)
|
|||||||
// Successful mq_open call
|
// Successful mq_open call
|
||||||
this->id = tempId;
|
this->id = tempId;
|
||||||
}
|
}
|
||||||
|
if (args != nullptr) {
|
||||||
|
this->mqArgs = *args;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueue::~MessageQueue() {
|
MessageQueue::~MessageQueue() {
|
||||||
@ -240,9 +243,9 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
bool ignoreFault) {
|
bool ignoreFault) {
|
||||||
if (message == nullptr) {
|
if (message == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is nullptr!" << std::endl;
|
sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is nullptr" << std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printError("MessageQueue::sendMessageFromMessageQueue: Message is nullptr!\n");
|
sif::printError("MessageQueue::sendMessageFromMessageQueue: Message is nullptr\n");
|
||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
@ -256,7 +259,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
|
|||||||
if (!ignoreFault) {
|
if (!ignoreFault) {
|
||||||
InternalErrorReporterIF* internalErrorReporter =
|
InternalErrorReporterIF* internalErrorReporter =
|
||||||
ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
|
ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
|
||||||
if (internalErrorReporter != NULL) {
|
if (internalErrorReporter != nullptr) {
|
||||||
internalErrorReporter->queueMessageNotSent();
|
internalErrorReporter->queueMessageNotSent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
|
#include "fsfw/ipc/definitions.h"
|
||||||
/**
|
/**
|
||||||
* @brief This class manages sending and receiving of message queue messages.
|
* @brief This class manages sending and receiving of message queue messages.
|
||||||
*
|
*
|
||||||
@ -42,7 +43,8 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
* This should be left default.
|
* This should be left default.
|
||||||
*/
|
*/
|
||||||
MessageQueue(uint32_t messageDepth = 3,
|
MessageQueue(uint32_t messageDepth = 3,
|
||||||
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE);
|
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE,
|
||||||
|
MqArgs* args = nullptr);
|
||||||
/**
|
/**
|
||||||
* @brief The destructor deletes the formerly created message queue.
|
* @brief The destructor deletes the formerly created message queue.
|
||||||
* @details This is accomplished by using the delete call provided by the operating system.
|
* @details This is accomplished by using the delete call provided by the operating system.
|
||||||
@ -184,6 +186,8 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
*/
|
*/
|
||||||
char name[16];
|
char name[16];
|
||||||
|
|
||||||
|
MqArgs mqArgs = {};
|
||||||
|
|
||||||
static uint16_t queueCounter;
|
static uint16_t queueCounter;
|
||||||
const size_t maxMessageSize;
|
const size_t maxMessageSize;
|
||||||
|
|
||||||
|
@ -28,8 +28,9 @@ QueueFactory::QueueFactory() {}
|
|||||||
|
|
||||||
QueueFactory::~QueueFactory() {}
|
QueueFactory::~QueueFactory() {}
|
||||||
|
|
||||||
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) {
|
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
|
||||||
return new MessageQueue(messageDepth, maxMessageSize);
|
MqArgs* args) {
|
||||||
|
return new MessageQueue(messageDepth, maxMessageSize, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }
|
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "fsfw/osal/rtems/RtemsBasic.h"
|
#include "fsfw/osal/rtems/RtemsBasic.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size)
|
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size, MqArgs* args)
|
||||||
: id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) {
|
: id(0), lastPartner(0), defaultDestination(NO_QUEUE), internalErrorReporter(nullptr) {
|
||||||
rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
|
rtems_name name = ('Q' << 24) + (queueCounter++ << 8);
|
||||||
rtems_status_code status =
|
rtems_status_code status =
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
|
#include "fsfw/ipc/definitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class manages sending and receiving of message queue messages.
|
* @brief This class manages sending and receiving of message queue messages.
|
||||||
@ -34,7 +35,8 @@ class MessageQueue : public MessageQueueIF {
|
|||||||
* This should be left default.
|
* This should be left default.
|
||||||
*/
|
*/
|
||||||
MessageQueue(size_t message_depth = 3,
|
MessageQueue(size_t message_depth = 3,
|
||||||
size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE);
|
size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE,
|
||||||
|
MqArgs* args = nullptr);
|
||||||
/**
|
/**
|
||||||
* @brief The destructor deletes the formerly created message queue.
|
* @brief The destructor deletes the formerly created message queue.
|
||||||
* @details This is accomplished by using the delete call provided by the operating system.
|
* @details This is accomplished by using the delete call provided by the operating system.
|
||||||
|
@ -49,8 +49,9 @@ QueueFactory::QueueFactory() {}
|
|||||||
|
|
||||||
QueueFactory::~QueueFactory() {}
|
QueueFactory::~QueueFactory() {}
|
||||||
|
|
||||||
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) {
|
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize,
|
||||||
return new MessageQueue(messageDepth, maxMessageSize);
|
MqArgs* args) {
|
||||||
|
return new MessageQueue(messageDepth, maxMessageSize, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }
|
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { delete queue; }
|
||||||
|
@ -15,7 +15,8 @@ PowerSensor::PowerSensor(object_id_t objectId, sid_t setId, VariableIds ids, Def
|
|||||||
limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh),
|
limits.currentMin, limits.currentMax, events.currentLow, events.currentHigh),
|
||||||
voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount,
|
voltageLimit(objectId, MODULE_ID_VOLTAGE, ids.pidVoltage, confirmationCount,
|
||||||
limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) {
|
limits.voltageMin, limits.voltageMax, events.voltageLow, events.voltageHigh) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue();
|
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
PowerSensor::~PowerSensor() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
@ -16,7 +16,8 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj
|
|||||||
apid(apid),
|
apid(apid),
|
||||||
serviceId(serviceId),
|
serviceId(serviceId),
|
||||||
targetDestination(targetDestination) {
|
targetDestination(targetDestination) {
|
||||||
tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||||
|
tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Service1TelecommandVerification::~Service1TelecommandVerification() {
|
Service1TelecommandVerification::~Service1TelecommandVerification() {
|
||||||
|
@ -12,7 +12,9 @@ Service5EventReporting::Service5EventReporting(object_id_t objectId, uint16_t ap
|
|||||||
uint32_t messageQueueDepth)
|
uint32_t messageQueueDepth)
|
||||||
: PusServiceBase(objectId, apid, serviceId),
|
: PusServiceBase(objectId, apid, serviceId),
|
||||||
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
maxNumberReportsPerCycle(maxNumberReportsPerCycle) {
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth);
|
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||||
|
eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
|
sif::info << eventQueue->getId() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Service5EventReporting::~Service5EventReporting() {
|
Service5EventReporting::~Service5EventReporting() {
|
||||||
|
@ -8,11 +8,13 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, Mode_t
|
|||||||
uint16_t commandQueueDepth)
|
uint16_t commandQueueDepth)
|
||||||
: SystemObject(setObjectId),
|
: SystemObject(setObjectId),
|
||||||
mode(initialMode),
|
mode(initialMode),
|
||||||
commandQueue(QueueFactory::instance()->createMessageQueue(commandQueueDepth,
|
|
||||||
CommandMessage::MAX_MESSAGE_SIZE)),
|
|
||||||
healthHelper(this, setObjectId),
|
healthHelper(this, setObjectId),
|
||||||
modeHelper(this),
|
modeHelper(this),
|
||||||
parentId(parent) {}
|
parentId(parent) {
|
||||||
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth,
|
||||||
|
CommandMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
|
}
|
||||||
|
|
||||||
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
SubsystemBase::~SubsystemBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); }
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
|
|
||||||
TcDistributor::TcDistributor(object_id_t objectId) : SystemObject(objectId) {
|
TcDistributor::TcDistributor(object_id_t objectId) : SystemObject(objectId) {
|
||||||
tcQueue = QueueFactory::instance()->createMessageQueue(DISTRIBUTER_MAX_PACKETS);
|
auto mqArgs = MqArgs(objectId);
|
||||||
|
tcQueue = QueueFactory::instance()->createMessageQueue(DISTRIBUTER_MAX_PACKETS, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
TcDistributor::~TcDistributor() { QueueFactory::instance()->deleteMessageQueue(tcQueue); }
|
TcDistributor::~TcDistributor() { QueueFactory::instance()->deleteMessageQueue(tcQueue); }
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid,
|
AbstractTemperatureSensor::AbstractTemperatureSensor(object_id_t setObjectid,
|
||||||
ThermalModuleIF *thermalModule)
|
ThermalModuleIF *thermalModule)
|
||||||
: SystemObject(setObjectid),
|
: SystemObject(setObjectid),
|
||||||
commandQueue(NULL),
|
|
||||||
healthHelper(this, setObjectid),
|
healthHelper(this, setObjectid),
|
||||||
parameterHelper(this) {
|
parameterHelper(this) {
|
||||||
if (thermalModule != NULL) {
|
if (thermalModule != nullptr) {
|
||||||
thermalModule->registerSensor(this);
|
thermalModule->registerSensor(this);
|
||||||
}
|
}
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue();
|
auto mqArgs = MqArgs(setObjectid, static_cast<void*>(this));
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractTemperatureSensor::~AbstractTemperatureSensor() {
|
AbstractTemperatureSensor::~AbstractTemperatureSensor() {
|
||||||
|
@ -51,7 +51,7 @@ class AbstractTemperatureSensor : public HasHealthIF,
|
|||||||
HasHealthIF::HealthState getHealth();
|
HasHealthIF::HealthState getHealth();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueIF* commandQueue;
|
MessageQueueIF* commandQueue = nullptr;
|
||||||
HealthHelper healthHelper;
|
HealthHelper healthHelper;
|
||||||
ParameterHelper parameterHelper;
|
ParameterHelper parameterHelper;
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ Heater::Heater(uint32_t objectId, uint8_t switch0, uint8_t switch1)
|
|||||||
switch1(switch1),
|
switch1(switch1),
|
||||||
heaterOnCountdown(10800000) /*about two orbits*/,
|
heaterOnCountdown(10800000) /*about two orbits*/,
|
||||||
parameterHelper(this) {
|
parameterHelper(this) {
|
||||||
eventQueue = QueueFactory::instance()->createMessageQueue();
|
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||||
|
eventQueue = QueueFactory::instance()->createMessageQueue(3, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Heater::~Heater() { QueueFactory::instance()->deleteMessageQueue(eventQueue); }
|
Heater::~Heater() { QueueFactory::instance()->deleteMessageQueue(eventQueue); }
|
||||||
|
@ -20,8 +20,10 @@ CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t a
|
|||||||
service(service),
|
service(service),
|
||||||
timeoutSeconds(commandTimeoutSeconds),
|
timeoutSeconds(commandTimeoutSeconds),
|
||||||
commandMap(numberOfParallelCommands) {
|
commandMap(numberOfParallelCommands) {
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth);
|
size_t mqSz = MessageQueueMessage::MAX_MESSAGE_SIZE;
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth, mqSz, &mqArgs);
|
||||||
|
requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth, mqSz, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandingServiceBase::setPacketSource(object_id_t packetSource) {
|
void CommandingServiceBase::setPacketSource(object_id_t packetSource) {
|
||||||
|
@ -13,7 +13,8 @@ object_id_t PusServiceBase::packetDestination = 0;
|
|||||||
|
|
||||||
PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId)
|
PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId)
|
||||||
: SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) {
|
: SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) {
|
||||||
requestQueue = QueueFactory::instance()->createMessageQueue(PUS_SERVICE_MAX_RECEPTION);
|
auto mqArgs = MqArgs(setObjectId, static_cast<void*>(this));
|
||||||
|
requestQueue = QueueFactory::instance()->createMessageQueue(PUS_SERVICE_MAX_RECEPTION, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
PusServiceBase::~PusServiceBase() { QueueFactory::instance()->deleteMessageQueue(requestQueue); }
|
PusServiceBase::~PusServiceBase() { QueueFactory::instance()->deleteMessageQueue(requestQueue); }
|
||||||
|
@ -15,7 +15,8 @@ TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination, object_i
|
|||||||
tcDestination(tcDestination)
|
tcDestination(tcDestination)
|
||||||
|
|
||||||
{
|
{
|
||||||
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH);
|
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||||
|
tmTcReceptionQueue = QueueFactory::instance()->createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
|
TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); }
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
|
||||||
bool TestTask::oneShotAction = true;
|
|
||||||
MutexIF* TestTask::testLock = nullptr;
|
MutexIF* TestTask::testLock = nullptr;
|
||||||
|
|
||||||
TestTask::TestTask(object_id_t objectId) : SystemObject(objectId), testMode(testModes::A) {
|
TestTask::TestTask(object_id_t objectId) : SystemObject(objectId), testMode(testModes::A) {
|
||||||
|
@ -29,7 +29,7 @@ class TestTask : public SystemObject, public ExecutableObjectIF, public HasRetur
|
|||||||
bool testFlag = false;
|
bool testFlag = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool oneShotAction;
|
bool oneShotAction = true;
|
||||||
static MutexIF* testLock;
|
static MutexIF* testLock;
|
||||||
StorageManagerIF* IPCStore;
|
StorageManagerIF* IPCStore;
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user