Compare commits
60 Commits
c20bf31d5d
...
v4.0.0
Author | SHA1 | Date | |
---|---|---|---|
a274d6598e | |||
c3d78120ea | |||
f24de22e9b | |||
918783774f | |||
6744a55b9b | |||
a612fb446c | |||
a5adeb333c | |||
7788cada54 | |||
074ef29b86 | |||
d4f059d639 | |||
22bc300902 | |||
0d38ac62d8 | |||
d81257a91c | |||
d53c7e1190 | |||
e312cd094a | |||
9e958e752e | |||
3bcd71598d | |||
2602d4fed1 | |||
805538ec6e | |||
120750f22a | |||
9897f51307 | |||
4f87e24f60 | |||
2dcf896cca | |||
cdf2a90f90 | |||
b25555a533 | |||
bc0100ee08 | |||
c6d152a01d | |||
f4f1174849 | |||
9df8722c10 | |||
7208139630 | |||
54f3d7bd2d | |||
7a83289b3d | |||
136524424f | |||
793b97f651 | |||
2e4cd80556 | |||
a4f57a38fa | |||
6dc34fc1f0 | |||
9e6948a8d7 | |||
9b17b282c6 | |||
5f48d77c64 | |||
8ab8c57f9c | |||
c7b9df5e40 | |||
7b8019c621 | |||
baddbf7340 | |||
80a610141a | |||
f93c173715 | |||
620841a9e5 | |||
bd29688307 | |||
43b7a314b6 | |||
1b41153ee6 | |||
f08d291e3e | |||
06ffe27fcc | |||
e9b0951a95 | |||
348274c145 | |||
40329a33b2 | |||
2d52042ed6 | |||
79936a3335 | |||
51add8a8ad | |||
ad5bb4c694 | |||
2a268e14d1 |
@ -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
|
||||
|
||||
@ -27,7 +237,7 @@
|
||||
|
||||
- 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
|
||||
|
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(FSFW_VERSION 2)
|
||||
set(FSFW_VERSION 4)
|
||||
set(FSFW_SUBVERSION 0)
|
||||
set(FSFW_REVISION 0)
|
||||
|
||||
@ -60,6 +60,8 @@ if(FSFW_BUILD_UNITTESTS)
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(Catch2)
|
||||
#fixes regression -preview4, to be confirmed in later releases
|
||||
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
|
||||
endif()
|
||||
|
||||
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.
|
||||
|
||||
## 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
|
||||
|
||||
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
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
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'
|
||||
}
|
||||
agent {
|
||||
dockerfile {
|
||||
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
|
||||
}
|
||||
docker { image 'fsfw-ci:d1'}
|
||||
}
|
||||
stages {
|
||||
stage('Clean') {
|
||||
|
@ -1,3 +1,110 @@
|
||||
.. _dhb-prim-doc:
|
||||
|
||||
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
|
||||
instructions provided in `this blogpost <https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/>`_. You can set up a
|
||||
documentation build system using the following commands
|
||||
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.
|
||||
|
||||
.. 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
|
||||
|
||||
@ -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
|
||||
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
|
||||
.. _`Catch2 library`: https://github.com/catchorg/Catch2
|
||||
.. _`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``.
|
||||
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
|
||||
related [documentation section](doc/README-devicehandlers.md#top).
|
||||
related :ref:`documentation section <dhb-prim-doc>`.
|
||||
|
||||
Modes and Health
|
||||
--------------------
|
||||
|
@ -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,
|
||||
# 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_LIBGPIOD "Target implements libgpiod" ON)
|
||||
|
||||
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)
|
||||
|
@ -11,7 +11,7 @@ namespace gpio {
|
||||
|
||||
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 };
|
||||
|
||||
@ -20,7 +20,7 @@ enum class GpioTypes {
|
||||
GPIO_REGULAR_BY_CHIP,
|
||||
GPIO_REGULAR_BY_LABEL,
|
||||
GPIO_REGULAR_BY_LINE_NAME,
|
||||
TYPE_CALLBACK
|
||||
CALLBACK
|
||||
};
|
||||
|
||||
static constexpr gpioId_t NO_GPIO = -1;
|
||||
@ -57,7 +57,7 @@ class GpioBase {
|
||||
// Can be used to cast GpioBase to a concrete child implementation
|
||||
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
|
||||
std::string consumer;
|
||||
gpio::Direction direction = gpio::Direction::DIR_IN;
|
||||
gpio::Direction direction = gpio::Direction::IN;
|
||||
gpio::Levels initValue = gpio::Levels::NONE;
|
||||
};
|
||||
|
||||
@ -79,8 +79,8 @@ class GpiodRegularBase : public GpioBase {
|
||||
class GpiodRegularByChip : public GpiodRegularBase {
|
||||
public:
|
||||
GpiodRegularByChip()
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, std::string(),
|
||||
gpio::Direction::DIR_IN, gpio::LOW, 0) {}
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, std::string(), gpio::Direction::IN,
|
||||
gpio::LOW, 0) {}
|
||||
|
||||
GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_,
|
||||
gpio::Direction direction_, gpio::Levels initValue_)
|
||||
@ -89,7 +89,7 @@ class GpiodRegularByChip : public GpiodRegularBase {
|
||||
chipname(chipname_) {}
|
||||
|
||||
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_),
|
||||
chipname(chipname_) {}
|
||||
|
||||
@ -105,7 +105,7 @@ class GpiodRegularByLabel : public GpiodRegularBase {
|
||||
label(label_) {}
|
||||
|
||||
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_),
|
||||
label(label_) {}
|
||||
|
||||
@ -126,8 +126,8 @@ class GpiodRegularByLineName : public GpiodRegularBase {
|
||||
lineName(lineName_) {}
|
||||
|
||||
GpiodRegularByLineName(std::string lineName_, std::string consumer_)
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_,
|
||||
gpio::Direction::DIR_IN, gpio::LOW),
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, gpio::Direction::IN,
|
||||
gpio::LOW),
|
||||
lineName(lineName_) {}
|
||||
|
||||
std::string lineName;
|
||||
@ -137,7 +137,7 @@ class GpioCallback : public GpioBase {
|
||||
public:
|
||||
GpioCallback(std::string consumer, gpio::Direction direction_, gpio::Levels initValue_,
|
||||
gpio::gpio_cb_t callback, void* callbackArgs)
|
||||
: GpioBase(gpio::GpioTypes::TYPE_CALLBACK, consumer, direction_, initValue_),
|
||||
: GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_),
|
||||
callback(callback),
|
||||
callbackArgs(callbackArgs) {}
|
||||
|
||||
|
@ -10,7 +10,7 @@ GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceC
|
||||
transitionDelayMs(transitionDelayMs),
|
||||
dataset(this) {
|
||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
||||
debugDivider = new PeriodicOperationDivider(10);
|
||||
debugDivider = new PeriodicOperationDivider(3);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCom
|
||||
dataset(this),
|
||||
transitionDelay(transitionDelay) {
|
||||
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
||||
debugDivider = new PeriodicOperationDivider(10);
|
||||
debugDivider = new PeriodicOperationDivider(3);
|
||||
#endif
|
||||
// Set to default values right away
|
||||
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
|
||||
@ -264,7 +264,7 @@ ReturnValue_t MgmLIS3MDLHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
int16_t mgmMeasurementRawZ =
|
||||
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 *
|
||||
MGMLIS3MDL::GAUSS_TO_MICROTESLA_FACTOR;
|
||||
float mgmY = static_cast<float>(mgmMeasurementRawY) * sensitivityFactor *
|
||||
@ -462,9 +462,7 @@ ReturnValue_t MgmLIS3MDLHandler::prepareCtrlRegisterWrite() {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void MgmLIS3MDLHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
|
||||
}
|
||||
void MgmLIS3MDLHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {}
|
||||
|
||||
uint32_t MgmLIS3MDLHandler::getTransitionDelayMs(Mode_t from, Mode_t to) { return transitionDelay; }
|
||||
|
||||
|
@ -12,7 +12,7 @@ MgmRM3100Handler::MgmRM3100Handler(object_id_t objectId, object_id_t deviceCommu
|
||||
primaryDataset(this),
|
||||
transitionDelay(transitionDelay) {
|
||||
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
||||
debugDivider = new PeriodicOperationDivider(10);
|
||||
debugDivider = new PeriodicOperationDivider(3);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,7 @@ target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
)
|
||||
|
||||
if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
|
||||
if(FSFW_HAL_LINUX_ADD_LIBGPIOD)
|
||||
add_subdirectory(gpio)
|
||||
endif()
|
||||
add_subdirectory(spi)
|
||||
add_subdirectory(i2c)
|
||||
add_subdirectory(uart)
|
||||
|
@ -74,7 +74,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||
configureGpioByLineName(gpioConfig.first, *regularGpio);
|
||||
break;
|
||||
}
|
||||
case (gpio::GpioTypes::TYPE_CALLBACK): {
|
||||
case (gpio::GpioTypes::CALLBACK): {
|
||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
||||
if (gpioCallback->callback == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
@ -161,11 +161,11 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, struct gpiod
|
||||
consumer = regularGpio.consumer;
|
||||
/* Configure direction and add a description to the GPIO */
|
||||
switch (direction) {
|
||||
case (gpio::DIR_OUT): {
|
||||
case (gpio::OUT): {
|
||||
result = gpiod_line_request_output(lineHandle, consumer.c_str(), regularGpio.initValue);
|
||||
break;
|
||||
}
|
||||
case (gpio::DIR_IN): {
|
||||
case (gpio::IN): {
|
||||
result = gpiod_line_request_input(lineHandle, consumer.c_str());
|
||||
break;
|
||||
}
|
||||
@ -326,7 +326,7 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (gpio::GpioTypes::TYPE_CALLBACK): {
|
||||
case (gpio::GpioTypes::CALLBACK): {
|
||||
auto callbackGpio = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
||||
if (callbackGpio == nullptr) {
|
||||
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_LABEL):
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (gpio::GpioTypes::TYPE_CALLBACK): {
|
||||
if (gpioType != gpio::GpioTypes::TYPE_CALLBACK) {
|
||||
case (gpio::GpioTypes::CALLBACK): {
|
||||
if (gpioType != gpio::GpioTypes::CALLBACK) {
|
||||
eraseDuplicateDifferentType = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,4 @@
|
||||
#include "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 "fsfw_hal/linux/i2c/I2cComIF.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -17,6 +8,11 @@
|
||||
|
||||
#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() {}
|
||||
@ -116,11 +112,6 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, s
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
@ -185,11 +176,6 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLe
|
||||
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;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
ReturnValue_t gpio::createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin,
|
||||
std::string consumer, gpio::Direction direction,
|
||||
gpio::Levels initValue) {
|
||||
int initValue) {
|
||||
if (cookie == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
@ -21,8 +21,7 @@ namespace gpio {
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin,
|
||||
std::string consumer, gpio::Direction direction,
|
||||
gpio::Levels initValue);
|
||||
std::string consumer, gpio::Direction direction, int initValue);
|
||||
} // namespace gpio
|
||||
|
||||
#endif /* BSP_RPI_GPIO_GPIORPI_H_ */
|
||||
|
@ -269,50 +269,6 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki
|
||||
cfsetispeed(options, B460800);
|
||||
cfsetospeed(options, B460800);
|
||||
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:
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "UartCookie.h"
|
||||
#include "fsfw_hal/linux/uart/UartCookie.h"
|
||||
|
||||
#include <fsfw/serviceinterface.h>
|
||||
|
||||
|
@ -22,7 +22,7 @@ ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permiss
|
||||
int fd = open(uioFile.c_str(), O_RDWR);
|
||||
if (fd < 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
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
@ -36,8 +36,8 @@ ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permiss
|
||||
|
||||
if (*address == MAP_FAILED) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "UioMapper::getMappedAdress: Failed to map physical address of uio device "
|
||||
<< uioFile.c_str() << " and map" << static_cast<int>(mapNum) << std::endl;
|
||||
sif::error << "UioMapper::getMappedAdress: Failed to map physical address of uio device "
|
||||
<< uioFile.c_str() << " and map" << static_cast<int>(mapNum) << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
@ -52,7 +52,7 @@ ReturnValue_t UioMapper::getMapSize(size_t* size) {
|
||||
fp = fopen(namestream.str().c_str(), "r");
|
||||
if (fp == nullptr) {
|
||||
#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
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
@ -60,11 +60,12 @@ ReturnValue_t UioMapper::getMapSize(size_t* size) {
|
||||
int items = fscanf(fp, "%s", hexstring);
|
||||
if (items != 1) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "UioMapper::getMapSize: Failed with error code " << errno
|
||||
<< " to read size "
|
||||
"string from file "
|
||||
<< namestream.str() << std::endl;
|
||||
sif::error << "UioMapper::getMapSize: Failed with error code " << errno
|
||||
<< " to read size "
|
||||
"string from file "
|
||||
<< namestream.str() << std::endl;
|
||||
#endif
|
||||
fclose(fp);
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
uint32_t sizeTmp = 0;
|
||||
@ -74,9 +75,10 @@ ReturnValue_t UioMapper::getMapSize(size_t* size) {
|
||||
}
|
||||
if (items != 1) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "UioMapper::getMapSize: Failed with error code " << errno << "to convert "
|
||||
<< "size of map" << mapNum << " to integer" << std::endl;
|
||||
sif::error << "UioMapper::getMapSize: Failed with error code " << errno << "to convert "
|
||||
<< "size of map" << mapNum << " to integer" << std::endl;
|
||||
#endif
|
||||
fclose(fp);
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
fclose(fp);
|
||||
|
@ -143,7 +143,10 @@ def handle_tests_type(args, build_dir_list: list):
|
||||
if which("valgrind") is None:
|
||||
print("Please install valgrind first")
|
||||
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.chdir("..")
|
||||
|
||||
|
@ -57,11 +57,6 @@
|
||||
#define FSFW_HAL_SPI_WIRETAPPING 0
|
||||
#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
|
||||
#define FSFW_HAL_L3GD20_GYRO_DEBUG 0
|
||||
#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef FSFW_CONTROLLER_CONTROLLERBASE_H_
|
||||
#define FSFW_CONTROLLER_CONTROLLERBASE_H_
|
||||
|
||||
#include "fsfw/datapool/HkSwitchHelper.h"
|
||||
#include "fsfw/health/HasHealthIF.h"
|
||||
#include "fsfw/health/HealthHelper.h"
|
||||
#include "fsfw/modes/HasModesIF.h"
|
||||
|
@ -1,4 +1,6 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
PoolDataSetBase.cpp
|
||||
PoolEntry.cpp
|
||||
target_sources(${LIB_FSFW_NAME}
|
||||
PRIVATE
|
||||
HkSwitchHelper.cpp
|
||||
PoolDataSetBase.cpp
|
||||
PoolEntry.cpp
|
||||
)
|
67
src/fsfw/datapool/HkSwitchHelper.cpp
Normal file
67
src/fsfw/datapool/HkSwitchHelper.cpp
Normal 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; }
|
44
src/fsfw/datapool/HkSwitchHelper.h
Normal file
44
src/fsfw/datapool/HkSwitchHelper.h
Normal 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_ */
|
@ -47,14 +47,13 @@ LocalPoolObjectBase::LocalPoolObjectBase(object_id_t poolOwner, lp_id_t poolId,
|
||||
HasLocalDataPoolIF* hkOwner = ObjectManager::instance()->get<HasLocalDataPoolIF>(poolOwner);
|
||||
if (hkOwner == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "LocalPoolVariable: The supplied pool owner 0x" << std::hex << poolOwner
|
||||
<< std::dec << " did not implement the correct interface "
|
||||
<< "HasLocalDataPoolIF" << std::endl;
|
||||
sif::error << "LocalPoolVariable: The supplied pool owner did not implement the correct "
|
||||
"interface HasLocalDataPoolIF!"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printError(
|
||||
"LocalPoolVariable: The supplied pool owner 0x%08x did not implement the correct "
|
||||
"interface HasLocalDataPoolIF\n",
|
||||
poolOwner);
|
||||
"LocalPoolVariable: The supplied pool owner did not implement the correct "
|
||||
"interface HasLocalDataPoolIF!\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class StaticLocalDataSet : public LocalPoolDataSetBase {
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList = {};
|
||||
std::array<PoolVariableIF*, NUM_VARIABLES> poolVarList;
|
||||
};
|
||||
|
||||
#endif /* FSFW_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */
|
||||
|
@ -29,7 +29,6 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event)
|
||||
switch (event->getEvent()) {
|
||||
case HasModesIF::MODE_TRANSITION_FAILED:
|
||||
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
||||
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
|
||||
// We'll try a recovery as long as defined in MAX_REBOOT.
|
||||
// Might cause some AssemblyBase cycles, so keep number low.
|
||||
handleRecovery(event->getEvent());
|
||||
|
@ -109,7 +109,6 @@ class DeviceHandlerIF {
|
||||
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_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;
|
||||
|
||||
|
@ -14,12 +14,13 @@ class FailureIsolationBase : public HasReturnvaluesIF,
|
||||
public HasParametersIF {
|
||||
public:
|
||||
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 = MAKE_EVENT(1, severity::INFO);
|
||||
//! FDIR tries to restart device. Par1: event that caused recovery.
|
||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, severity::MEDIUM);
|
||||
//! FDIR turns off device. Par1: event that caused recovery.
|
||||
static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, severity::MEDIUM);
|
||||
static const Event FDIR_CHANGED_STATE =
|
||||
MAKE_EVENT(1, severity::INFO); //!< FDIR has an internal state, which changed from par2
|
||||
//!< (oldState) to par1 (newState).
|
||||
static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(
|
||||
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); //!< FDIR turns off device. Par1: event that caused recovery.
|
||||
|
||||
FailureIsolationBase(object_id_t owner, object_id_t parent = objects::NO_OBJECT,
|
||||
uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0);
|
||||
|
@ -117,7 +117,7 @@ uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t starti
|
||||
// {
|
||||
// if (xor_out[i] == true)
|
||||
// crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before
|
||||
// Final XOR
|
||||
//Final XOR
|
||||
// }
|
||||
//
|
||||
// crc_value = 0;// for debug mode
|
||||
|
@ -23,15 +23,19 @@ class HasHealthIF {
|
||||
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_PROBLEMS = MAKE_EVENT(8, severity::LOW);
|
||||
//! Assembly overwrites health information of children to keep satellite alive.
|
||||
static const Event OVERWRITING_HEALTH = MAKE_EVENT(9, severity::LOW);
|
||||
//! Someone starts a recovery of a component (typically power-cycle). No parameters.
|
||||
static const Event TRYING_RECOVERY = MAKE_EVENT(10, severity::MEDIUM);
|
||||
//! Recovery is ongoing. Comes twice during recovery.
|
||||
//! P1: 0 for the first, 1 for the second event. P2: 0
|
||||
static const Event RECOVERY_STEP = MAKE_EVENT(11, severity::MEDIUM);
|
||||
//! Recovery was completed. Not necessarily successful. No parameters.
|
||||
static const Event RECOVERY_DONE = MAKE_EVENT(12, severity::MEDIUM);
|
||||
static const Event OVERWRITING_HEALTH =
|
||||
MAKE_EVENT(9, severity::LOW); //!< Assembly overwrites health information of children to keep
|
||||
//!< satellite alive.
|
||||
static const Event TRYING_RECOVERY =
|
||||
MAKE_EVENT(10, severity::MEDIUM); //!< Someone starts a recovery of a component (typically
|
||||
//!< power-cycle). No parameters.
|
||||
static const Event RECOVERY_STEP =
|
||||
MAKE_EVENT(11, severity::MEDIUM); //!< Recovery is ongoing. Comes twice during recovery. P1:
|
||||
//!< 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 MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
@ -19,29 +19,32 @@ class HasModesIF {
|
||||
static const ReturnValue_t INVALID_SUBMODE = MAKE_RETURN_CODE(0x04);
|
||||
|
||||
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 = MAKE_EVENT(0, severity::INFO);
|
||||
//! An Object announces its mode; parameter1 is mode, parameter2 is submode
|
||||
static const Event MODE_INFO = MAKE_EVENT(1, severity::INFO);
|
||||
static const Event CHANGING_MODE =
|
||||
MAKE_EVENT(0, severity::INFO); //!< An object announces changing the mode. p1: target mode.
|
||||
//!< p2: target submode
|
||||
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 MODE_TRANSITION_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||
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 = MAKE_EVENT(5, severity::LOW);
|
||||
//! The mode is changed, but for some reason, the change is forced, i.e. EXTERNAL_CONTROL ignored.
|
||||
//! p1: target mode. p2: target submode
|
||||
static const Event FORCING_MODE = MAKE_EVENT(6, severity::MEDIUM);
|
||||
//! A mode command was rejected by the called object. Par1: called object id, Par2: return code.
|
||||
static const Event MODE_CMD_REJECTED = MAKE_EVENT(7, severity::LOW);
|
||||
static const Event OBJECT_IN_INVALID_MODE =
|
||||
MAKE_EVENT(5, severity::LOW); //!< Indicates a bug or configuration failure: Object is in a
|
||||
//!< mode it should never be in.
|
||||
static const Event FORCING_MODE = MAKE_EVENT(
|
||||
6, severity::MEDIUM); //!< The mode is changed, but for some reason, the change is forced,
|
||||
//!< i.e. EXTERNAL_CONTROL ignored. p1: target mode. p2: target submode
|
||||
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
|
||||
//! sent by the device handler itself, but direct commands van be commanded and will be
|
||||
//! interpreted
|
||||
static const Mode_t MODE_ON = 1;
|
||||
//! 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;
|
||||
//! To avoid checks against magic number "0".
|
||||
static const Submode_t SUBMODE_NONE = 0;
|
||||
static const Mode_t MODE_ON =
|
||||
1; //!< The device is powered and ready to perform operations. In this mode, no commands are
|
||||
//!< sent by the device handler itself, but direct commands van be commanded and will be
|
||||
//!< interpreted
|
||||
static const Mode_t MODE_OFF = 0; //!< The device is powered off. The only command accepted in
|
||||
//!< this mode is a mode change to on.
|
||||
static const Submode_t SUBMODE_NONE = 0; //!< To avoid checks against magic number "0".
|
||||
|
||||
virtual ~HasModesIF() {}
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
@ -1,29 +1,29 @@
|
||||
target_sources(${LIB_FSFW_NAME} PRIVATE
|
||||
Clock.cpp
|
||||
BinarySemaphore.cpp
|
||||
CountingSemaphore.cpp
|
||||
FixedTimeslotTask.cpp
|
||||
InternalErrorCodes.cpp
|
||||
MessageQueue.cpp
|
||||
Mutex.cpp
|
||||
MutexFactory.cpp
|
||||
PeriodicPosixTask.cpp
|
||||
PosixThread.cpp
|
||||
QueueFactory.cpp
|
||||
SemaphoreFactory.cpp
|
||||
TaskFactory.cpp
|
||||
tcpipHelpers.cpp
|
||||
unixUtility.cpp
|
||||
BinarySemaphore.cpp
|
||||
CountingSemaphore.cpp
|
||||
FixedTimeslotTask.cpp
|
||||
InternalErrorCodes.cpp
|
||||
MessageQueue.cpp
|
||||
Mutex.cpp
|
||||
MutexFactory.cpp
|
||||
PeriodicPosixTask.cpp
|
||||
PosixThread.cpp
|
||||
QueueFactory.cpp
|
||||
SemaphoreFactory.cpp
|
||||
TaskFactory.cpp
|
||||
tcpipHelpers.cpp
|
||||
unixUtility.cpp
|
||||
)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
target_link_libraries(${LIB_FSFW_NAME} PRIVATE
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
rt
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
rt
|
||||
)
|
||||
|
||||
target_link_libraries(${LIB_FSFW_NAME} INTERFACE
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
|
||||
|
@ -65,10 +65,9 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
|
||||
/**
|
||||
* @brief The function containing the actual functionality of the task.
|
||||
* @details The method sets and starts
|
||||
* the task's period, then enters a loop that is repeated indefinitely. Within
|
||||
* the loop, all performOperation methods of the added objects are called. Afterwards the task
|
||||
* will be blocked until the next period. On missing the deadline, the deadlineMissedFunction is
|
||||
* executed.
|
||||
* the task's period, then enters a loop that is repeated indefinitely. Within the
|
||||
* loop, all performOperation methods of the added objects are called. Afterwards the task will be
|
||||
* blocked until the next period. On missing the deadline, the deadlineMissedFunction is executed.
|
||||
*/
|
||||
virtual void taskFunctionality(void);
|
||||
/**
|
||||
|
@ -13,8 +13,8 @@ class ExecutableObjectIF;
|
||||
* @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
|
||||
* multiple objects that implement the ExecutableObjectIF interface. The
|
||||
* objects must be added prior to starting the task.
|
||||
* multiple objects that implement the ExecutableObjectIF interface. The objects
|
||||
* must be added prior to starting the task.
|
||||
* @author baetz
|
||||
* @ingroup task_handling
|
||||
*/
|
||||
|
@ -34,14 +34,14 @@ class Fuse : public SystemObject,
|
||||
};
|
||||
|
||||
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(1, severity::LOW);
|
||||
//! PSS detected a fuse that went off.
|
||||
static const Event FUSE_WENT_OFF = MAKE_EVENT(2, severity::LOW);
|
||||
//! PSS detected a fuse that violates its limits.
|
||||
static const Event POWER_ABOVE_HIGH_LIMIT = MAKE_EVENT(4, severity::LOW);
|
||||
//! PSS detected a fuse that violates its limits.
|
||||
static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, severity::LOW);
|
||||
static const Event FUSE_CURRENT_HIGH = MAKE_EVENT(
|
||||
1, severity::LOW); //!< PSS detected that current on a fuse is totally out of bounds.
|
||||
static const Event FUSE_WENT_OFF =
|
||||
MAKE_EVENT(2, severity::LOW); //!< PSS detected a fuse that went off.
|
||||
static const Event POWER_ABOVE_HIGH_LIMIT =
|
||||
MAKE_EVENT(4, severity::LOW); //!< PSS detected a fuse that violates its limits.
|
||||
static const Event POWER_BELOW_LOW_LIMIT =
|
||||
MAKE_EVENT(5, severity::LOW); //!< PSS detected a fuse that violates its limits.
|
||||
|
||||
typedef std::list<PowerComponentIF *> DeviceList;
|
||||
Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet, VariableIds ids,
|
||||
|
@ -6,10 +6,10 @@
|
||||
class Service9TimeManagement : public PusServiceBase {
|
||||
public:
|
||||
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 = MAKE_EVENT(0, severity::INFO);
|
||||
//!< Clock could not be set. P1: Returncode.
|
||||
static constexpr Event CLOCK_SET_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||
static constexpr Event CLOCK_SET =
|
||||
MAKE_EVENT(0, severity::INFO); //!< Clock has been set. P1: New Uptime. P2: Old Uptime
|
||||
static constexpr Event CLOCK_SET_FAILURE =
|
||||
MAKE_EVENT(1, severity::LOW); //!< Clock could not be set. P1: Returncode.
|
||||
|
||||
static constexpr uint8_t CLASS_ID = CLASS_ID::PUS_SERVICE_9;
|
||||
|
||||
|
@ -169,8 +169,8 @@ class RMAP : public HasReturnvaluesIF {
|
||||
* @param buffer the data to write
|
||||
* @param length length of data
|
||||
* @return
|
||||
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was ==
|
||||
* NULL in write command
|
||||
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in
|
||||
* write command
|
||||
* - return codes of RMAPChannelIF::sendCommand()
|
||||
*/
|
||||
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 expLength the expected maximum length of the reply
|
||||
* @return
|
||||
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was ==
|
||||
* NULL in write command, or nullpointer in read command
|
||||
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in
|
||||
* write command, or nullpointer in read command
|
||||
* - return codes of RMAPChannelIF::sendCommand()
|
||||
*/
|
||||
static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength);
|
||||
|
@ -75,11 +75,11 @@ class RMAPChannelIF {
|
||||
* - @c RETURN_OK
|
||||
* - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending
|
||||
* command; command was not sent
|
||||
* - @c COMMAND_BUFFER_FULL no receiver buffer available for
|
||||
* expected len; command was not sent
|
||||
* - @c COMMAND_TOO_BIG the data that was to be sent was too long
|
||||
* for the hw to handle (write command) or the expected len was bigger than maximal expected len
|
||||
* (read command) command was not sent
|
||||
* - @c COMMAND_BUFFER_FULL no receiver buffer available for expected len;
|
||||
* command was not sent
|
||||
* - @c COMMAND_TOO_BIG the data that was to be sent was too long for the hw
|
||||
* to handle (write command) or the expected len was bigger than maximal expected len (read
|
||||
* command) command was not sent
|
||||
* - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set
|
||||
* - @c NOT_SUPPORTED if you dont feel like
|
||||
* implementing something...
|
||||
@ -97,8 +97,8 @@ class RMAPChannelIF {
|
||||
* - @c REPLY_NO_REPLY no reply was received
|
||||
* - @c REPLY_NOT_SENT command was not sent, implies no reply
|
||||
* - @c REPLY_NOT_YET_SENT command is still waiting to be sent
|
||||
* - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission
|
||||
* buffer still being processed)
|
||||
* - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer still
|
||||
* being processed)
|
||||
* - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last
|
||||
* operation, data could not be processed. (transmission error)
|
||||
* - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value)
|
||||
|
@ -99,13 +99,6 @@ class Clock {
|
||||
*/
|
||||
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.
|
||||
* @param time The time of day as input
|
||||
|
@ -1,9 +1,7 @@
|
||||
#include <ctime>
|
||||
|
||||
#include "fsfw/ipc/MutexGuard.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;
|
||||
ReturnValue_t result = getLeapSeconds(&leapSeconds);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
@ -33,7 +31,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
||||
ReturnValue_t Clock::getLeapSeconds(uint16_t *leapSeconds_) {
|
||||
if (timeMutex == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
@ -44,22 +42,9 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) {
|
||||
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() {
|
||||
if (timeMutex == nullptr) {
|
||||
MutexFactory* mutexFactory = MutexFactory::instance();
|
||||
MutexFactory *mutexFactory = MutexFactory::instance();
|
||||
if (mutexFactory == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
@ -33,47 +33,50 @@ class TmStoreBackendIF : public HasParametersIF {
|
||||
static const ReturnValue_t INVALID_REQUEST = MAKE_RETURN_CODE(15);
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::MEMORY;
|
||||
//! Initiating sending data to store failed. Low, par1:
|
||||
//! returnCode, par2: integer (debug info)
|
||||
static const Event STORE_SEND_WRITE_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||
//! Data was sent, but writing failed. Low, par1: returnCode, par2: 0
|
||||
static const Event STORE_WRITE_FAILED = MAKE_EVENT(1, severity::LOW);
|
||||
//! Initiating reading data from store failed. Low, par1: returnCode, par2: 0
|
||||
static const Event STORE_SEND_READ_FAILED = MAKE_EVENT(2, severity::LOW);
|
||||
//! Data was requested, but access failed. Low, par1: returnCode, par2: 0
|
||||
static const Event STORE_READ_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||
//! An unexpected TM packet or data message occurred. Low, par1: 0, par2: integer (debug info)
|
||||
static const Event UNEXPECTED_MSG = MAKE_EVENT(4, severity::LOW);
|
||||
//! Storing data failed. May simply be a full store. Low, par1: returnCode,
|
||||
//! par2: integer (sequence count of failed packet).
|
||||
static const Event STORING_FAILED = MAKE_EVENT(5, severity::LOW);
|
||||
//! Dumping retrieved data failed. Low, par1: returnCode,
|
||||
//! par2: integer (sequence count of failed packet).
|
||||
static const Event TM_DUMP_FAILED = MAKE_EVENT(6, severity::LOW);
|
||||
//! Corrupted init data or read error. Low, par1: returnCode, par2: integer (debug info)
|
||||
//! Store was not initialized. Starts empty. Info, parameters both zero.
|
||||
static const Event STORE_INIT_FAILED = MAKE_EVENT(7, severity::LOW);
|
||||
//! Data was read out, but it is inconsistent. Low par1:
|
||||
//! Memory address of corruption, par2: integer (debug info)
|
||||
static const Event STORE_INIT_EMPTY = MAKE_EVENT(8, severity::INFO);
|
||||
|
||||
static const Event STORE_CONTENT_CORRUPTED = MAKE_EVENT(9, severity::LOW);
|
||||
//! Info event indicating the store will be initialized, either at boot or after IOB switch.
|
||||
//! Info. pars: 0
|
||||
static const Event STORE_INITIALIZE = MAKE_EVENT(10, severity::INFO);
|
||||
//! Info event indicating the store was successfully initialized, either at boot or after
|
||||
//! IOB switch. Info. pars: 0
|
||||
static const Event INIT_DONE = MAKE_EVENT(11, severity::INFO);
|
||||
//! Info event indicating that dumping finished successfully.
|
||||
//! par1: Number of dumped packets. par2: APID/SSC (16bits each)
|
||||
static const Event DUMP_FINISHED = MAKE_EVENT(12, severity::INFO);
|
||||
//! Info event indicating that deletion finished successfully.
|
||||
//! par1:Number of deleted packets. par2: APID/SSC (16bits each)
|
||||
static const Event DELETION_FINISHED = MAKE_EVENT(13, severity::INFO);
|
||||
//! Info event indicating that something went wrong during deletion. pars: 0
|
||||
static const Event DELETION_FAILED = MAKE_EVENT(14, severity::LOW);
|
||||
//! Info that the a auto catalog report failed
|
||||
static const Event AUTO_CATALOGS_SENDING_FAILED = MAKE_EVENT(15, severity::INFO);
|
||||
static const Event STORE_SEND_WRITE_FAILED =
|
||||
MAKE_EVENT(0, severity::LOW); //!< Initiating sending data to store failed. Low, par1:
|
||||
//!< returnCode, par2: integer (debug info)
|
||||
static const Event STORE_WRITE_FAILED = MAKE_EVENT(
|
||||
1, severity::LOW); //!< Data was sent, but writing failed. Low, par1: returnCode, par2: 0
|
||||
static const Event STORE_SEND_READ_FAILED =
|
||||
MAKE_EVENT(2, severity::LOW); //!< Initiating reading data from store failed. Low, par1:
|
||||
//!< returnCode, par2: 0
|
||||
static const Event STORE_READ_FAILED = MAKE_EVENT(
|
||||
3, severity::LOW); //!< Data was requested, but access failed. Low, par1: returnCode, par2: 0
|
||||
static const Event UNEXPECTED_MSG =
|
||||
MAKE_EVENT(4, severity::LOW); //!< An unexpected TM packet or data message occurred. Low,
|
||||
//!< par1: 0, par2: integer (debug info)
|
||||
static const Event STORING_FAILED = MAKE_EVENT(
|
||||
5, severity::LOW); //!< Storing data failed. May simply be a full store. Low, par1:
|
||||
//!< returnCode, par2: integer (sequence count of failed packet).
|
||||
static const Event TM_DUMP_FAILED =
|
||||
MAKE_EVENT(6, severity::LOW); //!< Dumping retrieved data failed. Low, par1: returnCode,
|
||||
//!< par2: integer (sequence count of failed packet).
|
||||
static const Event STORE_INIT_FAILED =
|
||||
MAKE_EVENT(7, severity::LOW); //!< Corrupted init data or read error. Low, par1: returnCode,
|
||||
//!< par2: integer (debug 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); //!< Data was read out, but it is inconsistent. Low par1:
|
||||
//!< Memory address of corruption, par2: integer (debug info)
|
||||
static const Event STORE_INITIALIZE =
|
||||
MAKE_EVENT(10, severity::INFO); //!< Info event indicating the store will be initialized,
|
||||
//!< either at boot or after IOB switch. Info. pars: 0
|
||||
static const Event INIT_DONE = MAKE_EVENT(
|
||||
11, severity::INFO); //!< Info event indicating the store was successfully initialized,
|
||||
//!< either at boot or after IOB switch. Info. pars: 0
|
||||
static const Event DUMP_FINISHED = MAKE_EVENT(
|
||||
12, severity::INFO); //!< Info event indicating that dumping finished successfully. par1:
|
||||
//!< Number of dumped packets. par2: APID/SSC (16bits each)
|
||||
static const Event DELETION_FINISHED = MAKE_EVENT(
|
||||
13, severity::INFO); //!< Info event indicating that deletion finished successfully. par1:
|
||||
//!< Number of deleted packets. par2: APID/SSC (16bits each)
|
||||
static const Event DELETION_FAILED = MAKE_EVENT(
|
||||
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() {}
|
||||
|
||||
|
@ -172,18 +172,15 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage* message) {
|
||||
}
|
||||
|
||||
if (tmFifo->full()) {
|
||||
if (warningSwitch) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
|
||||
"of stored packet IDs reached!"
|
||||
<< std::endl;
|
||||
sif::warning << "TmTcBridge::storeDownlinkData: TM downlink max. number "
|
||||
"of stored packet IDs reached!"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning(
|
||||
"TmTcBridge::storeDownlinkData: TM downlink max. number "
|
||||
"of stored packet IDs reached!\n");
|
||||
sif::printWarning(
|
||||
"TmTcBridge::storeDownlinkData: TM downlink max. number "
|
||||
"of stored packet IDs reached!\n");
|
||||
#endif
|
||||
warningSwitch = true;
|
||||
}
|
||||
if (overwriteOld) {
|
||||
tmFifo->retrieve(&storeId);
|
||||
tmStore->deleteData(storeId);
|
||||
|
@ -72,8 +72,6 @@ class TmTcBridge : public AcceptsTelemetryIF,
|
||||
virtual uint16_t getIdentifier() override;
|
||||
virtual MessageQueueId_t getRequestQueue() override;
|
||||
|
||||
bool warningSwitch = true;
|
||||
|
||||
protected:
|
||||
//! Cached for initialize function.
|
||||
object_id_t tmStoreId = objects::NO_OBJECT;
|
||||
|
@ -45,7 +45,7 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
|
||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||
usleep(500);
|
||||
REQUIRE(limitIdx < 5);
|
||||
REQUIRE(limitIdx < 500);
|
||||
}
|
||||
|
||||
limitIdx = 0;
|
||||
@ -71,8 +71,9 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
|
||||
limitIdx++;
|
||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||
// This ensures that the tests do not block indefinitely
|
||||
usleep(500);
|
||||
REQUIRE(limitIdx < 20);
|
||||
REQUIRE(limitIdx < 500);
|
||||
}
|
||||
limitIdx = 0;
|
||||
CHECK(bytesHaveBeenRead == true);
|
||||
@ -89,7 +90,7 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
|
||||
std::string allTheReply(reinterpret_cast<char*>(largerReadBuffer));
|
||||
// I am just going to assume that this string is the same across ping implementations
|
||||
// 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
|
||||
result = cmdExecutor.load("false", false, false);
|
||||
@ -101,8 +102,9 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
|
||||
limitIdx++;
|
||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||
// This ensures that the tests do not block indefinitely
|
||||
usleep(500);
|
||||
REQUIRE(limitIdx < 20);
|
||||
REQUIRE(limitIdx < 500);
|
||||
}
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
|
||||
REQUIRE(cmdExecutor.getLastError() == 1);
|
||||
|
Reference in New Issue
Block a user