diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3cc5ffd58..76542842f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -106,15 +106,17 @@ else()
)
endif()
-if(CMAKE_COMPILER_IS_GNUCXX)
- set(WARNING_FLAGS
- -Wall
- -Wextra
- -Wshadow=local
- -Wimplicit-fallthrough=1
- -Wno-unused-parameter
- -Wno-psabi
- )
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ if(NOT DEFINED FSFW_WARNING_FLAGS)
+ set(FSFW_WARNING_FLAGS
+ -Wall
+ -Wextra
+ -Wshadow=local
+ -Wimplicit-fallthrough=1
+ -Wno-unused-parameter
+ -Wno-psabi
+ )
+ endif()
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
@@ -135,8 +137,7 @@ target_include_directories(${LIB_FSFW_NAME} PRIVATE
${FSFW_CONFIG_PATH_ABSOLUTE}
)
-# Machine specific options can be set with the ABI_FLAGS variable.
target_compile_options(${LIB_FSFW_NAME} PRIVATE
- ${WARNING_FLAGS}
+ ${FSFW_WARNING_FLAGS}
${COMPILER_FLAGS}
)
diff --git a/README.md b/README.md
index 8552e0c81..fb3be429e 100644
--- a/README.md
+++ b/README.md
@@ -9,121 +9,40 @@ The initial version of the Flight Software Framework was developed during
the Flying Laptop Project by the University of Stuttgart in cooperation
with Airbus Defence and Space GmbH.
-## Intended Use
+## Quick facts
-The framework is designed for systems, which communicate with external devices, perform control loops, receive telecommands and send telemetry, and need to maintain a high level of availability.
-Therefore, a mode and health system provides control over the states of the software and the controlled devices.
-In addition, a simple mechanism of event based fault detection, isolation and recovery is implemented as well.
+The framework is designed for systems, which communicate with external devices, perform control loops, receive telecommands and send telemetry, and need to maintain a high level of availability. Therefore, a mode and health system provides control over the states of the software and the controlled devices. In addition, a simple mechanism of event based fault detection, isolation and recovery is implemented as well.
-The recommended hardware is a microprocessor with more than 1 MB of RAM and 1 MB of non-volatile Memory.
-For reference, current Applications use a Cobham Gaisler UT699 (LEON3FT), a ISISPACE IOBC or a Zynq-7020 SoC.
-The `fsfw` was also tested on the STM32H743ZI-Nucleo board.
+The FSFW provides abstraction layers for operating systems to provide a uniform operating system abstraction layer (OSAL). Some components of this OSAL are required internally by the FSFW but is also very useful for developers to implement the same application logic on different operating systems with a uniform interface.
-## How to Use
+Currently, the FSFW provides the following OSALs:
+
+- Linux
+- Host
+- FreeRTOS
+- RTEMS
+
+The recommended hardware is a microprocessor with more than 1 MB of RAM and 1 MB of non-volatile Memory. For reference, current applications use a Cobham Gaisler UT699 (LEON3FT), a ISISPACE IOBC or a Zynq-7020 SoC. The `fsfw` was also successfully run on the STM32H743ZI-Nucleo board and on a Raspberry Pi and is currently running on the active satellite mission Flying Laptop.
+
+## Getting started
+
+The [FSFW example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example) provides a good starting point and a demo to see the FSFW capabilities and build it with the Make or the CMake build system. It is recommended to evaluate the FSFW by building and playing around with the demo application.
-The [FSFW example](https://egit.irs.uni-stuttgart.de/fsfw/fsfw_example) provides a good starting point and a demo
-to see the FSFW capabilities and build it with the Make or the CMake build system.
Generally, the FSFW is included in a project by compiling the FSFW sources and providing
-a configuration folder and adding it to the include path.
+a configuration folder and adding it to the include path. There are some functions like `printChar` which are different depending on the target architecture and need to be implemented by the mission developer.
+
A template configuration folder was provided and can be copied into the project root to have
-a starting point. The [configuration section](doc/README-config.md#top) provides more specific information about
-the possible options.
+a starting point. The [configuration section](doc/README-config.md#top) provides more specific information about the possible options.
-## Structure
+## Index
-The general structure is driven by the usage of interfaces provided by objects.
-The FSFW uses C++11 as baseline. The intention behind this is that this C++ Standard should be widely available, even with older compilers.
-The FSFW uses dynamic allocation during the initialization but provides static containers during runtime.
-This simplifies the instantiation of objects and allows the usage of some standard containers.
-Dynamic Allocation after initialization is discouraged and different solutions are provided in the FSFW to achieve that.
-The fsfw uses run-time type information but exceptions are not allowed.
+[1. High-level overview](doc/README-highlevel.md#top)
+[2. Core components](doc/README-core.md#top)
+[3. OSAL overview](doc/README-osal.md#top)
+[4. PUS services](doc/README-pus.md#top)
+[5. Device Handler overview](doc/README-devicehandlers.md#top)
+[6. Controller overview](doc/README-controllers.md#top)
+[7. Local Data Pools](doc/README-localpools.md#top)
-### Failure Handling
-Functions should return a defined ReturnValue_t to signal to the caller that something has gone wrong.
-Returnvalues must be unique. For this the function HasReturnvaluesIF::makeReturnCode or the Macro MAKE_RETURN can be used.
-The CLASS_ID is a unique id for that type of object. See returnvalues/FwClassIds.
-### OSAL
-
-The FSFW provides operation system abstraction layers for Linux, FreeRTOS and RTEMS.
-A independent Host OSAL is in development which will provide abstraction for common type of
-host OSes (tested for Linux and Windows, not for MacOS yet).
-The OSAL provides periodic tasks, message queues, clocks and semaphores as well as mutexes.
-
-### Core Components
-
-The FSFW has following core components. More detailed informations can be found in the
-[core component section](doc/README-core.md#top):
-
-1. Tasks: Abstraction for different (periodic) task types like periodic tasks or tasks with fixed timeslots
-2. ObjectManager: This module stores all `SystemObjects` by mapping a provided unique object ID to the object handles.
-3. Static Stores: Different stores are provided to store data of variable size (like telecommands or small telemetry) in a pool structure without
- using dynamic memory allocation. These pools are allocated up front.
-3. Clock: This module provided common time related functions
-4. EventManager: This module allows routing of events generated by `SystemObjects`
-5. HealthTable: A component which stores the health states of objects
-
-### Static Ids in the framework
-
-Some parts of the framework use a static routing address for communication.
-An example setup of ids can be found in the example config in "defaultcft/fsfwconfig/objects/Factory::setStaticFrameworkObjectIds()".
-
-### Events
-
-Events are tied to objects. EventIds can be generated by calling the Macro MAKE_EVENT. This works analog to the returnvalues.
-Every object that needs own EventIds has to get a unique SUBSYSTEM_ID.
-Every SystemObject can call triggerEvent from the parent class.
-Therefore, event messages contain the specific EventId and the objectId of the object that has triggered.
-
-### Internal Communication
-
-Components communicate mostly over Message through Queues.
-Those queues are created by calling the singleton QueueFactory::instance()->create().
-
-### External Communication
-
-The external communication with the mission control system is mostly up to the user implementation.
-The FSFW provides PUS Services which can be used to but don't need to be used.
-The services can be seen as a conversion from a TC to a message based communication and back.
-
-#### CCSDS Frames, CCSDS Space Packets and PUS
-
-If the communication is based on CCSDS Frames and Space Packets, several classes can be used to distributed the packets to the corresponding services. Those can be found in tcdistribution.
-If Space Packets are used, a timestamper must be created.
-An example can be found in the timemanager folder, this uses CCSDSTime::CDS_short.
-
-#### Device Handlers
-
-DeviceHandlers are another important component of the FSFW.
-The idea is, to have a software counterpart of every physical device to provide a simple mode, health and commanding interface.
-By separating the underlying Communication Interface with DeviceCommunicationIF, a device handler (DH) can be tested on different hardware.
-The DH has mechanisms to monitor the communication with the physical device which allow for FDIR reaction.
-Device Handlers can be created by overriding `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).
-
-#### Modes, Health
-
-The two interfaces HasModesIF and HasHealthIF provide access for commanding and monitoring of components.
-On-board Mode Management is implement in hierarchy system.
-DeviceHandlers and Controllers are the lowest part of the hierarchy.
-The next layer are Assemblies. Those assemblies act as a component which handle redundancies of handlers.
-Assemblies share a common core with the next level which are the Subsystems.
-
-Those Assemblies are intended to act as auto-generated components from a database which describes the subsystem modes.
-The definitions contain transition and target tables which contain the DH, Assembly and Controller Modes to be commanded.
-Transition tables contain as many steps as needed to reach the mode from any other mode, e.g. a switch into any higher AOCS mode might first turn on the sensors, than the actuators and the controller as last component.
-The target table is used to describe the state that is checked continuously by the subsystem.
-All of this allows System Modes to be generated as Subsystem object as well from the same database.
-This System contains list of subsystem modes in the transition and target tables.
-Therefore, it allows a modular system to create system modes and easy commanding of those, because only the highest components must be commanded.
-
-The health state represents if the component is able to perform its tasks.
-This can be used to signal the system to avoid using this component instead of a redundant one.
-The on-board FDIR uses the health state for isolation and recovery.
-
-## Unit Tests
-
-Unit Tests are provided in the unittest folder. Those use the catch2 framework but do not include catch2 itself.
-See README.md in the unittest Folder.
\ No newline at end of file
diff --git a/controller/ExtendedControllerBase.cpp b/controller/ExtendedControllerBase.cpp
index 017acafe1..e0aec63a5 100644
--- a/controller/ExtendedControllerBase.cpp
+++ b/controller/ExtendedControllerBase.cpp
@@ -4,7 +4,7 @@
ExtendedControllerBase::ExtendedControllerBase(object_id_t objectId,
object_id_t parentId, size_t commandQueueDepth):
ControllerBase(objectId, parentId, commandQueueDepth),
- localPoolManager(this, commandQueue),
+ poolManager(this, commandQueue),
actionHelper(this, commandQueue) {
}
@@ -17,7 +17,7 @@ ReturnValue_t ExtendedControllerBase::executeAction(ActionId_t actionId,
ReturnValue_t ExtendedControllerBase::initializeLocalDataPool(
- LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
+ localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
// needs to be overriden and implemented by child class.
return HasReturnvaluesIF::RETURN_OK;
}
@@ -26,8 +26,8 @@ object_id_t ExtendedControllerBase::getObjectId() const {
return SystemObject::getObjectId();
}
-LocalDataPoolManager* ExtendedControllerBase::getHkManagerHandle() {
- return &localPoolManager;
+AccessPoolManagerIF* ExtendedControllerBase::getAccessorHandle() {
+ return &poolManager;
}
uint32_t ExtendedControllerBase::getPeriodicOperationFrequency() const {
@@ -40,7 +40,7 @@ ReturnValue_t ExtendedControllerBase::handleCommandMessage(
if(result == HasReturnvaluesIF::RETURN_OK) {
return result;
}
- return localPoolManager.handleHousekeepingMessage(message);
+ return poolManager.handleHousekeepingMessage(message);
}
void ExtendedControllerBase::handleQueue() {
@@ -64,7 +64,7 @@ void ExtendedControllerBase::handleQueue() {
continue;
}
- result = localPoolManager.handleHousekeepingMessage(&command);
+ result = poolManager.handleHousekeepingMessage(&command);
if (result == RETURN_OK) {
continue;
}
@@ -88,16 +88,16 @@ ReturnValue_t ExtendedControllerBase::initialize() {
return result;
}
- return localPoolManager.initialize(commandQueue);
+ return poolManager.initialize(commandQueue);
}
ReturnValue_t ExtendedControllerBase::initializeAfterTaskCreation() {
- return localPoolManager.initializeAfterTaskCreation();
+ return poolManager.initializeAfterTaskCreation();
}
ReturnValue_t ExtendedControllerBase::performOperation(uint8_t opCode) {
handleQueue();
- localPoolManager.performHkOperation();
+ poolManager.performHkOperation();
performControlOperation();
return RETURN_OK;
}
@@ -113,3 +113,7 @@ LocalPoolDataSetBase* ExtendedControllerBase::getDataSetHandle(sid_t sid) {
#endif
return nullptr;
}
+
+ProvidesDataPoolSubscriptionIF* ExtendedControllerBase::getSubscriptionInterface() {
+ return &poolManager;
+}
diff --git a/controller/ExtendedControllerBase.h b/controller/ExtendedControllerBase.h
index 02c5728e1..b27605141 100644
--- a/controller/ExtendedControllerBase.h
+++ b/controller/ExtendedControllerBase.h
@@ -32,10 +32,20 @@ public:
virtual ReturnValue_t performOperation(uint8_t opCode) override;
virtual ReturnValue_t initializeAfterTaskCreation() override;
+ /**
+ * Provides a subscription interface for objects which required updates on changed
+ * controller variables or datasets
+ * @return
+ */
+ ProvidesDataPoolSubscriptionIF* getSubscriptionInterface() override;
+
protected:
- LocalDataPoolManager localPoolManager;
+ LocalDataPoolManager poolManager;
ActionHelper actionHelper;
+ //! Accessor handle required for internal handling
+ AccessPoolManagerIF* getAccessorHandle() override;
+
/**
* Implemented by child class. Handle all command messages which are
* not health, mode, action or housekeeping messages.
@@ -60,9 +70,8 @@ protected:
/** HasLocalDatapoolIF overrides */
virtual object_id_t getObjectId() const override;
virtual ReturnValue_t initializeLocalDataPool(
- LocalDataPool& localDataPoolMap,
+ localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
- virtual LocalDataPoolManager* getHkManagerHandle() override;
virtual uint32_t getPeriodicOperationFrequency() const override;
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
};
diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp
index 05797012f..010697854 100644
--- a/datapool/PoolDataSetBase.cpp
+++ b/datapool/PoolDataSetBase.cpp
@@ -88,7 +88,8 @@ ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
{
if(protectEveryReadCommitCall) {
result = registeredVariables[count]->read(
- MutexIF::TimeoutType::WAITING, mutexTimeout);
+ timeoutTypeForSingleVars,
+ mutexTimeoutForSingleVars);
}
else {
result = registeredVariables[count]->readWithoutLock();
@@ -122,7 +123,8 @@ void PoolDataSetBase::handleAlreadyReadDatasetCommit(
!= PoolVariableIF::NO_PARAMETER) {
if(protectEveryReadCommitCall) {
registeredVariables[count]->commit(
- MutexIF::TimeoutType::WAITING, mutexTimeout);
+ timeoutTypeForSingleVars,
+ mutexTimeoutForSingleVars);
}
else {
registeredVariables[count]->commitWithoutLock();
@@ -144,7 +146,8 @@ ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(
!= PoolVariableIF::NO_PARAMETER) {
if(protectEveryReadCommitCall) {
result = registeredVariables[count]->commit(
- MutexIF::TimeoutType::WAITING, mutexTimeout);
+ timeoutTypeForSingleVars,
+ mutexTimeoutForSingleVars);
}
else {
result = registeredVariables[count]->commitWithoutLock();
@@ -214,8 +217,14 @@ void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) {
this->registeredVariables = variablesContainer;
}
-void PoolDataSetBase::setReadCommitProtectionBehaviour(
- bool protectEveryReadCommit, uint32_t mutexTimeout) {
- this->protectEveryReadCommitCall = protectEveryReadCommit;
- this->mutexTimeout = mutexTimeout;
+PoolVariableIF** PoolDataSetBase::getContainer() const {
+ return registeredVariables;
+}
+
+void PoolDataSetBase::setReadCommitProtectionBehaviour(
+ bool protectEveryReadCommit, MutexIF::TimeoutType timeoutType,
+ uint32_t mutexTimeout) {
+ this->protectEveryReadCommitCall = protectEveryReadCommit;
+ this->timeoutTypeForSingleVars = timeoutType;
+ this->mutexTimeoutForSingleVars = mutexTimeout;
}
diff --git a/datapool/PoolDataSetBase.h b/datapool/PoolDataSetBase.h
index 0528f40f3..65a6651e5 100644
--- a/datapool/PoolDataSetBase.h
+++ b/datapool/PoolDataSetBase.h
@@ -3,6 +3,7 @@
#include "PoolDataSetIF.h"
#include "PoolVariableIF.h"
+#include "../serialize/SerializeIF.h"
#include "../ipc/MutexIF.h"
/**
@@ -119,16 +120,16 @@ public:
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
SerializeIF::Endianness streamEndianness) override;
+ /**
+ * Can be used to individually protect every read and commit call.
+ * @param protectEveryReadCommit
+ * @param mutexTimeout
+ */
+ void setReadCommitProtectionBehaviour(bool protectEveryReadCommit,
+ MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING,
+ uint32_t mutexTimeout = 20);
protected:
- /**
- * Can be used to individually protect every read and commit call.
- * @param protectEveryReadCommit
- * @param mutexTimeout
- */
- void setReadCommitProtectionBehaviour(bool protectEveryReadCommit,
- uint32_t mutexTimeout = 20);
-
/**
* @brief The fill_count attribute ensures that the variables
* register in the correct array position and that the maximum
@@ -157,10 +158,12 @@ protected:
const size_t maxFillCount = 0;
void setContainer(PoolVariableIF** variablesContainer);
+ PoolVariableIF** getContainer() const;
private:
bool protectEveryReadCommitCall = false;
- uint32_t mutexTimeout = 20;
+ MutexIF::TimeoutType timeoutTypeForSingleVars;
+ uint32_t mutexTimeoutForSingleVars = 20;
ReturnValue_t readVariable(uint16_t count);
void handleAlreadyReadDatasetCommit(
diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp
index 5f5f56f25..a5867222b 100644
--- a/datapool/PoolEntry.cpp
+++ b/datapool/PoolEntry.cpp
@@ -1,32 +1,24 @@
#include "PoolEntry.h"
-#include "../serviceinterface/ServiceInterfaceStream.h"
+#include "../serviceinterface/ServiceInterface.h"
#include "../globalfunctions/arrayprinter.h"
#include
#include
template
-PoolEntry::PoolEntry(std::initializer_list initValue, uint8_t setLength,
- bool setValid ) : length(setLength), valid(setValid) {
+PoolEntry::PoolEntry(std::initializer_list initValue, bool setValid ):
+ length(initValue.size()), valid(setValid) {
this->address = new T[this->length];
if(initValue.size() == 0) {
std::memset(this->address, 0, this->getByteSize());
}
- else if (initValue.size() != setLength){
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::warning << "PoolEntry: setLength is not equal to initializer list"
- "length! Performing zero initialization with given setLength"
- << std::endl;
-#endif
- std::memset(this->address, 0, this->getByteSize());
- }
else {
std::copy(initValue.begin(), initValue.end(), this->address);
}
}
template
-PoolEntry::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) :
+PoolEntry::PoolEntry(T* initValue, uint8_t setLength, bool setValid):
length(setLength), valid(setValid) {
this->address = new T[this->length];
if (initValue != nullptr) {
@@ -70,14 +62,26 @@ bool PoolEntry::getValid() {
template
void PoolEntry::print() {
+ const char* validString = nullptr;
+ if(valid) {
+ validString = "Valid";
+ }
+ else {
+ validString = "Invalid";
+ }
#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::debug << "Pool Entry Validity: " <<
- (this->valid? " (valid) " : " (invalid) ") << std::endl;
-#endif
- arrayprinter::print(reinterpret_cast(address), length);
-#if FSFW_CPP_OSTREAM_ENABLED == 1
- sif::debug << std::dec << std::endl;
+ sif::info << "PoolEntry information." << std::endl;
+ sif::info << "PoolEntry validity: " << validString << std::endl;
+#else
+ sif::printInfo("PoolEntry information.\n");
+ sif::printInfo("PoolEntry validity: %s\n", validString);
#endif
+ arrayprinter::print(reinterpret_cast(address), getByteSize());
+}
+
+template
+inline T* PoolEntry::getDataPtr() {
+ return this->address;
}
template
diff --git a/datapool/PoolEntry.h b/datapool/PoolEntry.h
index 033db40d0..30940320c 100644
--- a/datapool/PoolEntry.h
+++ b/datapool/PoolEntry.h
@@ -35,24 +35,22 @@ public:
"uint8_t");
/**
* @brief In the classe's constructor, space is allocated on the heap and
- * potential init values are copied to that space.
+ * potential initialization values are copied to that space.
* @details
* Not passing any arguments will initialize an non-array pool entry
- * (setLength = 1) with an initial invalid state.
- * Please note that if an initializer list is passed, the correct
- * corresponding length should be passed too, otherwise a zero
- * initialization will be performed with the given setLength.
+ * with an initial invalid state and the value 0.
+ * Please note that if an initializer list is passed, the length of the
+ * initializer list needs to be correct for vector entries because
+ * required allocated space will be deduced from the initializer list length
+ * and the pool entry type.
* @param initValue
- * Initializer list with values to initialize with, for example {0,0} to
- * initialize the two entries to zero.
- * @param setLength
- * Defines the array length of this entry. Should be equal to the
- * intializer list length.
+ * Initializer list with values to initialize with, for example {0, 0} to
+ * initialize the a pool entry of a vector with two entries to 0.
* @param setValid
* Sets the initialization flag. It is invalid by default.
*/
- PoolEntry(std::initializer_list initValue = {}, uint8_t setLength = 1,
- bool setValid = false);
+ PoolEntry(std::initializer_list initValue = {0}, bool setValid = false);
+
/**
* @brief In the classe's constructor, space is allocated on the heap and
* potential init values are copied to that space.
@@ -66,9 +64,9 @@ public:
*/
PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false);
- //! Explicitely deleted copy ctor, copying is not allowed!
+ //! Explicitely deleted copy ctor, copying is not allowed.
PoolEntry(const PoolEntry&) = delete;
- //! Explicitely deleted copy assignment, copying is not allowed!
+ //! Explicitely deleted copy assignment, copying is not allowed.
PoolEntry& operator=(const PoolEntry&) = delete;
/**
@@ -82,21 +80,16 @@ public:
~PoolEntry();
/**
- * @brief This is the address pointing to the allocated memory.
+ * Return typed pointer to start of data.
+ * @return
*/
- T* address;
- /**
- * @brief This attribute stores the length information.
- */
- uint8_t length;
- /**
- * @brief Here, the validity information for a variable is stored.
- * Every entry (single variable or vector) has one valid flag.
- */
- uint8_t valid;
+ T* getDataPtr();
+
/**
* @brief getSize returns the array size of the entry.
- * @details A single parameter has size 1.
+ * @details
+ * For non-array pool entries return type size, for vector entries
+ * return type size times the number of entries.
*/
uint8_t getSize();
/**
@@ -123,8 +116,22 @@ public:
* information to the screen. It prints all array entries in a row.
*/
void print();
-
Type getType();
+
+private:
+ /**
+ * @brief This attribute stores the length information.
+ */
+ uint8_t length;
+ /**
+ * @brief Here, the validity information for a variable is stored.
+ * Every entry (single variable or vector) has one valid flag.
+ */
+ uint8_t valid;
+ /**
+ * @brief This is the address pointing to the allocated memory.
+ */
+ T* address;
};
#endif /* FSFW_DATAPOOL_POOLENTRY_H_ */
diff --git a/datapool/ReadCommitIF.h b/datapool/ReadCommitIF.h
index efe515944..e6355e824 100644
--- a/datapool/ReadCommitIF.h
+++ b/datapool/ReadCommitIF.h
@@ -1,8 +1,8 @@
#ifndef FSFW_DATAPOOL_READCOMMITIF_H_
#define FSFW_DATAPOOL_READCOMMITIF_H_
-#include
-#include
+#include "../returnvalues/HasReturnvaluesIF.h"
+#include "../ipc/MutexIF.h"
/**
* @brief Common interface for all software objects which employ read-commit
diff --git a/datapoollocal/AccessLocalPoolF.h b/datapoollocal/AccessLocalPoolF.h
new file mode 100644
index 000000000..f68189f65
--- /dev/null
+++ b/datapoollocal/AccessLocalPoolF.h
@@ -0,0 +1,27 @@
+#ifndef FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_
+#define FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_
+
+class LocalDataPoolManager;
+class MutexIF;
+
+/**
+ * @brief Accessor class which can be used by classes which like to use the pool manager.
+ */
+class AccessPoolManagerIF {
+public:
+ virtual ~AccessPoolManagerIF() {};
+
+ virtual MutexIF* getLocalPoolMutex() = 0;
+
+ /**
+ * Can be used to get a handle to the local data pool manager.
+ * This function is protected because it should only be used by the
+ * class imlementing the interface.
+ */
+ virtual LocalDataPoolManager* getHkManagerHandle() = 0;
+
+protected:
+
+};
+
+#endif /* FSFW_DATAPOOLLOCAL_ACCESSLOCALPOOLF_H_ */
diff --git a/datapoollocal/CMakeLists.txt b/datapoollocal/CMakeLists.txt
index c6b187cd2..e2db39eb0 100644
--- a/datapoollocal/CMakeLists.txt
+++ b/datapoollocal/CMakeLists.txt
@@ -5,4 +5,6 @@ target_sources(${LIB_FSFW_NAME}
LocalPoolDataSetBase.cpp
LocalPoolObjectBase.cpp
SharedLocalDataSet.cpp
-)
\ No newline at end of file
+)
+
+add_subdirectory(internal)
\ No newline at end of file
diff --git a/datapoollocal/HasLocalDataPoolIF.h b/datapoollocal/HasLocalDataPoolIF.h
index 7707fab84..3d822650b 100644
--- a/datapoollocal/HasLocalDataPoolIF.h
+++ b/datapoollocal/HasLocalDataPoolIF.h
@@ -1,105 +1,66 @@
#ifndef FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
#define FSFW_DATAPOOLLOCAL_HASLOCALDATAPOOLIF_H_
-#include "locPoolDefinitions.h"
+#include "localPoolDefinitions.h"
#include "../datapool/PoolEntryIF.h"
+#include "../serviceinterface/ServiceInterface.h"
#include "../ipc/MessageQueueSenderIF.h"
#include "../housekeeping/HousekeepingMessage.h"
#include