Merge remote-tracking branch 'upstream/development' into mueller/master
This commit is contained in:
commit
67a79c505a
@ -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 3)
|
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
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -14,3 +14,5 @@ if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS)
|
|||||||
add_subdirectory(i2c)
|
add_subdirectory(i2c)
|
||||||
add_subdirectory(uart)
|
add_subdirectory(uart)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(uio)
|
||||||
|
3
hal/src/fsfw_hal/linux/uio/CMakeLists.txt
Normal file
3
hal/src/fsfw_hal/linux/uio/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
target_sources(${LIB_FSFW_NAME} PUBLIC
|
||||||
|
UioMapper.cpp
|
||||||
|
)
|
86
hal/src/fsfw_hal/linux/uio/UioMapper.cpp
Normal file
86
hal/src/fsfw_hal/linux/uio/UioMapper.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#include "UioMapper.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "fsfw/serviceinterface.h"
|
||||||
|
|
||||||
|
const char UioMapper::UIO_PATH_PREFIX[] = "/sys/class/uio/";
|
||||||
|
const char UioMapper::MAP_SUBSTR[] = "/maps/map";
|
||||||
|
const char UioMapper::SIZE_FILE_PATH[] = "/size";
|
||||||
|
|
||||||
|
UioMapper::UioMapper(std::string uioFile, int mapNum) : uioFile(uioFile), mapNum(mapNum) {}
|
||||||
|
|
||||||
|
UioMapper::~UioMapper() {}
|
||||||
|
|
||||||
|
ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permissions) {
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
|
int fd = open(uioFile.c_str(), O_RDWR);
|
||||||
|
if (fd < 1) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "PtmeAxiConfig::initialize: Invalid UIO device file" << std::endl;
|
||||||
|
#endif
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
size_t size = 0;
|
||||||
|
result = getMapSize(&size);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
*address = static_cast<uint32_t*>(
|
||||||
|
mmap(NULL, size, static_cast<int>(permissions), MAP_SHARED, fd, mapNum * getpagesize()));
|
||||||
|
|
||||||
|
if (*address == MAP_FAILED) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t UioMapper::getMapSize(size_t* size) {
|
||||||
|
std::stringstream namestream;
|
||||||
|
namestream << UIO_PATH_PREFIX << uioFile.substr(5, std::string::npos) << MAP_SUBSTR << mapNum
|
||||||
|
<< SIZE_FILE_PATH;
|
||||||
|
FILE* fp;
|
||||||
|
fp = fopen(namestream.str().c_str(), "r");
|
||||||
|
if (fp == nullptr) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "UioMapper::getMapSize: Failed to open file " << namestream.str() << std::endl;
|
||||||
|
#endif
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
char hexstring[SIZE_HEX_STRING] = "";
|
||||||
|
int items = fscanf(fp, "%s", hexstring);
|
||||||
|
if (items != 1) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
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;
|
||||||
|
items = sscanf(hexstring, "%x", &sizeTmp);
|
||||||
|
if (size != nullptr) {
|
||||||
|
*size = sizeTmp;
|
||||||
|
}
|
||||||
|
if (items != 1) {
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
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);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
58
hal/src/fsfw_hal/linux/uio/UioMapper.h
Normal file
58
hal/src/fsfw_hal/linux/uio/UioMapper.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef FSFW_HAL_SRC_FSFW_HAL_LINUX_UIO_UIOMAPPER_H_
|
||||||
|
#define FSFW_HAL_SRC_FSFW_HAL_LINUX_UIO_UIOMAPPER_H_
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Class to help opening uio device files and mapping the physical addresses into the user
|
||||||
|
* address space.
|
||||||
|
*
|
||||||
|
* @author J. Meier
|
||||||
|
*/
|
||||||
|
class UioMapper {
|
||||||
|
public:
|
||||||
|
enum class Permissions : int {
|
||||||
|
READ_ONLY = PROT_READ,
|
||||||
|
WRITE_ONLY = PROT_WRITE,
|
||||||
|
READ_WRITE = PROT_READ | PROT_WRITE
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* @param uioFile The device file of the uiO to open
|
||||||
|
* @param uioMap Number of memory map. Most UIO drivers have only one map which has than 0.
|
||||||
|
*/
|
||||||
|
UioMapper(std::string uioFile, int mapNum = 0);
|
||||||
|
virtual ~UioMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maps the physical address into user address space and returns the mapped address
|
||||||
|
*
|
||||||
|
* @address The mapped user space address
|
||||||
|
* @permissions Specifies the read/write permissions of the address region
|
||||||
|
*/
|
||||||
|
ReturnValue_t getMappedAdress(uint32_t** address, Permissions permissions);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char UIO_PATH_PREFIX[];
|
||||||
|
static const char MAP_SUBSTR[];
|
||||||
|
static const char SIZE_FILE_PATH[];
|
||||||
|
static constexpr int SIZE_HEX_STRING = 10;
|
||||||
|
|
||||||
|
std::string uioFile;
|
||||||
|
int mapNum = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads the map size from the associated sysfs size file
|
||||||
|
*
|
||||||
|
* @param size The read map size
|
||||||
|
*/
|
||||||
|
ReturnValue_t getMapSize(size_t* size);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FSFW_HAL_SRC_FSFW_HAL_LINUX_UIO_UIOMAPPER_H_ */
|
@ -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("..")
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class DataLinkLayer : public CCSDSReturnValuesIF {
|
|||||||
//! [EXPORT] : [COMMENT] A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0
|
//! [EXPORT] : [COMMENT] A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0
|
||||||
static const Event BIT_LOCK_LOST = MAKE_EVENT(3, severity::INFO);
|
static const Event BIT_LOCK_LOST = MAKE_EVENT(3, severity::INFO);
|
||||||
// static const Event RF_CHAIN_LOST = MAKE_EVENT(4, severity::INFO); //!< The CCSDS Board
|
// static const Event RF_CHAIN_LOST = MAKE_EVENT(4, severity::INFO); //!< The CCSDS Board
|
||||||
//detected that either bit lock or RF available or both are lost. No parameters.
|
// detected that either bit lock or RF available or both are lost. No parameters.
|
||||||
//! [EXPORT] : [COMMENT] The CCSDS Board could not interpret a TC
|
//! [EXPORT] : [COMMENT] The CCSDS Board could not interpret a TC
|
||||||
static const Event FRAME_PROCESSING_FAILED = MAKE_EVENT(5, severity::LOW);
|
static const Event FRAME_PROCESSING_FAILED = MAKE_EVENT(5, severity::LOW);
|
||||||
/**
|
/**
|
||||||
|
@ -30,9 +30,9 @@ ReturnValue_t VirtualChannelReception::mapDemultiplexing(TcTransferFrame* frame)
|
|||||||
mapChannelIterator iter = mapChannels.find(mapId);
|
mapChannelIterator iter = mapChannels.find(mapId);
|
||||||
if (iter == mapChannels.end()) {
|
if (iter == mapChannels.end()) {
|
||||||
// error << "VirtualChannelReception::mapDemultiplexing on VC " << std::hex << (int)
|
// error << "VirtualChannelReception::mapDemultiplexing on VC " << std::hex << (int)
|
||||||
//channelId
|
// channelId
|
||||||
// << ": MapChannel " << (int) mapId << std::dec << " not found." <<
|
// << ": MapChannel " << (int) mapId << std::dec << " not found." <<
|
||||||
//std::endl;
|
// std::endl;
|
||||||
return VC_NOT_FOUND;
|
return VC_NOT_FOUND;
|
||||||
} else {
|
} else {
|
||||||
return (iter->second)->extractPackets(frame);
|
return (iter->second)->extractPackets(frame);
|
||||||
|
@ -291,3 +291,5 @@ float LocalPoolDataSetBase::getCollectionInterval() const {
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalPoolDataSetBase::printSet() { return; }
|
||||||
|
@ -171,6 +171,11 @@ class LocalPoolDataSetBase : public PoolDataSetBase, public MarkChangedIF {
|
|||||||
*/
|
*/
|
||||||
float getCollectionInterval() const;
|
float getCollectionInterval() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Can be overwritten by a specific implementation of a dataset to print the set.
|
||||||
|
*/
|
||||||
|
virtual void printSet();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
sid_t sid;
|
sid_t sid;
|
||||||
//! This mutex is used if the data is created by one object only.
|
//! This mutex is used if the data is created by one object only.
|
||||||
|
@ -665,6 +665,11 @@ void DeviceHandlerBase::doGetWrite() {
|
|||||||
void DeviceHandlerBase::doSendRead() {
|
void DeviceHandlerBase::doSendRead() {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
|
|
||||||
|
result = doSendReadHook();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
size_t replyLen = 0;
|
size_t replyLen = 0;
|
||||||
if (cookieInfo.pendingCommand != deviceCommandMap.end()) {
|
if (cookieInfo.pendingCommand != deviceCommandMap.end()) {
|
||||||
replyLen = getNextReplyLength(cookieInfo.pendingCommand->first);
|
replyLen = getNextReplyLength(cookieInfo.pendingCommand->first);
|
||||||
@ -920,6 +925,8 @@ void DeviceHandlerBase::commandSwitch(ReturnValue_t onOff) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t DeviceHandlerBase::doSendReadHook() { return RETURN_OK; }
|
||||||
|
|
||||||
ReturnValue_t DeviceHandlerBase::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) {
|
ReturnValue_t DeviceHandlerBase::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) {
|
||||||
return DeviceHandlerBase::NO_SWITCH;
|
return DeviceHandlerBase::NO_SWITCH;
|
||||||
}
|
}
|
||||||
|
@ -1082,6 +1082,12 @@ class DeviceHandlerBase : public DeviceHandlerIF,
|
|||||||
*/
|
*/
|
||||||
void commandSwitch(ReturnValue_t onOff);
|
void commandSwitch(ReturnValue_t onOff);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function can be used to insert device specific code during the do-send-read
|
||||||
|
* step.
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t doSendReadHook();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* State a cookie is in.
|
* State a cookie is in.
|
||||||
|
@ -116,8 +116,8 @@ uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t starti
|
|||||||
// for (int i=0; i<16 ;i++)
|
// for (int i=0; i<16 ;i++)
|
||||||
// {
|
// {
|
||||||
// if (xor_out[i] == true)
|
// if (xor_out[i] == true)
|
||||||
// crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before Final
|
// crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before
|
||||||
//XOR
|
//Final XOR
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// crc_value = 0;// for debug mode
|
// crc_value = 0;// for debug mode
|
||||||
|
@ -14,30 +14,30 @@ class ModeMessage {
|
|||||||
static const uint8_t MESSAGE_ID = messagetypes::MODE_COMMAND;
|
static const uint8_t MESSAGE_ID = messagetypes::MODE_COMMAND;
|
||||||
static const Command_t CMD_MODE_COMMAND =
|
static const Command_t CMD_MODE_COMMAND =
|
||||||
MAKE_COMMAND_ID(0x01); //!> Command to set the specified Mode, replies are: REPLY_MODE_REPLY,
|
MAKE_COMMAND_ID(0x01); //!> Command to set the specified Mode, replies are: REPLY_MODE_REPLY,
|
||||||
//!REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies,
|
//! REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies,
|
||||||
//!as this will break the subsystem mode machine!!
|
//! as this will break the subsystem mode machine!!
|
||||||
static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(
|
static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(
|
||||||
0xF1); //!> Command to set the specified Mode, regardless of external control flag, replies
|
0xF1); //!> Command to set the specified Mode, regardless of external control flag, replies
|
||||||
//!are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any
|
//! are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any
|
||||||
//!replies, as this will break the subsystem mode machine!!
|
//! replies, as this will break the subsystem mode machine!!
|
||||||
static const Command_t REPLY_MODE_REPLY =
|
static const Command_t REPLY_MODE_REPLY =
|
||||||
MAKE_COMMAND_ID(0x02); //!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
|
MAKE_COMMAND_ID(0x02); //!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ
|
||||||
static const Command_t REPLY_MODE_INFO =
|
static const Command_t REPLY_MODE_INFO =
|
||||||
MAKE_COMMAND_ID(0x03); //!> Unrequested info about the current mode (used for composites to
|
MAKE_COMMAND_ID(0x03); //!> Unrequested info about the current mode (used for composites to
|
||||||
//!inform their container of a changed mode)
|
//! inform their container of a changed mode)
|
||||||
static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID(
|
static const Command_t REPLY_CANT_REACH_MODE = MAKE_COMMAND_ID(
|
||||||
0x04); //!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0
|
0x04); //!> Reply in case a mode command can't be executed. Par1: returnCode, Par2: 0
|
||||||
static const Command_t REPLY_WRONG_MODE_REPLY =
|
static const Command_t REPLY_WRONG_MODE_REPLY =
|
||||||
MAKE_COMMAND_ID(0x05); //!> Reply to a CMD_MODE_COMMAND, indicating that a mode was commanded
|
MAKE_COMMAND_ID(0x05); //!> Reply to a CMD_MODE_COMMAND, indicating that a mode was commanded
|
||||||
//!and a transition started but was aborted; the parameters contain
|
//! and a transition started but was aborted; the parameters contain
|
||||||
//!the mode that was reached
|
//! the mode that was reached
|
||||||
static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID(
|
static const Command_t CMD_MODE_READ = MAKE_COMMAND_ID(
|
||||||
0x06); //!> Command to read the current mode and reply with a REPLY_MODE_REPLY
|
0x06); //!> Command to read the current mode and reply with a REPLY_MODE_REPLY
|
||||||
static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID(
|
static const Command_t CMD_MODE_ANNOUNCE = MAKE_COMMAND_ID(
|
||||||
0x07); //!> Command to trigger an ModeInfo Event. This command does NOT have a reply.
|
0x07); //!> Command to trigger an ModeInfo Event. This command does NOT have a reply.
|
||||||
static const Command_t CMD_MODE_ANNOUNCE_RECURSIVELY =
|
static const Command_t CMD_MODE_ANNOUNCE_RECURSIVELY =
|
||||||
MAKE_COMMAND_ID(0x08); //!> Command to trigger an ModeInfo Event and to send this command to
|
MAKE_COMMAND_ID(0x08); //!> Command to trigger an ModeInfo Event and to send this command to
|
||||||
//!every child. This command does NOT have a reply.
|
//! every child. This command does NOT have a reply.
|
||||||
|
|
||||||
static Mode_t getMode(const CommandMessage* message);
|
static Mode_t getMode(const CommandMessage* message);
|
||||||
static Submode_t getSubmode(const CommandMessage* message);
|
static Submode_t getSubmode(const CommandMessage* message);
|
||||||
|
@ -65,8 +65,8 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
|
|||||||
/**
|
/**
|
||||||
* @brief The function containing the actual functionality of the task.
|
* @brief The function containing the actual functionality of the task.
|
||||||
* @details The method sets and starts
|
* @details The method sets and starts
|
||||||
* the task's period, then enters a loop that is repeated indefinitely. Within the loop,
|
* the task's period, then enters a loop that is repeated indefinitely. Within the
|
||||||
* all performOperation methods of the added objects are called. Afterwards the task will be
|
* 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.
|
* blocked until the next period. On missing the deadline, the deadlineMissedFunction is executed.
|
||||||
*/
|
*/
|
||||||
virtual void taskFunctionality(void);
|
virtual void taskFunctionality(void);
|
||||||
|
@ -13,8 +13,8 @@ class ExecutableObjectIF;
|
|||||||
* @brief This class represents a specialized task for periodic activities of multiple objects.
|
* @brief This class represents a specialized task for periodic activities of multiple objects.
|
||||||
*
|
*
|
||||||
* @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute
|
* @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute
|
||||||
* multiple objects that implement the ExecutableObjectIF interface. The objects must
|
* multiple objects that implement the ExecutableObjectIF interface. The objects
|
||||||
* be added prior to starting the task.
|
* must be added prior to starting the task.
|
||||||
* @author baetz
|
* @author baetz
|
||||||
* @ingroup task_handling
|
* @ingroup task_handling
|
||||||
*/
|
*/
|
||||||
|
@ -25,8 +25,8 @@ class RTEMSTaskBase {
|
|||||||
* all other attributes are set with default values.
|
* all other attributes are set with default values.
|
||||||
* @param priority Sets the priority of a task. Values range from a low 0 to a high 99.
|
* @param priority Sets the priority of a task. Values range from a low 0 to a high 99.
|
||||||
* @param stack_size The stack size reserved by the operating system for the task.
|
* @param stack_size The stack size reserved by the operating system for the task.
|
||||||
* @param nam The name of the Task, as a null-terminated String. Currently max 4 chars
|
* @param nam The name of the Task, as a null-terminated String. Currently max 4
|
||||||
* supported (excluding Null-terminator), rest will be truncated
|
* chars supported (excluding Null-terminator), rest will be truncated
|
||||||
*/
|
*/
|
||||||
RTEMSTaskBase(rtems_task_priority priority, size_t stack_size, const char *name);
|
RTEMSTaskBase(rtems_task_priority priority, size_t stack_size, const char *name);
|
||||||
/**
|
/**
|
||||||
|
@ -51,9 +51,9 @@ class RMAP : public HasReturnvaluesIF {
|
|||||||
// MAKE_RETURN_CODE(0xE4); //the data that was to be sent was too long for the hw to handle (write
|
// MAKE_RETURN_CODE(0xE4); //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
|
// command) or the expected len was bigger than maximal expected len (read command) command was
|
||||||
// not sent
|
// not sent
|
||||||
// replaced by DeviceCommunicationIF::NULLPOINTER static const ReturnValue_t COMMAND_NULLPOINTER
|
// replaced by DeviceCommunicationIF::NULLPOINTER static const ReturnValue_t
|
||||||
// = MAKE_RETURN_CODE(0xE5); //datalen was != 0 but data was == NULL in write command, or
|
// COMMAND_NULLPOINTER = MAKE_RETURN_CODE(0xE5); //datalen was != 0 but data was == NULL in write
|
||||||
// nullpointer in read command
|
// command, or nullpointer in read command
|
||||||
static const ReturnValue_t COMMAND_CHANNEL_DEACTIVATED =
|
static const ReturnValue_t COMMAND_CHANNEL_DEACTIVATED =
|
||||||
MAKE_RETURN_CODE(0xE6); // the channel has no port set
|
MAKE_RETURN_CODE(0xE6); // the channel has no port set
|
||||||
static const ReturnValue_t COMMAND_PORT_OUT_OF_RANGE =
|
static const ReturnValue_t COMMAND_PORT_OUT_OF_RANGE =
|
||||||
@ -73,8 +73,8 @@ class RMAP : public HasReturnvaluesIF {
|
|||||||
static const ReturnValue_t REPLY_MISSMATCH = MAKE_RETURN_CODE(
|
static const ReturnValue_t REPLY_MISSMATCH = MAKE_RETURN_CODE(
|
||||||
0xD3); // a read command was issued, but get_write_rply called, or other way round
|
0xD3); // a read command was issued, but get_write_rply called, or other way round
|
||||||
static const ReturnValue_t REPLY_TIMEOUT = MAKE_RETURN_CODE(0xD4); // timeout
|
static const ReturnValue_t REPLY_TIMEOUT = MAKE_RETURN_CODE(0xD4); // timeout
|
||||||
// replaced by DeviceCommunicationIF::NULLPOINTER static const ReturnValue_t REPLY_NULLPOINTER =
|
// replaced by DeviceCommunicationIF::NULLPOINTER static const ReturnValue_t REPLY_NULLPOINTER
|
||||||
// MAKE_RETURN_CODE(0xD5);//one of the arguments in a read reply was NULL return values for
|
// = MAKE_RETURN_CODE(0xD5);//one of the arguments in a read reply was NULL return values for
|
||||||
// get_reply
|
// get_reply
|
||||||
static const ReturnValue_t REPLY_INTERFACE_BUSY =
|
static const ReturnValue_t REPLY_INTERFACE_BUSY =
|
||||||
MAKE_RETURN_CODE(0xC0); // Interface is busy (transmission buffer still being processed)
|
MAKE_RETURN_CODE(0xC0); // Interface is busy (transmission buffer still being processed)
|
||||||
@ -169,8 +169,8 @@ class RMAP : public HasReturnvaluesIF {
|
|||||||
* @param buffer the data to write
|
* @param buffer the data to write
|
||||||
* @param length length of data
|
* @param length length of data
|
||||||
* @return
|
* @return
|
||||||
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in write
|
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in
|
||||||
* command
|
* write command
|
||||||
* - return codes of RMAPChannelIF::sendCommand()
|
* - return codes of RMAPChannelIF::sendCommand()
|
||||||
*/
|
*/
|
||||||
static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, const uint8_t *buffer, size_t length);
|
static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, const uint8_t *buffer, size_t length);
|
||||||
@ -205,8 +205,8 @@ class RMAP : public HasReturnvaluesIF {
|
|||||||
* @param cookie to cookie to read from
|
* @param cookie to cookie to read from
|
||||||
* @param expLength the expected maximum length of the reply
|
* @param expLength the expected maximum length of the reply
|
||||||
* @return
|
* @return
|
||||||
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in write
|
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in
|
||||||
* command, or nullpointer in read command
|
* write command, or nullpointer in read command
|
||||||
* - return codes of RMAPChannelIF::sendCommand()
|
* - return codes of RMAPChannelIF::sendCommand()
|
||||||
*/
|
*/
|
||||||
static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength);
|
static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength);
|
||||||
|
@ -73,16 +73,16 @@ class RMAPChannelIF {
|
|||||||
* @param datalen length of data
|
* @param datalen length of data
|
||||||
* @return
|
* @return
|
||||||
* - @c RETURN_OK
|
* - @c RETURN_OK
|
||||||
* - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending command;
|
* - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending
|
||||||
* command was not sent
|
* command; command was not sent
|
||||||
* - @c COMMAND_BUFFER_FULL no receiver buffer available for expected len; command
|
* - @c COMMAND_BUFFER_FULL no receiver buffer available for expected len;
|
||||||
* 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
|
* 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 COMMAND_CHANNEL_DEACTIVATED the channel has no port set
|
||||||
* - @c NOT_SUPPORTED if you dont feel like implementing
|
* - @c NOT_SUPPORTED if you dont feel like
|
||||||
* something...
|
* implementing something...
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t sendCommand(RMAPCookie *cookie, uint8_t instruction, const uint8_t *data,
|
virtual ReturnValue_t sendCommand(RMAPCookie *cookie, uint8_t instruction, const uint8_t *data,
|
||||||
size_t datalen) = 0;
|
size_t datalen) = 0;
|
||||||
@ -97,8 +97,8 @@ class RMAPChannelIF {
|
|||||||
* - @c REPLY_NO_REPLY no reply was received
|
* - @c REPLY_NO_REPLY no reply was received
|
||||||
* - @c REPLY_NOT_SENT command was not sent, implies no reply
|
* - @c REPLY_NOT_SENT command was not sent, implies no reply
|
||||||
* - @c REPLY_NOT_YET_SENT command is still waiting to be sent
|
* - @c REPLY_NOT_YET_SENT command is still waiting to be sent
|
||||||
* - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer still being
|
* - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer still
|
||||||
* processed)
|
* being processed)
|
||||||
* - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last
|
* - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last
|
||||||
* operation, data could not be processed. (transmission error)
|
* operation, data could not be processed. (transmission error)
|
||||||
* - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value)
|
* - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value)
|
||||||
|
@ -32,10 +32,10 @@ static const uint8_t RMAP_COMMAND_READ = ((1 << RMAP_COMMAND_BIT) | (1 << RMAP_C
|
|||||||
static const uint8_t RMAP_REPLY_WRITE =
|
static const uint8_t RMAP_REPLY_WRITE =
|
||||||
((1 << RMAP_COMMAND_BIT_WRITE) | (1 << RMAP_COMMAND_BIT_REPLY));
|
((1 << RMAP_COMMAND_BIT_WRITE) | (1 << RMAP_COMMAND_BIT_REPLY));
|
||||||
static const uint8_t RMAP_REPLY_READ = ((1 << RMAP_COMMAND_BIT_REPLY));
|
static const uint8_t RMAP_REPLY_READ = ((1 << RMAP_COMMAND_BIT_REPLY));
|
||||||
//#define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE) |
|
//#define RMAP_COMMAND_WRITE ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_WRITE)
|
||||||
//(1<<RMAP_COMMAND_BIT_REPLY)) #define RMAP_COMMAND_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT) |
|
//| (1<<RMAP_COMMAND_BIT_REPLY)) #define RMAP_COMMAND_WRITE_VERIFY ((1<<RMAP_COMMAND_BIT) |
|
||||||
//(1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define
|
//(1<<RMAP_COMMAND_BIT_WRITE) | (1<<RMAP_COMMAND_BIT_REPLY) | (1<<RMAP_COMMAND_BIT_VERIFY)) #define
|
||||||
//RMAP_COMMAND_READ ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY))
|
// RMAP_COMMAND_READ ((1<<RMAP_COMMAND_BIT) | (1<<RMAP_COMMAND_BIT_REPLY))
|
||||||
|
|
||||||
//#define RMAP_REPLY_WRITE ((1<<RMAP_COMMAND_BIT_WRITE) |
|
//#define RMAP_REPLY_WRITE ((1<<RMAP_COMMAND_BIT_WRITE) |
|
||||||
//(1<<RMAP_COMMAND_BIT_REPLY))
|
//(1<<RMAP_COMMAND_BIT_REPLY))
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user