Compare commits
208 Commits
mueller/pr
...
source/vor
Author | SHA1 | Date | |
---|---|---|---|
2a7e82bd28 | |||
49d4b6ebc7 | |||
9e0a905096 | |||
d5dedce294 | |||
e535bc1427 | |||
18105e2d16 | |||
ebc11bd777 | |||
3d4daa51d5 | |||
3905b72b08 | |||
90a3e2b8c5 | |||
ea9288d848 | |||
78442a8b92 | |||
03539a6991 | |||
6ac36cec15 | |||
d58fc5c6f7 | |||
be6060ec94 | |||
d8bf1931cc | |||
2198406714 | |||
4213e2e081 | |||
e188e65897 | |||
652c60c362 | |||
c16675f69a | |||
4bffcf17fb | |||
036a887ea3 | |||
a87a8f527f | |||
b74fbbddb9 | |||
88cec7ddb1 | |||
0defc6a7d8 | |||
32f22dd974 | |||
40d0568062 | |||
86c48cb7d8 | |||
136a68000b | |||
06e7f286d6 | |||
be9d0a61f4 | |||
e1c17409d9 | |||
b400deed1a | |||
307c954007 | |||
aca0c94c51 | |||
7a4a2f986a | |||
52f56ca798 | |||
639e61cebf | |||
8f2a7b9e68 | |||
ced61da357 | |||
ef2a44c683 | |||
9f12f232bc | |||
ae486f5330 | |||
14f86422e3 | |||
d34ee48126 | |||
170a2c58f0 | |||
72c9ef1089 | |||
85d24b9dfe | |||
97b01f837c | |||
6b2b788308 | |||
5fb5cea949 | |||
26b5ef6dac | |||
d1e922eecf | |||
83484237ae | |||
1025a3cecc | |||
90e299977b | |||
133ed9586b | |||
9f4f8d945c | |||
986bb154be | |||
ce5a241f4f | |||
56c8f4877d | |||
6f40a8c622 | |||
856f1efd6b | |||
6a0a2675b1 | |||
05393b900b | |||
c3172d7308 | |||
6e79972086 | |||
45430e8586 | |||
89accf8940 | |||
06b481b02f | |||
8c68895c06 | |||
3cd946fef8 | |||
d311c49998 | |||
5400e38126 | |||
bfd49caab4 | |||
053b472157 | |||
1ed5da3a12 | |||
ce3e4a1176 | |||
fc0d42e3e0 | |||
644896245f | |||
8a56964dab | |||
19cbac923f | |||
a5a53e7f9b | |||
f6d2549534 | |||
e10cf44c8d | |||
b4bc05fb12 | |||
93d57c0784 | |||
e935b8bd04 | |||
d51b3b68e4 | |||
4507bdfb69 | |||
1cc50639c7 | |||
0c9c9c581b | |||
bf63ba15fe | |||
3c7ac60dbe | |||
2cada2df4a | |||
ffe2a7bffe | |||
56aaa29985 | |||
31e5577763 | |||
d8e9e34ad9 | |||
cda3130b34 | |||
b412ef587a | |||
0c45522540 | |||
72f3b16c24 | |||
534fddd2c6 | |||
482aedfaf2 | |||
5dc2133c3a | |||
39d5fe34bb | |||
372493828d | |||
ed7b4e2a3a | |||
860cdba94d | |||
887f8331a2 | |||
dc43222db8 | |||
dd8543fedd | |||
9c766c123d | |||
cef5fda379 | |||
38b0792cdc | |||
639b517eda | |||
7014833c1c | |||
3a573c1b4c | |||
c0808e71d9 | |||
d466921aa0 | |||
1cb241ca0c | |||
11c64a91a3 | |||
966c9c3993 | |||
f8fb370ae7 | |||
764608005b | |||
ef13249405 | |||
9361568b45 | |||
7259a13569 | |||
e5cea3ead0 | |||
70454b4640 | |||
a9a23d7623 | |||
c5bb18a788 | |||
f15424be4f | |||
0be418a553 | |||
1cf5991101 | |||
ca74e0c0f2 | |||
9951b59627 | |||
dd5b301980 | |||
5de68fcc6e | |||
112779d91f | |||
98449ddc7f | |||
19b4332801 | |||
35b9346c2b | |||
4f278b610d | |||
7eb250a90a | |||
df7be467eb | |||
0bf8e97830 | |||
80c6eff8a6 | |||
deb8ce3744 | |||
e8a1912fda | |||
f4ad38f07f | |||
7ceb6f3c96 | |||
fb0834ffe1 | |||
b8e7b12a63 | |||
a159e60a90 | |||
fadebe2eb4 | |||
614deea323 | |||
33eae034c7 | |||
25ff8784cf | |||
1181ebcbda | |||
684dd67f63 | |||
6be607e422 | |||
07247dbf40 | |||
cf3190a904 | |||
2093329481 | |||
c30cae3431 | |||
ea904642d1 | |||
b78b3ac68a | |||
225e1b98a0 | |||
3bd83c00f5 | |||
fd100cb994 | |||
f4c925e671 | |||
7f08bb3506 | |||
36dbf6e1ce | |||
1820ad14b7 | |||
c8983650f7 | |||
bb650ac784 | |||
ff47fa191a | |||
520ed881bb | |||
ce554c615c | |||
eacedf7ed6 | |||
74b8c3eef4 | |||
62644bdfc9 | |||
1ec1d057b8 | |||
7126c19ee0 | |||
574d6051ba | |||
0c0c8ec448 | |||
eb9f43d202 | |||
0cb2abfe7e | |||
abe7239018 | |||
a1f36e6ae5 | |||
db34c45b67 | |||
9c958c06fe | |||
81ab5a6914 | |||
2b740a3c0f | |||
ee23a7c0b5 | |||
511c0db8c7 | |||
ac4275ef05 | |||
bfb0234d41 | |||
ea41514553 | |||
59812199fd | |||
029b2133e6 | |||
e03aff3731 | |||
368ef242ff |
@ -1,6 +1,6 @@
|
||||
#include <framework/action/ActionHelper.h>
|
||||
#include <framework/action/HasActionsIF.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include "ActionHelper.h"
|
||||
#include "HasActionsIF.h"
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
|
||||
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) :
|
||||
owner(setOwner), queueToUse(useThisQueue), ipcStore(nullptr) {
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef ACTIONHELPER_H_
|
||||
#define ACTIONHELPER_H_
|
||||
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/serialize/SerializeIF.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
#include "ActionMessage.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
/**
|
||||
* \brief Action Helper is a helper class which handles action messages
|
||||
*
|
||||
@ -35,7 +35,7 @@ public:
|
||||
ReturnValue_t handleActionMessage(CommandMessage* command);
|
||||
/**
|
||||
* Helper initialize function. Must be called before use of any other helper function
|
||||
* @param queueToUse_ Pointer to the messageQueue to be used
|
||||
* @param queueToUse_ Pointer to the messageQueue to be used, optional if queue was set in constructor
|
||||
* @return Returns RETURN_OK if successful
|
||||
*/
|
||||
ReturnValue_t initialize(MessageQueueIF* queueToUse_ = nullptr);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include "ActionMessage.h"
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
#include "../storagemanager/StorageManagerIF.h"
|
||||
|
||||
ActionMessage::ActionMessage() {
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
#ifndef ACTIONMESSAGE_H_
|
||||
#define ACTIONMESSAGE_H_
|
||||
|
||||
#include <framework/ipc/CommandMessage.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include "../ipc/CommandMessage.h"
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
#include "../storagemanager/StorageManagerIF.h"
|
||||
typedef uint32_t ActionId_t;
|
||||
|
||||
class ActionMessage {
|
||||
private:
|
||||
ActionMessage();
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = messagetypes::ACTION;
|
||||
static const uint8_t MESSAGE_ID = MESSAGE_TYPE::ACTION;
|
||||
static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1);
|
||||
static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2);
|
||||
static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3);
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/action/CommandActionHelper.h>
|
||||
#include <framework/action/CommandsActionsIF.h>
|
||||
#include <framework/action/HasActionsIF.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include "ActionMessage.h"
|
||||
#include "CommandActionHelper.h"
|
||||
#include "CommandsActionsIF.h"
|
||||
#include "HasActionsIF.h"
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
|
||||
CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner) :
|
||||
owner(setOwner), queueToUse(NULL), ipcStore(
|
||||
|
@ -1,12 +1,12 @@
|
||||
#ifndef COMMANDACTIONHELPER_H_
|
||||
#define COMMANDACTIONHELPER_H_
|
||||
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/serialize/SerializeIF.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
#include "ActionMessage.h"
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
#include "../storagemanager/StorageManagerIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
|
||||
class CommandsActionsIF;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef COMMANDSACTIONSIF_H_
|
||||
#define COMMANDSACTIONSIF_H_
|
||||
|
||||
#include <framework/action/CommandActionHelper.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
#include "CommandActionHelper.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
|
||||
/**
|
||||
* Interface to separate commanding actions of other objects.
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef FRAMEWORK_ACTION_HASACTIONSIF_H_
|
||||
#define FRAMEWORK_ACTION_HASACTIONSIF_H_
|
||||
|
||||
#include <framework/action/ActionHelper.h>
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/action/SimpleActionHelper.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
#include "ActionHelper.h"
|
||||
#include "ActionMessage.h"
|
||||
#include "SimpleActionHelper.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
/**
|
||||
* @brief
|
||||
* Interface for component which uses actions
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <framework/action/HasActionsIF.h>
|
||||
#include <framework/action/SimpleActionHelper.h>
|
||||
#include "HasActionsIF.h"
|
||||
#include "SimpleActionHelper.h"
|
||||
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner,
|
||||
MessageQueueIF* useThisQueue) :
|
||||
ActionHelper(setOwner, useThisQueue), isExecuting(false), lastCommander(
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef SIMPLEACTIONHELPER_H_
|
||||
#define SIMPLEACTIONHELPER_H_
|
||||
|
||||
#include <framework/action/ActionHelper.h>
|
||||
#include "ActionHelper.h"
|
||||
|
||||
class SimpleActionHelper: public ActionHelper {
|
||||
public:
|
||||
|
@ -1,15 +1,15 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_ARRAYLIST_H_
|
||||
#define FRAMEWORK_CONTAINER_ARRAYLIST_H_
|
||||
#ifndef ARRAYLIST_H_
|
||||
#define ARRAYLIST_H_
|
||||
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/serialize/SerializeAdapter.h>
|
||||
#include <framework/serialize/SerializeIF.h>
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
|
||||
/**
|
||||
* @brief A List that stores its values in an array.
|
||||
* @details
|
||||
* The underlying storage is an array that can be allocated by the class
|
||||
* itself or supplied via ctor.
|
||||
* A List that stores its values in an array.
|
||||
*
|
||||
* The backend is an array that can be allocated by the class itself or supplied via ctor.
|
||||
*
|
||||
*
|
||||
* @ingroup container
|
||||
*/
|
||||
@ -20,13 +20,81 @@ public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
||||
|
||||
/**
|
||||
* Copying is forbiden by declaring copy ctor and copy assignment deleted
|
||||
* It is too ambigous in this case.
|
||||
* (Allocate a new backend? Use the same? What to do in an modifying call?)
|
||||
*/
|
||||
ArrayList(const ArrayList& other) = delete;
|
||||
const ArrayList& operator=(const ArrayList& other) = delete;
|
||||
/**
|
||||
* An Iterator to go trough an ArrayList
|
||||
*
|
||||
* It stores a pointer to an element and increments the
|
||||
* pointer when incremented itself.
|
||||
*/
|
||||
class Iterator {
|
||||
public:
|
||||
/**
|
||||
* Empty ctor, points to NULL
|
||||
*/
|
||||
Iterator() :
|
||||
value(0) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Iterator to point to an element
|
||||
*
|
||||
* @param initialize
|
||||
*/
|
||||
Iterator(T *initialize) {
|
||||
value = initialize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current element the iterator points to
|
||||
*/
|
||||
T *value;
|
||||
|
||||
Iterator& operator++() {
|
||||
value++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) {
|
||||
Iterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Iterator& operator--() {
|
||||
value--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator--(int) {
|
||||
Iterator tmp(*this);
|
||||
operator--();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T operator*() {
|
||||
return *value;
|
||||
}
|
||||
|
||||
T *operator->() {
|
||||
return value;
|
||||
}
|
||||
|
||||
const T *operator->() const{
|
||||
return value;
|
||||
}
|
||||
|
||||
//SHOULDDO this should be implemented as non-member
|
||||
bool operator==(const typename ArrayList<T, count_t>::Iterator& other) const{
|
||||
return (value == other.value);
|
||||
}
|
||||
|
||||
//SHOULDDO this should be implemented as non-member
|
||||
bool operator!=(const typename ArrayList<T, count_t>::Iterator& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
/**
|
||||
* Number of Elements stored in this List
|
||||
@ -67,78 +135,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An Iterator to go trough an ArrayList
|
||||
*
|
||||
* It stores a pointer to an element and increments the
|
||||
* pointer when incremented itself.
|
||||
*/
|
||||
class Iterator {
|
||||
public:
|
||||
/**
|
||||
* Empty ctor, points to NULL
|
||||
*/
|
||||
Iterator(): value(0) {}
|
||||
|
||||
/**
|
||||
* Initializes the Iterator to point to an element
|
||||
*
|
||||
* @param initialize
|
||||
*/
|
||||
Iterator(T *initialize) {
|
||||
value = initialize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current element the iterator points to
|
||||
*/
|
||||
T *value;
|
||||
|
||||
Iterator& operator++() {
|
||||
value++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int) {
|
||||
Iterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Iterator& operator--() {
|
||||
value--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator--(int) {
|
||||
Iterator tmp(*this);
|
||||
operator--();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T operator*() {
|
||||
return *value;
|
||||
}
|
||||
|
||||
T *operator->() {
|
||||
return value;
|
||||
}
|
||||
|
||||
const T *operator->() const{
|
||||
return value;
|
||||
}
|
||||
|
||||
//SHOULDDO this should be implemented as non-member
|
||||
bool operator==(const typename ArrayList<T, count_t>::Iterator& other) const{
|
||||
return (value == other.value);
|
||||
}
|
||||
|
||||
//SHOULDDO this should be implemented as non-member
|
||||
bool operator!=(const typename ArrayList<T, count_t>::Iterator& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterator pointing to the first stored elmement
|
||||
*
|
||||
@ -227,7 +223,19 @@ public:
|
||||
count_t remaining() {
|
||||
return (maxSize_ - size);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* This is the copy constructor
|
||||
*
|
||||
* It is private, as copying is too ambigous in this case. (Allocate a new backend? Use the same?
|
||||
* What to do in an modifying call?)
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
ArrayList(const ArrayList& other) :
|
||||
size(other.size), entries(other.entries), maxSize_(other.maxSize_), allocated(
|
||||
false) {
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
* pointer to the array in which the entries are stored
|
||||
@ -242,6 +250,6 @@ protected:
|
||||
* true if the array was allocated and needs to be deleted in the destructor.
|
||||
*/
|
||||
bool allocated;
|
||||
};
|
||||
|
||||
};
|
||||
#endif /* ARRAYLIST_H_ */
|
||||
|
@ -1,42 +0,0 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_DYNAMICFIFO_H_
|
||||
#define FRAMEWORK_CONTAINER_DYNAMICFIFO_H_
|
||||
|
||||
#include <framework/container/FIFOBase.h>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief Simple First-In-First-Out data structure. The maximum size
|
||||
* can be set in the constructor.
|
||||
* @details
|
||||
* The maximum capacity can be determined at run-time, so this container
|
||||
* performs dynamic memory allocation!
|
||||
* The public interface of FIFOBase exposes the user interface for the FIFO.
|
||||
* @tparam T Entry Type
|
||||
* @tparam capacity Maximum capacity
|
||||
*/
|
||||
template<typename T>
|
||||
class DynamicFIFO: public FIFOBase<T> {
|
||||
public:
|
||||
DynamicFIFO(size_t maxCapacity): FIFOBase<T>(nullptr, maxCapacity),
|
||||
fifoVector(maxCapacity) {
|
||||
// trying to pass the pointer of the uninitialized vector
|
||||
// to the FIFOBase constructor directly lead to a super evil bug.
|
||||
// So we do it like this now.
|
||||
this->setData(fifoVector.data());
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Custom copy constructor which prevents setting the
|
||||
* underlying pointer wrong.
|
||||
*/
|
||||
DynamicFIFO(const DynamicFIFO& other): FIFOBase<T>(other),
|
||||
fifoVector(other.maxCapacity) {
|
||||
this->setData(fifoVector.data());
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::vector<T> fifoVector;
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ */
|
@ -1,34 +1,82 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_FIFO_H_
|
||||
#define FRAMEWORK_CONTAINER_FIFO_H_
|
||||
#ifndef FIFO_H_
|
||||
#define FIFO_H_
|
||||
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/container/FIFOBase.h>
|
||||
#include <array>
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
* @brief Simple First-In-First-Out data structure with size fixed at
|
||||
* compile time
|
||||
* @details
|
||||
* Performs no dynamic memory allocation.
|
||||
* The public interface of FIFOBase exposes the user interface for the FIFO.
|
||||
* @brief Simple First-In-First-Out data structure
|
||||
* @tparam T Entry Type
|
||||
* @tparam capacity Maximum capacity
|
||||
*/
|
||||
template<typename T, size_t capacity>
|
||||
class FIFO: public FIFOBase<T> {
|
||||
public:
|
||||
FIFO(): FIFOBase<T>(fifoArray.data(), capacity) {};
|
||||
template<typename T, uint8_t capacity>
|
||||
class FIFO {
|
||||
private:
|
||||
uint8_t readIndex, writeIndex, currentSize;
|
||||
T data[capacity];
|
||||
|
||||
/**
|
||||
* @brief Custom copy constructor to set pointer correctly.
|
||||
* @param other
|
||||
*/
|
||||
FIFO(const FIFO& other): FIFOBase<T>(other) {
|
||||
this->setData(fifoArray.data());
|
||||
uint8_t next(uint8_t current) {
|
||||
++current;
|
||||
if (current == capacity) {
|
||||
current = 0;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
public:
|
||||
FIFO() :
|
||||
readIndex(0), writeIndex(0), currentSize(0) {
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<T, capacity> fifoArray;
|
||||
bool empty() {
|
||||
return (currentSize == 0);
|
||||
}
|
||||
|
||||
bool full() {
|
||||
return (currentSize == capacity);
|
||||
}
|
||||
|
||||
uint8_t size(){
|
||||
return currentSize;
|
||||
}
|
||||
|
||||
ReturnValue_t insert(T value) {
|
||||
if (full()) {
|
||||
return FULL;
|
||||
} else {
|
||||
data[writeIndex] = value;
|
||||
writeIndex = next(writeIndex);
|
||||
++currentSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t retrieve(T *value) {
|
||||
if (empty()) {
|
||||
return EMPTY;
|
||||
} else {
|
||||
*value = data[readIndex];
|
||||
readIndex = next(readIndex);
|
||||
--currentSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t peek(T * value) {
|
||||
if(empty()) {
|
||||
return EMPTY;
|
||||
} else {
|
||||
*value = data[readIndex];
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t pop() {
|
||||
T value;
|
||||
return this->retrieve(&value);
|
||||
}
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
|
||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINERS_STATICFIFO_H_ */
|
||||
#endif /* FIFO_H_ */
|
||||
|
@ -1,65 +0,0 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_FIFOBASE_H_
|
||||
#define FRAMEWORK_CONTAINER_FIFOBASE_H_
|
||||
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
template <typename T>
|
||||
class FIFOBase {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS;
|
||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2);
|
||||
|
||||
/** Default ctor, takes pointer to first entry of underlying container
|
||||
* and maximum capacity */
|
||||
FIFOBase(T* values, const size_t maxCapacity);
|
||||
|
||||
/**
|
||||
* Insert value into FIFO
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t insert(T value);
|
||||
/**
|
||||
* Retrieve item from FIFO. This removes the item from the FIFO.
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t retrieve(T *value);
|
||||
/**
|
||||
* Retrieve item from FIFO without removing it from FIFO.
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t peek(T * value);
|
||||
/**
|
||||
* Remove item from FIFO.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t pop();
|
||||
|
||||
bool empty();
|
||||
bool full();
|
||||
size_t size();
|
||||
|
||||
|
||||
size_t getMaxCapacity() const;
|
||||
|
||||
protected:
|
||||
void setData(T* data);
|
||||
size_t maxCapacity = 0;
|
||||
|
||||
T* values;
|
||||
|
||||
size_t readIndex = 0;
|
||||
size_t writeIndex = 0;
|
||||
size_t currentSize = 0;
|
||||
|
||||
size_t next(size_t current);
|
||||
};
|
||||
|
||||
#include <framework/container/FIFOBase.tpp>
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_FIFOBASE_H_ */
|
@ -1,87 +0,0 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_FIFOBASE_TPP_
|
||||
#define FRAMEWORK_CONTAINER_FIFOBASE_TPP_
|
||||
|
||||
#ifndef FRAMEWORK_CONTAINER_FIFOBASE_H_
|
||||
#error Include FIFOBase.h before FIFOBase.tpp!
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline FIFOBase<T>::FIFOBase(T* values, const size_t maxCapacity):
|
||||
maxCapacity(maxCapacity), values(values){};
|
||||
|
||||
template<typename T>
|
||||
inline ReturnValue_t FIFOBase<T>::insert(T value) {
|
||||
if (full()) {
|
||||
return FULL;
|
||||
} else {
|
||||
values[writeIndex] = value;
|
||||
writeIndex = next(writeIndex);
|
||||
++currentSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline ReturnValue_t FIFOBase<T>::retrieve(T* value) {
|
||||
if (empty()) {
|
||||
return EMPTY;
|
||||
} else {
|
||||
*value = values[readIndex];
|
||||
readIndex = next(readIndex);
|
||||
--currentSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline ReturnValue_t FIFOBase<T>::peek(T* value) {
|
||||
if(empty()) {
|
||||
return EMPTY;
|
||||
} else {
|
||||
*value = values[readIndex];
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline ReturnValue_t FIFOBase<T>::pop() {
|
||||
T value;
|
||||
return this->retrieve(&value);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline bool FIFOBase<T>::empty() {
|
||||
return (currentSize == 0);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline bool FIFOBase<T>::full() {
|
||||
return (currentSize == maxCapacity);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline size_t FIFOBase<T>::size() {
|
||||
return currentSize;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline size_t FIFOBase<T>::next(size_t current) {
|
||||
++current;
|
||||
if (current == maxCapacity) {
|
||||
current = 0;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline size_t FIFOBase<T>::getMaxCapacity() const {
|
||||
return maxCapacity;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void FIFOBase<T>::setData(T *data) {
|
||||
this->values = data;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,42 +1,19 @@
|
||||
#ifndef FIXEDARRAYLIST_H_
|
||||
#define FIXEDARRAYLIST_H_
|
||||
|
||||
#include <framework/container/ArrayList.h>
|
||||
|
||||
#include "ArrayList.h"
|
||||
/**
|
||||
* @brief Array List with a fixed maximum size
|
||||
* @ingroup container
|
||||
* \ingroup container
|
||||
*/
|
||||
template<typename T, uint32_t MAX_SIZE, typename count_t = uint8_t>
|
||||
class FixedArrayList: public ArrayList<T, count_t> {
|
||||
private:
|
||||
T data[MAX_SIZE];
|
||||
public:
|
||||
/**
|
||||
* (Robin) Maybe we should also implement move assignment and move ctor.
|
||||
* Or at least delete them.
|
||||
*/
|
||||
FixedArrayList() :
|
||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||
}
|
||||
|
||||
// (Robin): We could create a constructor to initialize the fixed array list
|
||||
// with data and the known size field
|
||||
// so it can be used for serialization too (with SerialFixedArrrayListAdapter)
|
||||
// is this feasible?
|
||||
/**
|
||||
* Initialize a fixed array list with data and number of data fields.
|
||||
* Endianness of entries can be swapped optionally.
|
||||
* @param data_
|
||||
* @param count
|
||||
* @param swapArrayListEndianess
|
||||
*/
|
||||
FixedArrayList(T * data_, count_t count):
|
||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||
memcpy(this->data, data_, count * sizeof(T));
|
||||
this->size = count;
|
||||
}
|
||||
|
||||
FixedArrayList(const FixedArrayList& other) :
|
||||
ArrayList<T, count_t>(data, MAX_SIZE) {
|
||||
memcpy(this->data, other.data, sizeof(this->data));
|
||||
|
@ -1,16 +1,12 @@
|
||||
#ifndef FIXEDMAP_H_
|
||||
#define FIXEDMAP_H_
|
||||
|
||||
#include <framework/container/ArrayList.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include "ArrayList.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* @brief Map implementation for maps with a pre-defined size.
|
||||
* @details Can be initialized with desired maximum size.
|
||||
* Iterator is used to access <key,value> pair and
|
||||
* iterate through map entries. Complexity O(n).
|
||||
* @ingroup container
|
||||
* \ingroup container
|
||||
*/
|
||||
template<typename key_t, typename T>
|
||||
class FixedMap: public SerializeIF {
|
||||
@ -56,24 +52,12 @@ public:
|
||||
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
|
||||
}
|
||||
|
||||
// -> operator overloaded, can be used to access value
|
||||
T *operator->() {
|
||||
return &ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
|
||||
}
|
||||
|
||||
// Can be used to access the key of the iterator
|
||||
key_t first() {
|
||||
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->first;
|
||||
}
|
||||
|
||||
// Alternative to access value, similar to std::map implementation
|
||||
T second() {
|
||||
return ArrayList<std::pair<key_t, T>, uint32_t>::Iterator::value->second;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Iterator begin() const {
|
||||
return Iterator(&theMap[0]);
|
||||
}
|
||||
@ -88,10 +72,10 @@ public:
|
||||
|
||||
ReturnValue_t insert(key_t key, T value, Iterator *storedValue = NULL) {
|
||||
if (exists(key) == HasReturnvaluesIF::RETURN_OK) {
|
||||
return FixedMap::KEY_ALREADY_EXISTS;
|
||||
return KEY_ALREADY_EXISTS;
|
||||
}
|
||||
if (_size == theMap.maxSize()) {
|
||||
return FixedMap::MAP_FULL;
|
||||
return MAP_FULL;
|
||||
}
|
||||
theMap[_size].first = key;
|
||||
theMap[_size].second = value;
|
||||
@ -103,7 +87,7 @@ public:
|
||||
}
|
||||
|
||||
ReturnValue_t insert(std::pair<key_t, T> pair) {
|
||||
return insert(pair.first, pair.second);
|
||||
return insert(pair.fist, pair.second);
|
||||
}
|
||||
|
||||
ReturnValue_t exists(key_t key) const {
|
||||
@ -164,16 +148,6 @@ public:
|
||||
return theMap.maxSize();
|
||||
}
|
||||
|
||||
|
||||
bool full() {
|
||||
if(_size == theMap.maxSize()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) const {
|
||||
ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
||||
#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
||||
|
||||
#include <framework/container/ArrayList.h>
|
||||
#include "ArrayList.h"
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
/**
|
||||
@ -10,7 +10,7 @@
|
||||
template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
|
||||
class FixedOrderedMultimap {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MULTIMAP;
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::FIXED_MAP;
|
||||
static const ReturnValue_t KEY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t MAP_FULL = MAKE_RETURN_CODE(0x02);
|
||||
static const ReturnValue_t KEY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
|
||||
#define FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
|
||||
|
||||
#include <framework/container/ArrayList.h>
|
||||
#include <framework/container/SinglyLinkedList.h>
|
||||
#include "ArrayList.h"
|
||||
#include "SinglyLinkedList.h"
|
||||
|
||||
template<typename T, typename count_t = uint8_t>
|
||||
class HybridIterator: public LinkedElement<T>::Iterator,
|
||||
|
@ -1,34 +1,27 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_
|
||||
#define FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_
|
||||
|
||||
#include <framework/container/ArrayList.h>
|
||||
#include <framework/globalfunctions/CRC.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/serialize/SerialArrayListAdapter.h>
|
||||
#include "ArrayList.h"
|
||||
#include "../globalfunctions/CRC.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../serialize/SerialArrayListAdapter.h"
|
||||
#include <cmath>
|
||||
|
||||
/**
|
||||
* Index is the Type used for the list of indices.
|
||||
*
|
||||
* @tparam T Type which destribes the index. Needs to be a child of SerializeIF
|
||||
* to be able to make it persistent
|
||||
*/
|
||||
template<typename T>
|
||||
class Index: public SerializeIF{
|
||||
/**
|
||||
*
|
||||
* Index is the Type used for the list of indices. The template parameter is the type which describes the index, it needs to be a child of SerializeIF to be able to make it persistent
|
||||
*/
|
||||
static_assert(std::is_base_of<SerializeIF,T>::value,
|
||||
"Wrong Type for Index, Type must implement SerializeIF");
|
||||
static_assert(std::is_base_of<SerializeIF,T>::value,"Wrong Type for Index, Type must implement SerializeIF");
|
||||
public:
|
||||
Index():blockStartAddress(0),size(0),storedPackets(0){}
|
||||
|
||||
Index(uint32_t startAddress):blockStartAddress(startAddress),
|
||||
size(0),storedPackets(0) {
|
||||
Index(uint32_t startAddress):blockStartAddress(startAddress),size(0),storedPackets(0){
|
||||
|
||||
}
|
||||
|
||||
void setBlockStartAddress(uint32_t newAddress) {
|
||||
void setBlockStartAddress(uint32_t newAddress){
|
||||
this->blockStartAddress = newAddress;
|
||||
}
|
||||
|
||||
@ -40,7 +33,7 @@ public:
|
||||
return &indexType;
|
||||
}
|
||||
|
||||
T* modifyIndexType() {
|
||||
T* modifyIndexType(){
|
||||
return &indexType;
|
||||
}
|
||||
/**
|
||||
@ -135,35 +128,26 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Indexed Ring Memory Array is a class for a ring memory with indices.
|
||||
* @details
|
||||
* It assumes that the newest data comes in last
|
||||
* It uses the currentWriteBlock as pointer to the current writing position
|
||||
* The currentReadBlock must be set manually
|
||||
* @tparam T
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
class IndexedRingMemoryArray: public SerializeIF, public ArrayList<Index<T>, uint32_t>{
|
||||
/**
|
||||
*
|
||||
* Indexed Ring Memory Array is a class for a ring memory with indices. It assumes that the newest data comes in last
|
||||
* It uses the currentWriteBlock as pointer to the current writing position
|
||||
* The currentReadBlock must be set manually
|
||||
*/
|
||||
public:
|
||||
IndexedRingMemoryArray(uint32_t startAddress, uint32_t size, uint32_t bytesPerBlock,
|
||||
SerializeIF* additionalInfo, bool overwriteOld):
|
||||
ArrayList<Index<T>,uint32_t>(NULL,(uint32_t)10,(uint32_t)0),totalSize(size),
|
||||
indexAddress(startAddress),currentReadSize(0),currentReadBlockSizeCached(0),
|
||||
lastBlockToReadSize(0), additionalInfo(additionalInfo),overwriteOld(overwriteOld)
|
||||
{
|
||||
IndexedRingMemoryArray(uint32_t startAddress, uint32_t size, uint32_t bytesPerBlock, SerializeIF* additionalInfo,
|
||||
bool overwriteOld) :ArrayList<Index<T>,uint32_t>(NULL,(uint32_t)10,(uint32_t)0),totalSize(size),indexAddress(startAddress),currentReadSize(0),currentReadBlockSizeCached(0),lastBlockToReadSize(0), additionalInfo(additionalInfo),overwriteOld(overwriteOld){
|
||||
|
||||
//Calculate the maximum number of indices needed for this blocksize
|
||||
uint32_t maxNrOfIndices = floor(static_cast<double>(size)/static_cast<double>(bytesPerBlock));
|
||||
|
||||
//Calculate the Size needeed for the index itself
|
||||
size_t serializedSize = 0;
|
||||
if(additionalInfo!=NULL) {
|
||||
uint32_t serializedSize = 0;
|
||||
if(additionalInfo!=NULL){
|
||||
serializedSize += additionalInfo->getSerializedSize();
|
||||
}
|
||||
|
||||
//Size of current iterator type
|
||||
Index<T> tempIndex;
|
||||
serializedSize += tempIndex.getSerializedSize();
|
||||
@ -178,7 +162,6 @@ public:
|
||||
error << "IndexedRingMemory: Store is too small for index" << std::endl;
|
||||
}
|
||||
uint32_t useableSize = totalSize - serializedSize;
|
||||
|
||||
//Update the totalSize for calculations
|
||||
totalSize = useableSize;
|
||||
|
||||
@ -195,10 +178,12 @@ public:
|
||||
this->allocated = true;
|
||||
|
||||
//Check trueNumberOfBlocks
|
||||
if(trueNumberOfBlocks<1) {
|
||||
if(trueNumberOfBlocks<1){
|
||||
error << "IndexedRingMemory: Invalid Number of Blocks: " << trueNumberOfBlocks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Fill address into index
|
||||
uint32_t address = trueStartAddress;
|
||||
for (typename IndexedRingMemoryArray<T>::Iterator it = this->begin();it!=this->end();++it) {
|
||||
@ -208,6 +193,7 @@ public:
|
||||
address += bytesPerBlock;
|
||||
}
|
||||
|
||||
|
||||
//Initialize iterators
|
||||
currentWriteBlock = this->begin();
|
||||
currentReadBlock = this->begin();
|
||||
@ -246,10 +232,10 @@ public:
|
||||
(*typeResetFnc)(it->modifyIndexType());
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Reading
|
||||
* @param it
|
||||
*/
|
||||
|
||||
void setCurrentReadBlock(typename IndexedRingMemoryArray<T>::Iterator it){
|
||||
currentReadBlock = it;
|
||||
currentReadBlockSizeCached = it->getSize();
|
||||
@ -262,7 +248,6 @@ public:
|
||||
lastBlockToRead = currentWriteBlock;
|
||||
lastBlockToReadSize = currentWriteBlock->getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last block to read to this iterator.
|
||||
* Can be used to dump until block x
|
||||
@ -307,39 +292,33 @@ public:
|
||||
uint32_t getCurrentReadAddress() const {
|
||||
return getAddressOfCurrentReadBlock() + currentReadSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds readSize to the current size and checks if the read has no more data
|
||||
* left and advances the read block.
|
||||
* Adds readSize to the current size and checks if the read has no more data left and advances the read block
|
||||
* @param readSize The size that was read
|
||||
* @return Returns true if the read can go on
|
||||
*/
|
||||
bool addReadSize(uint32_t readSize) {
|
||||
if(currentReadBlock == lastBlockToRead) {
|
||||
if(currentReadBlock == lastBlockToRead){
|
||||
//The current read block is the last to read
|
||||
if((currentReadSize+readSize)<lastBlockToReadSize) {
|
||||
if((currentReadSize+readSize)<lastBlockToReadSize){
|
||||
//the block has more data -> return true
|
||||
currentReadSize += readSize;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
}else{
|
||||
//Reached end of read -> return false
|
||||
currentReadSize = lastBlockToReadSize;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
}else{
|
||||
//We are not in the last Block
|
||||
if((currentReadSize + readSize)<currentReadBlockSizeCached) {
|
||||
if((currentReadSize + readSize)<currentReadBlockSizeCached){
|
||||
//The current Block has more data
|
||||
currentReadSize += readSize;
|
||||
return true;
|
||||
}
|
||||
// TODO: Maybe some logic blocks should be extracted
|
||||
else {
|
||||
}else{
|
||||
//The current block is written completely
|
||||
readNext();
|
||||
if(currentReadBlockSizeCached==0) {
|
||||
if(currentReadBlockSizeCached==0){
|
||||
//Next block is empty
|
||||
typename IndexedRingMemoryArray<T>::Iterator it(currentReadBlock);
|
||||
//Search if any block between this and the last block is not empty
|
||||
@ -442,13 +421,13 @@ public:
|
||||
T* modifyCurrentWriteBlockIndexType(){
|
||||
return currentWriteBlock->modifyIndexType();
|
||||
}
|
||||
|
||||
void updatePreviousWriteSize(uint32_t size, uint32_t storedPackets){
|
||||
typename IndexedRingMemoryArray<T>::Iterator it = getPreviousBlock(currentWriteBlock);
|
||||
it->addSize(size);
|
||||
it->addStoredPackets(storedPackets);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the block has enough space for sizeToWrite
|
||||
* @param sizeToWrite The data to be written in the Block
|
||||
@ -457,10 +436,7 @@ public:
|
||||
bool hasCurrentWriteBlockEnoughSpace(uint32_t sizeToWrite){
|
||||
typename IndexedRingMemoryArray<T>::Iterator next = getNextWrite();
|
||||
uint32_t addressOfNextBlock = next->getBlockStartAddress();
|
||||
uint32_t availableSize =
|
||||
( ( addressOfNextBlock + totalSize ) -
|
||||
(getAddressOfCurrentWriteBlock() + getSizeOfCurrentWriteBlock()))
|
||||
% totalSize;
|
||||
uint32_t availableSize = ((addressOfNextBlock+totalSize) - (getAddressOfCurrentWriteBlock()+getSizeOfCurrentWriteBlock()))%totalSize;
|
||||
return (sizeToWrite < availableSize);
|
||||
}
|
||||
|
||||
@ -550,7 +526,7 @@ public:
|
||||
*/
|
||||
size_t getSerializedSize() const {
|
||||
|
||||
size_t size = 0;
|
||||
uint32_t size = 0;
|
||||
if(additionalInfo!=NULL){
|
||||
size += additionalInfo->getSerializedSize();
|
||||
}
|
||||
@ -718,4 +694,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ */
|
||||
|
@ -1,13 +1,6 @@
|
||||
#ifndef ISDERIVEDFROM_H_
|
||||
#define ISDERIVEDFROM_H_
|
||||
|
||||
/**
|
||||
* These template type checks are based on SFINAE
|
||||
* (https://en.cppreference.com/w/cpp/language/sfinae)
|
||||
*
|
||||
* @tparam D Derived Type
|
||||
* @tparam B Base Type
|
||||
*/
|
||||
template<typename D, typename B>
|
||||
class IsDerivedFrom {
|
||||
class No {
|
||||
@ -16,9 +9,7 @@ class IsDerivedFrom {
|
||||
No no[3];
|
||||
};
|
||||
|
||||
// This will be chosen if B is the base type
|
||||
static Yes Test(B*); // declared, but not defined
|
||||
// This will be chosen for anything else
|
||||
static No Test(... ); // declared, but not defined
|
||||
|
||||
public:
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_
|
||||
#define FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_
|
||||
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include "../storagemanager/StorageManagerIF.h"
|
||||
#include <utility>
|
||||
|
||||
class PlacementFactory {
|
||||
|
@ -1,77 +1,17 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_
|
||||
#define FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_
|
||||
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <cstddef>
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
template<uint8_t N_READ_PTRS = 1>
|
||||
class RingBufferBase {
|
||||
public:
|
||||
RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) :
|
||||
start(startAddress), write(startAddress), size(size),
|
||||
overwriteOld(overwriteOld) {
|
||||
RingBufferBase(uint32_t startAddress, uint32_t size, bool overwriteOld) :
|
||||
start(startAddress), write(startAddress), size(size), overwriteOld(overwriteOld) {
|
||||
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
|
||||
read[count] = startAddress;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~RingBufferBase() {}
|
||||
|
||||
bool isFull(uint8_t n = 0) {
|
||||
return (availableWriteSpace(n) == 0);
|
||||
}
|
||||
bool isEmpty(uint8_t n = 0) {
|
||||
return (availableReadData(n) == 0);
|
||||
}
|
||||
|
||||
size_t availableReadData(uint8_t n = 0) const {
|
||||
return ((write + size) - read[n]) % size;
|
||||
}
|
||||
size_t availableWriteSpace(uint8_t n = 0) const {
|
||||
//One less to avoid ambiguous full/empty problem.
|
||||
return (((read[n] + size) - write - 1) % size);
|
||||
}
|
||||
|
||||
bool overwritesOld() const {
|
||||
return overwriteOld;
|
||||
}
|
||||
|
||||
size_t maxSize() const {
|
||||
return size - 1;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
write = start;
|
||||
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
|
||||
read[count] = start;
|
||||
}
|
||||
}
|
||||
|
||||
size_t writeTillWrap() {
|
||||
return (start + size) - write;
|
||||
}
|
||||
|
||||
size_t readTillWrap(uint8_t n = 0) {
|
||||
return (start + size) - read[n];
|
||||
}
|
||||
|
||||
size_t getStart() const {
|
||||
return start;
|
||||
}
|
||||
|
||||
protected:
|
||||
const size_t start;
|
||||
size_t write;
|
||||
size_t read[N_READ_PTRS];
|
||||
const size_t size;
|
||||
const bool overwriteOld;
|
||||
void incrementWrite(uint32_t amount) {
|
||||
write = ((write + amount - start) % size) + start;
|
||||
}
|
||||
void incrementRead(uint32_t amount, uint8_t n = 0) {
|
||||
read[n] = ((read[n] + amount - start) % size) + start;
|
||||
}
|
||||
|
||||
ReturnValue_t readData(uint32_t amount, uint8_t n = 0) {
|
||||
if (availableReadData(n) >= amount) {
|
||||
incrementRead(amount, n);
|
||||
@ -80,34 +20,77 @@ protected:
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t writeData(uint32_t amount) {
|
||||
if (availableWriteSpace() >= amount or overwriteOld) {
|
||||
if (availableWriteSpace() >= amount || overwriteOld) {
|
||||
incrementWrite(amount);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
uint32_t availableReadData(uint8_t n = 0) const {
|
||||
return ((write + size) - read[n]) % size;
|
||||
}
|
||||
uint32_t availableWriteSpace(uint8_t n = 0) const {
|
||||
//One less to avoid ambiguous full/empty problem.
|
||||
return (((read[n] + size) - write - 1) % size);
|
||||
}
|
||||
bool isFull(uint8_t n = 0) {
|
||||
return (availableWriteSpace(n) == 0);
|
||||
}
|
||||
bool isEmpty(uint8_t n = 0) {
|
||||
return (availableReadData(n) == 0);
|
||||
}
|
||||
virtual ~RingBufferBase() {
|
||||
|
||||
|
||||
size_t getRead(uint8_t n = 0) const {
|
||||
}
|
||||
uint32_t getRead(uint8_t n = 0) const {
|
||||
return read[n];
|
||||
}
|
||||
|
||||
void setRead(uint32_t read, uint8_t n = 0) {
|
||||
if (read >= start && read < (start+size)) {
|
||||
this->read[n] = read;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getWrite() const {
|
||||
return write;
|
||||
}
|
||||
|
||||
void setWrite(uint32_t write) {
|
||||
this->write = write;
|
||||
}
|
||||
void clear() {
|
||||
write = start;
|
||||
for (uint8_t count = 0; count < N_READ_PTRS; count++) {
|
||||
read[count] = start;
|
||||
}
|
||||
}
|
||||
uint32_t writeTillWrap() {
|
||||
return (start + size) - write;
|
||||
}
|
||||
uint32_t readTillWrap(uint8_t n = 0) {
|
||||
return (start + size) - read[n];
|
||||
}
|
||||
uint32_t getStart() const {
|
||||
return start;
|
||||
}
|
||||
bool overwritesOld() const {
|
||||
return overwriteOld;
|
||||
}
|
||||
uint32_t maxSize() const {
|
||||
return size - 1;
|
||||
}
|
||||
protected:
|
||||
const uint32_t start;
|
||||
uint32_t write;
|
||||
uint32_t read[N_READ_PTRS];
|
||||
const uint32_t size;
|
||||
const bool overwriteOld;
|
||||
void incrementWrite(uint32_t amount) {
|
||||
write = ((write + amount - start) % size) + start;
|
||||
}
|
||||
void incrementRead(uint32_t amount, uint8_t n = 0) {
|
||||
read[n] = ((read[n] + amount - start) % size) + start;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */
|
||||
|
@ -1,59 +0,0 @@
|
||||
#include <framework/container/SharedRingBuffer.h>
|
||||
#include <framework/ipc/MutexFactory.h>
|
||||
#include <framework/ipc/MutexHelper.h>
|
||||
|
||||
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||
bool overwriteOld, size_t maxExcessBytes, dur_millis_t mutexTimeout):
|
||||
SystemObject(objectId), SimpleRingBuffer(size, overwriteOld,
|
||||
maxExcessBytes), mutexTimeout(mutexTimeout) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer,
|
||||
const size_t size, bool overwriteOld, size_t maxExcessBytes,
|
||||
dur_millis_t mutexTimeout):
|
||||
SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld,
|
||||
maxExcessBytes), mutexTimeout(mutexTimeout) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
ReturnValue_t SharedRingBuffer::getFreeElementProtected(uint8_t** writePtr,
|
||||
size_t amount) {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return SimpleRingBuffer::getFreeElement(writePtr,amount);
|
||||
}
|
||||
|
||||
ReturnValue_t SharedRingBuffer::writeDataProtected(const uint8_t *data,
|
||||
size_t amount) {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return SimpleRingBuffer::writeData(data,amount);
|
||||
}
|
||||
|
||||
ReturnValue_t SharedRingBuffer::readDataProtected(uint8_t *data, size_t amount,
|
||||
bool incrementReadPtr, bool readRemaining,
|
||||
size_t *trueAmount) {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return SimpleRingBuffer::readData(data,amount, incrementReadPtr,
|
||||
readRemaining, trueAmount);
|
||||
}
|
||||
|
||||
ReturnValue_t SharedRingBuffer::deleteDataProtected(size_t amount,
|
||||
bool deleteRemaining, size_t *trueAmount) {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return SimpleRingBuffer::deleteData(amount, deleteRemaining, trueAmount);
|
||||
}
|
||||
|
||||
size_t SharedRingBuffer::getExcessBytes() const {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return SimpleRingBuffer::getExcessBytes();
|
||||
}
|
||||
|
||||
void SharedRingBuffer::moveExcessBytesToStart() {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return SimpleRingBuffer::moveExcessBytesToStart();
|
||||
}
|
||||
|
||||
size_t SharedRingBuffer::getAvailableReadDataProtected(uint8_t n) const {
|
||||
MutexHelper(mutex, mutexTimeout);
|
||||
return ((write + size) - read[n]) % size;
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_
|
||||
#define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_
|
||||
|
||||
#include <framework/container/SimpleRingBuffer.h>
|
||||
#include <framework/ipc/MutexIF.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/timemanager/Clock.h>
|
||||
|
||||
class SharedRingBuffer: public SystemObject,
|
||||
public SimpleRingBuffer {
|
||||
public:
|
||||
/**
|
||||
* This constructor allocates a new internal buffer with the supplied size.
|
||||
* @param size
|
||||
* @param overwriteOld
|
||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||
* will be overwritten.
|
||||
*/
|
||||
SharedRingBuffer(object_id_t objectId, const size_t size,
|
||||
bool overwriteOld, size_t maxExcessBytes,
|
||||
dur_millis_t mutexTimeout = 10);
|
||||
|
||||
/**
|
||||
* This constructor takes an external buffer with the specified size.
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param overwriteOld
|
||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||
* will be overwritten.
|
||||
*/
|
||||
SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size,
|
||||
bool overwriteOld, size_t maxExcessBytes,
|
||||
dur_millis_t mutexTimeout = 10);
|
||||
|
||||
void setMutexTimeout(dur_millis_t newTimeout);
|
||||
|
||||
virtual size_t getExcessBytes() const override;
|
||||
/**
|
||||
* Helper functions which moves any excess bytes to the start
|
||||
* of the ring buffer.
|
||||
* @return
|
||||
*/
|
||||
virtual void moveExcessBytesToStart() override;
|
||||
|
||||
/** Performs mutex protected SimpleRingBuffer::getFreeElement call */
|
||||
ReturnValue_t getFreeElementProtected(uint8_t** writePtr, size_t amount);
|
||||
|
||||
/** Performs mutex protected SimpleRingBuffer::writeData call */
|
||||
ReturnValue_t writeDataProtected(const uint8_t* data, size_t amount);
|
||||
|
||||
/** Performs mutex protected SimpleRingBuffer::readData call */
|
||||
ReturnValue_t readDataProtected(uint8_t *data, size_t amount,
|
||||
bool incrementReadPtr = false,
|
||||
bool readRemaining = false, size_t *trueAmount = nullptr);
|
||||
|
||||
/** Performs mutex protected SimpleRingBuffer::deleteData call */
|
||||
ReturnValue_t deleteDataProtected(size_t amount,
|
||||
bool deleteRemaining = false, size_t* trueAmount = nullptr);
|
||||
|
||||
size_t getAvailableReadDataProtected (uint8_t n = 0) const;
|
||||
private:
|
||||
dur_millis_t mutexTimeout;
|
||||
MutexIF* mutex = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ */
|
@ -1,64 +1,22 @@
|
||||
#include <framework/container/SimpleRingBuffer.h>
|
||||
#include <cstring>
|
||||
#include "SimpleRingBuffer.h"
|
||||
#include <string.h>
|
||||
|
||||
SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld,
|
||||
size_t maxExcessBytes) :
|
||||
RingBufferBase<>(0, size, overwriteOld),
|
||||
maxExcessBytes(maxExcessBytes) {
|
||||
if(maxExcessBytes > size) {
|
||||
this->maxExcessBytes = size;
|
||||
}
|
||||
else {
|
||||
this->maxExcessBytes = maxExcessBytes;
|
||||
}
|
||||
buffer = new uint8_t[size + maxExcessBytes];
|
||||
SimpleRingBuffer::SimpleRingBuffer(uint32_t size, bool overwriteOld) :
|
||||
RingBufferBase<>(0, size, overwriteOld), buffer(NULL) {
|
||||
buffer = new uint8_t[size];
|
||||
}
|
||||
|
||||
SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size,
|
||||
bool overwriteOld, size_t maxExcessBytes):
|
||||
RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {
|
||||
if(maxExcessBytes > size) {
|
||||
this->maxExcessBytes = size;
|
||||
}
|
||||
else {
|
||||
this->maxExcessBytes = maxExcessBytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SimpleRingBuffer::~SimpleRingBuffer() {
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer,
|
||||
size_t amount) {
|
||||
if (availableWriteSpace() >= amount or overwriteOld) {
|
||||
size_t amountTillWrap = writeTillWrap();
|
||||
if (amountTillWrap < amount) {
|
||||
if((amount - amountTillWrap + excessBytes) > maxExcessBytes) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
excessBytes = amount - amountTillWrap;
|
||||
}
|
||||
*writePointer = &buffer[write];
|
||||
incrementWrite(amount);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
|
||||
size_t amount) {
|
||||
if (availableWriteSpace() >= amount or overwriteOld) {
|
||||
size_t amountTillWrap = writeTillWrap();
|
||||
uint32_t amount) {
|
||||
if (availableWriteSpace() >= amount || overwriteOld) {
|
||||
uint32_t amountTillWrap = writeTillWrap();
|
||||
if (amountTillWrap >= amount) {
|
||||
// remaining size in buffer is sufficient to fit full amount.
|
||||
memcpy(&buffer[write], data, amount);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
memcpy(&buffer[write], data, amountTillWrap);
|
||||
memcpy(buffer, data + amountTillWrap, amount - amountTillWrap);
|
||||
}
|
||||
@ -69,19 +27,18 @@ ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data,
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount,
|
||||
bool incrementReadPtr, bool readRemaining, size_t* trueAmount) {
|
||||
size_t availableData = availableReadData(READ_PTR);
|
||||
size_t amountTillWrap = readTillWrap(READ_PTR);
|
||||
ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, uint32_t amount,
|
||||
bool readRemaining, uint32_t* trueAmount) {
|
||||
uint32_t availableData = availableReadData(READ_PTR);
|
||||
uint32_t amountTillWrap = readTillWrap(READ_PTR);
|
||||
if (availableData < amount) {
|
||||
if (readRemaining) {
|
||||
// more data available than amount specified.
|
||||
amount = availableData;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
if (trueAmount != nullptr) {
|
||||
if (trueAmount != NULL) {
|
||||
*trueAmount = amount;
|
||||
}
|
||||
if (amountTillWrap >= amount) {
|
||||
@ -90,27 +47,12 @@ ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount,
|
||||
memcpy(data, &buffer[read[READ_PTR]], amountTillWrap);
|
||||
memcpy(data + amountTillWrap, buffer, amount - amountTillWrap);
|
||||
}
|
||||
|
||||
if(incrementReadPtr) {
|
||||
deleteData(amount, readRemaining);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
size_t SimpleRingBuffer::getExcessBytes() const {
|
||||
return excessBytes;
|
||||
}
|
||||
|
||||
void SimpleRingBuffer::moveExcessBytesToStart() {
|
||||
if(excessBytes > 0) {
|
||||
std::memcpy(buffer, &buffer[size], excessBytes);
|
||||
excessBytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
|
||||
bool deleteRemaining, size_t* trueAmount) {
|
||||
size_t availableData = availableReadData(READ_PTR);
|
||||
ReturnValue_t SimpleRingBuffer::deleteData(uint32_t amount,
|
||||
bool deleteRemaining, uint32_t* trueAmount) {
|
||||
uint32_t availableData = availableReadData(READ_PTR);
|
||||
if (availableData < amount) {
|
||||
if (deleteRemaining) {
|
||||
amount = availableData;
|
||||
@ -118,10 +60,9 @@ ReturnValue_t SimpleRingBuffer::deleteData(size_t amount,
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
if (trueAmount != nullptr) {
|
||||
if (trueAmount != NULL) {
|
||||
*trueAmount = amount;
|
||||
}
|
||||
incrementRead(amount, READ_PTR);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -1,118 +1,20 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_
|
||||
#define FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_
|
||||
|
||||
#include <framework/container/RingBufferBase.h>
|
||||
#include <cstddef>
|
||||
#include "RingBufferBase.h"
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* @brief Circular buffer implementation, useful for buffering
|
||||
* into data streams.
|
||||
* @details
|
||||
* Note that the deleteData() has to be called to increment the read pointer.
|
||||
* This class allocated dynamically, so
|
||||
* @ingroup containers
|
||||
*/
|
||||
class SimpleRingBuffer: public RingBufferBase<> {
|
||||
public:
|
||||
/**
|
||||
* This constructor allocates a new internal buffer with the supplied size.
|
||||
*
|
||||
* @param size
|
||||
* @param overwriteOld If the ring buffer is overflowing at a write
|
||||
* operation, the oldest data will be overwritten.
|
||||
* @param maxExcessBytes These additional bytes will be allocated in addtion
|
||||
* to the specified size to accomodate contiguous write operations
|
||||
* with getFreeElement.
|
||||
*
|
||||
*/
|
||||
SimpleRingBuffer(const size_t size, bool overwriteOld,
|
||||
size_t maxExcessBytes = 0);
|
||||
/**
|
||||
* This constructor takes an external buffer with the specified size.
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param overwriteOld
|
||||
* If the ring buffer is overflowing at a write operartion, the oldest data
|
||||
* will be overwritten.
|
||||
* @param maxExcessBytes
|
||||
* If the buffer can accomodate additional bytes for contigous write
|
||||
* operations with getFreeElement, this is the maximum allowed additional
|
||||
* size
|
||||
*/
|
||||
SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld,
|
||||
size_t maxExcessBytes = 0);
|
||||
|
||||
SimpleRingBuffer(uint32_t size, bool overwriteOld);
|
||||
virtual ~SimpleRingBuffer();
|
||||
|
||||
/**
|
||||
* Write to circular buffer and increment write pointer by amount.
|
||||
* @param data
|
||||
* @param amount
|
||||
* @return -@c RETURN_OK if write operation was successfull
|
||||
* -@c RETURN_FAILED if
|
||||
*/
|
||||
ReturnValue_t writeData(const uint8_t* data, size_t amount);
|
||||
|
||||
/**
|
||||
* Returns a pointer to a free element. If the remaining buffer is
|
||||
* not large enough, the data will be written past the actual size
|
||||
* and the amount of excess bytes will be cached.
|
||||
* @param writePointer Pointer to a pointer which can be used to write
|
||||
* contiguous blocks into the ring buffer
|
||||
* @param amount
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount);
|
||||
|
||||
virtual size_t getExcessBytes() const;
|
||||
/**
|
||||
* Helper functions which moves any excess bytes to the start
|
||||
* of the ring buffer.
|
||||
* @return
|
||||
*/
|
||||
virtual void moveExcessBytesToStart();
|
||||
|
||||
/**
|
||||
* Read from circular buffer at read pointer.
|
||||
* @param data
|
||||
* @param amount
|
||||
* @param incrementReadPtr
|
||||
* If this is set to true, the read pointer will be incremented.
|
||||
* If readRemaining is set to true, the read pointer will be incremented
|
||||
* accordingly.
|
||||
* @param readRemaining
|
||||
* If this is set to true, the data will be read even if the amount
|
||||
* specified exceeds the read data available.
|
||||
* @param trueAmount [out]
|
||||
* If readRemaining was set to true, the true amount read will be assigned
|
||||
* to the passed value.
|
||||
* @return
|
||||
* - @c RETURN_OK if data was read successfully
|
||||
* - @c RETURN_FAILED if not enough data was available and readRemaining
|
||||
* was set to false.
|
||||
*/
|
||||
ReturnValue_t readData(uint8_t* data, size_t amount,
|
||||
bool incrementReadPtr = false, bool readRemaining = false,
|
||||
size_t* trueAmount = nullptr);
|
||||
|
||||
/**
|
||||
* Delete data by incrementing read pointer.
|
||||
* @param amount
|
||||
* @param deleteRemaining
|
||||
* If the amount specified is larger than the remaing size to read and this
|
||||
* is set to true, the remaining amount will be deleted as well
|
||||
* @param trueAmount [out]
|
||||
* If deleteRemaining was set to true, the amount deleted will be assigned
|
||||
* to the passed value.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false,
|
||||
size_t* trueAmount = nullptr);
|
||||
ReturnValue_t writeData(const uint8_t* data, uint32_t amount);
|
||||
ReturnValue_t readData(uint8_t* data, uint32_t amount, bool readRemaining = false, uint32_t* trueAmount = NULL);
|
||||
ReturnValue_t deleteData(uint32_t amount, bool deleteRemaining = false, uint32_t* trueAmount = NULL);
|
||||
private:
|
||||
// static const uint8_t TEMP_READ_PTR = 1;
|
||||
static const uint8_t READ_PTR = 0;
|
||||
uint8_t* buffer = nullptr;
|
||||
size_t maxExcessBytes;
|
||||
size_t excessBytes = 0;
|
||||
uint8_t* buffer;
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */
|
||||
|
@ -1,13 +1,10 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_
|
||||
#define FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#ifndef SINGLYLINKEDLIST_H_
|
||||
#define SINGLYLINKEDLIST_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
/**
|
||||
* @brief Linked list data structure,
|
||||
* each entry has a pointer to the next entry (singly)
|
||||
* @ingroup container
|
||||
* \ingroup container
|
||||
*/
|
||||
template<typename T>
|
||||
class LinkedElement {
|
||||
@ -15,8 +12,11 @@ public:
|
||||
T *value;
|
||||
class Iterator {
|
||||
public:
|
||||
LinkedElement<T> *value = nullptr;
|
||||
Iterator() {}
|
||||
LinkedElement<T> *value;
|
||||
Iterator() :
|
||||
value(NULL) {
|
||||
|
||||
}
|
||||
|
||||
Iterator(LinkedElement<T> *element) :
|
||||
value(element) {
|
||||
@ -45,11 +45,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
LinkedElement(T* setElement, LinkedElement<T>* setNext = nullptr):
|
||||
value(setElement), next(setNext) {}
|
||||
|
||||
virtual ~LinkedElement(){}
|
||||
LinkedElement(T* setElement, LinkedElement<T>* setNext = NULL) : value(setElement),
|
||||
next(setNext) {
|
||||
}
|
||||
virtual ~LinkedElement(){
|
||||
|
||||
}
|
||||
virtual LinkedElement* getNext() const {
|
||||
return next;
|
||||
}
|
||||
@ -57,16 +58,11 @@ public:
|
||||
virtual void setNext(LinkedElement* next) {
|
||||
this->next = next;
|
||||
}
|
||||
|
||||
virtual void setEnd() {
|
||||
this->next = nullptr;
|
||||
}
|
||||
|
||||
LinkedElement* begin() {
|
||||
return this;
|
||||
}
|
||||
LinkedElement* end() {
|
||||
return nullptr;
|
||||
return NULL;
|
||||
}
|
||||
private:
|
||||
LinkedElement *next;
|
||||
@ -75,80 +71,37 @@ private:
|
||||
template<typename T>
|
||||
class SinglyLinkedList {
|
||||
public:
|
||||
using ElementIterator = typename LinkedElement<T>::Iterator;
|
||||
|
||||
SinglyLinkedList() {}
|
||||
|
||||
SinglyLinkedList(ElementIterator start) :
|
||||
start(start.value) {}
|
||||
SinglyLinkedList() :
|
||||
start(NULL) {
|
||||
}
|
||||
|
||||
SinglyLinkedList(typename LinkedElement<T>::Iterator start) :
|
||||
start(start.value) {
|
||||
}
|
||||
SinglyLinkedList(LinkedElement<T>* startElement) :
|
||||
start(startElement) {}
|
||||
|
||||
ElementIterator begin() const {
|
||||
return ElementIterator::Iterator(start);
|
||||
start(startElement) {
|
||||
}
|
||||
typename LinkedElement<T>::Iterator begin() const {
|
||||
return LinkedElement<T>::Iterator::Iterator(start);
|
||||
}
|
||||
typename LinkedElement<T>::Iterator::Iterator end() const {
|
||||
return LinkedElement<T>::Iterator::Iterator();
|
||||
}
|
||||
|
||||
/** Returns iterator to nulltr */
|
||||
ElementIterator end() const {
|
||||
return ElementIterator::Iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last element in singly linked list.
|
||||
* @return
|
||||
*/
|
||||
ElementIterator back() const {
|
||||
LinkedElement<T> *element = start;
|
||||
while (element != nullptr) {
|
||||
element = element->getNext();
|
||||
}
|
||||
return ElementIterator::Iterator(element);
|
||||
}
|
||||
|
||||
size_t getSize() const {
|
||||
size_t size = 0;
|
||||
uint32_t getSize() const {
|
||||
uint32_t size = 0;
|
||||
LinkedElement<T> *element = start;
|
||||
while (element != nullptr) {
|
||||
while (element != NULL) {
|
||||
size++;
|
||||
element = element->getNext();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
void setStart(LinkedElement<T>* firstElement) {
|
||||
start = firstElement;
|
||||
void setStart(LinkedElement<T>* setStart) {
|
||||
start = setStart;
|
||||
}
|
||||
|
||||
void setNext(LinkedElement<T>* currentElement,
|
||||
LinkedElement<T>* nextElement) {
|
||||
currentElement->setNext(nextElement);
|
||||
}
|
||||
|
||||
void setLast(LinkedElement<T>* lastElement) {
|
||||
lastElement->setEnd();
|
||||
}
|
||||
|
||||
void insertElement(LinkedElement<T>* element, size_t position) {
|
||||
LinkedElement<T> *currentElement = start;
|
||||
for(size_t count = 0; count < position; count++) {
|
||||
if(currentElement == nullptr) {
|
||||
return;
|
||||
}
|
||||
currentElement = currentElement->getNext();
|
||||
}
|
||||
LinkedElement<T>* elementAfterCurrent = currentElement->next;
|
||||
currentElement->setNext(element);
|
||||
if(elementAfterCurrent != nullptr) {
|
||||
element->setNext(elementAfterCurrent);
|
||||
}
|
||||
}
|
||||
|
||||
void insertBack(LinkedElement<T>* lastElement) {
|
||||
back().value->setNext(lastElement);
|
||||
}
|
||||
|
||||
protected:
|
||||
LinkedElement<T> *start = nullptr;
|
||||
LinkedElement<T> *start;
|
||||
};
|
||||
|
||||
#endif /* SINGLYLINKEDLIST_H_ */
|
||||
|
@ -4,9 +4,11 @@
|
||||
/**
|
||||
* @defgroup container Container
|
||||
*
|
||||
* General Purpose Containers to store various elements.
|
||||
* As opposed to the STL library implementation, these implementations
|
||||
* don't allocate memory dynamically.
|
||||
* General Purpose Container to store various elements.
|
||||
*
|
||||
* Also contains Adapter classes to print elements to a
|
||||
* bytestream and to read them from a bytestream, as well
|
||||
* as an Adapter to swap the endianness.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include <framework/subsystem/SubsystemBase.h>
|
||||
#include <framework/controller/ControllerBase.h>
|
||||
#include <framework/subsystem/SubsystemBase.h>
|
||||
#include <framework/ipc/QueueFactory.h>
|
||||
#include <framework/action/HasActionsIF.h>
|
||||
#include "../subsystem/SubsystemBase.h"
|
||||
#include "ControllerBase.h"
|
||||
#include "../subsystem/SubsystemBase.h"
|
||||
#include "../ipc/QueueFactory.h"
|
||||
#include "../action/HasActionsIF.h"
|
||||
|
||||
ControllerBase::ControllerBase(uint32_t setObjectId, uint32_t parentId,
|
||||
size_t commandQueueDepth) :
|
||||
@ -56,26 +56,26 @@ MessageQueueId_t ControllerBase::getCommandQueue() const {
|
||||
}
|
||||
|
||||
void ControllerBase::handleQueue() {
|
||||
CommandMessage command;
|
||||
CommandMessage message;
|
||||
ReturnValue_t result;
|
||||
for (result = commandQueue->receiveMessage(&command); result == RETURN_OK;
|
||||
result = commandQueue->receiveMessage(&command)) {
|
||||
for (result = commandQueue->receiveMessage(&message); result == RETURN_OK;
|
||||
result = commandQueue->receiveMessage(&message)) {
|
||||
|
||||
result = modeHelper.handleModeCommand(&command);
|
||||
result = modeHelper.handleModeCommand(&message);
|
||||
if (result == RETURN_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result = healthHelper.handleHealthCommand(&command);
|
||||
result = healthHelper.handleHealthCommand(&message);
|
||||
if (result == RETURN_OK) {
|
||||
continue;
|
||||
}
|
||||
result = handleCommandMessage(&command);
|
||||
result = handleCommandMessage(&message);
|
||||
if (result == RETURN_OK) {
|
||||
continue;
|
||||
}
|
||||
command.setToUnknownCommand();
|
||||
commandQueue->reply(&command);
|
||||
message.setToUnknownCommand();
|
||||
commandQueue->reply(&message);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
#ifndef CONTROLLERBASE_H_
|
||||
#define CONTROLLERBASE_H_
|
||||
|
||||
#include <framework/health/HasHealthIF.h>
|
||||
#include <framework/health/HealthHelper.h>
|
||||
#include <framework/modes/HasModesIF.h>
|
||||
#include <framework/modes/ModeHelper.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
#include <framework/datapool/HkSwitchHelper.h>
|
||||
#include "../health/HasHealthIF.h"
|
||||
#include "../health/HealthHelper.h"
|
||||
#include "../modes/HasModesIF.h"
|
||||
#include "../modes/ModeHelper.h"
|
||||
#include "../objectmanager/SystemObject.h"
|
||||
#include "../tasks/ExecutableObjectIF.h"
|
||||
#include "../datapool/HkSwitchHelper.h"
|
||||
|
||||
|
||||
class ControllerBase: public HasModesIF,
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include <framework/coordinates/CoordinateTransformations.h>
|
||||
#include <framework/globalfunctions/constants.h>
|
||||
#include <framework/globalfunctions/math/MatrixOperations.h>
|
||||
#include <framework/globalfunctions/math/VectorOperations.h>
|
||||
#include "CoordinateTransformations.h"
|
||||
#include "../globalfunctions/constants.h"
|
||||
#include "../globalfunctions/math/MatrixOperations.h"
|
||||
#include "../globalfunctions/math/VectorOperations.h"
|
||||
#include <stddef.h>
|
||||
#include <cmath>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef COORDINATETRANSFORMATIONS_H_
|
||||
#define COORDINATETRANSFORMATIONS_H_
|
||||
|
||||
#include <framework/timemanager/Clock.h>
|
||||
#include "../timemanager/Clock.h"
|
||||
#include <cstring>
|
||||
|
||||
class CoordinateTransformations {
|
||||
|
@ -2,10 +2,10 @@
|
||||
#define FRAMEWORK_COORDINATES_JGM3MODEL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <framework/coordinates/CoordinateTransformations.h>
|
||||
#include <framework/globalfunctions/math/VectorOperations.h>
|
||||
#include <framework/globalfunctions/timevalOperations.h>
|
||||
#include <framework/globalfunctions/constants.h>
|
||||
#include "CoordinateTransformations.h"
|
||||
#include "../globalfunctions/math/VectorOperations.h"
|
||||
#include "../globalfunctions/timevalOperations.h"
|
||||
#include "../globalfunctions/constants.h"
|
||||
#include <memory.h>
|
||||
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include <framework/coordinates/CoordinateTransformations.h>
|
||||
#include <framework/coordinates/Sgp4Propagator.h>
|
||||
#include <framework/globalfunctions/constants.h>
|
||||
#include <framework/globalfunctions/math/MatrixOperations.h>
|
||||
#include <framework/globalfunctions/math/VectorOperations.h>
|
||||
#include <framework/globalfunctions/timevalOperations.h>
|
||||
#include "CoordinateTransformations.h"
|
||||
#include "Sgp4Propagator.h"
|
||||
#include "../globalfunctions/constants.h"
|
||||
#include "../globalfunctions/math/MatrixOperations.h"
|
||||
#include "../globalfunctions/math/VectorOperations.h"
|
||||
#include "../globalfunctions/timevalOperations.h"
|
||||
#include <cstring>
|
||||
Sgp4Propagator::Sgp4Propagator() :
|
||||
initialized(false), epoch({0, 0}), whichconst(wgs84) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <sys/time.h>
|
||||
#include "../contrib/sgp4/sgp4unit.h"
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
class Sgp4Propagator {
|
||||
public:
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef BCFRAME_H_
|
||||
#define BCFRAME_H_
|
||||
|
||||
#include <framework/datalinklayer/CCSDSReturnValuesIF.h>
|
||||
#include "CCSDSReturnValuesIF.h"
|
||||
|
||||
/**
|
||||
* Small helper class to identify a BcFrame.
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef CCSDSRETURNVALUESIF_H_
|
||||
#define CCSDSRETURNVALUESIF_H_
|
||||
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
/**
|
||||
* This is a helper class to collect special return values that come up during CCSDS Handling.
|
||||
* @ingroup ccsds_handling
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
|
||||
|
||||
#include <framework/datalinklayer/Clcw.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include "Clcw.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
Clcw::Clcw() {
|
||||
content.raw = 0;
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef CLCW_H_
|
||||
#define CLCW_H_
|
||||
|
||||
#include <framework/datalinklayer/ClcwIF.h>
|
||||
#include "ClcwIF.h"
|
||||
/**
|
||||
* Small helper method to handle the Clcw values.
|
||||
* It has a content struct that manages the register and can be set externally.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <framework/datalinklayer/DataLinkLayer.h>
|
||||
#include <framework/globalfunctions/CRC.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include "DataLinkLayer.h"
|
||||
#include "../globalfunctions/CRC.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
DataLinkLayer::DataLinkLayer(uint8_t* set_frame_buffer, ClcwIF* setClcw,
|
||||
uint8_t set_start_sequence_length, uint16_t set_scid) :
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef DATALINKLAYER_H_
|
||||
#define DATALINKLAYER_H_
|
||||
|
||||
#include <framework/datalinklayer/CCSDSReturnValuesIF.h>
|
||||
#include <framework/datalinklayer/ClcwIF.h>
|
||||
#include <framework/datalinklayer/TcTransferFrame.h>
|
||||
#include <framework/datalinklayer/VirtualChannelReceptionIF.h>
|
||||
#include <framework/events/Event.h>
|
||||
#include "CCSDSReturnValuesIF.h"
|
||||
#include "ClcwIF.h"
|
||||
#include "TcTransferFrame.h"
|
||||
#include "VirtualChannelReceptionIF.h"
|
||||
#include "../events/Event.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef FARM1STATEIF_H_
|
||||
#define FARM1STATEIF_H_
|
||||
|
||||
#include <framework/datalinklayer/CCSDSReturnValuesIF.h>
|
||||
#include "CCSDSReturnValuesIF.h"
|
||||
class VirtualChannelReception;
|
||||
class TcTransferFrame;
|
||||
class ClcwIF;
|
||||
|
@ -7,10 +7,10 @@
|
||||
|
||||
|
||||
|
||||
#include <framework/datalinklayer/ClcwIF.h>
|
||||
#include <framework/datalinklayer/Farm1StateLockout.h>
|
||||
#include <framework/datalinklayer/TcTransferFrame.h>
|
||||
#include <framework/datalinklayer/VirtualChannelReception.h>
|
||||
#include "ClcwIF.h"
|
||||
#include "Farm1StateLockout.h"
|
||||
#include "TcTransferFrame.h"
|
||||
#include "VirtualChannelReception.h"
|
||||
Farm1StateLockout::Farm1StateLockout(VirtualChannelReception* setMyVC) : myVC(setMyVC) {
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef FARM1STATELOCKOUT_H_
|
||||
#define FARM1STATELOCKOUT_H_
|
||||
|
||||
#include <framework/datalinklayer/Farm1StateIF.h>
|
||||
#include "Farm1StateIF.h"
|
||||
|
||||
/**
|
||||
* This class represents the FARM-1 "Lockout" State.
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
|
||||
|
||||
#include <framework/datalinklayer/ClcwIF.h>
|
||||
#include <framework/datalinklayer/Farm1StateOpen.h>
|
||||
#include <framework/datalinklayer/TcTransferFrame.h>
|
||||
#include <framework/datalinklayer/VirtualChannelReception.h>
|
||||
#include "ClcwIF.h"
|
||||
#include "Farm1StateOpen.h"
|
||||
#include "TcTransferFrame.h"
|
||||
#include "VirtualChannelReception.h"
|
||||
|
||||
Farm1StateOpen::Farm1StateOpen(VirtualChannelReception* setMyVC) : myVC(setMyVC) {
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef FARM1STATEOPEN_H_
|
||||
#define FARM1STATEOPEN_H_
|
||||
|
||||
#include <framework/datalinklayer/Farm1StateIF.h>
|
||||
#include "Farm1StateIF.h"
|
||||
|
||||
/**
|
||||
* This class represents the FARM-1 "Open" State.
|
||||
|
@ -6,10 +6,10 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <framework/datalinklayer/ClcwIF.h>
|
||||
#include <framework/datalinklayer/Farm1StateWait.h>
|
||||
#include <framework/datalinklayer/TcTransferFrame.h>
|
||||
#include <framework/datalinklayer/VirtualChannelReception.h>
|
||||
#include "ClcwIF.h"
|
||||
#include "Farm1StateWait.h"
|
||||
#include "TcTransferFrame.h"
|
||||
#include "VirtualChannelReception.h"
|
||||
|
||||
Farm1StateWait::Farm1StateWait(VirtualChannelReception* setMyVC) : myVC(setMyVC) {
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef FARM1STATEWAIT_H_
|
||||
#define FARM1STATEWAIT_H_
|
||||
|
||||
#include <framework/datalinklayer/Farm1StateIF.h>
|
||||
#include "Farm1StateIF.h"
|
||||
|
||||
/**
|
||||
* This class represents the FARM-1 "Wait" State.
|
||||
|
@ -5,20 +5,20 @@
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#include <framework/datalinklayer/MapPacketExtraction.h>
|
||||
#include <framework/ipc/QueueFactory.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include <framework/tmtcpacket/SpacePacketBase.h>
|
||||
#include <framework/tmtcservices/AcceptsTelecommandsIF.h>
|
||||
#include <framework/tmtcservices/TmTcMessage.h>
|
||||
#include "MapPacketExtraction.h"
|
||||
#include "../ipc/QueueFactory.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../storagemanager/StorageManagerIF.h"
|
||||
#include "../tmtcpacket/SpacePacketBase.h"
|
||||
#include "../tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "../tmtcservices/TmTcMessage.h"
|
||||
#include <string.h>
|
||||
|
||||
MapPacketExtraction::MapPacketExtraction(uint8_t setMapId,
|
||||
object_id_t setPacketDestination) :
|
||||
lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0),
|
||||
bufferPosition(packetBuffer), packetDestination(setPacketDestination),
|
||||
packetStore(nullptr), tcQueueId(MessageQueueMessageIF::NO_QUEUE) {
|
||||
lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), bufferPosition(
|
||||
packetBuffer), packetDestination(setPacketDestination), packetStore(
|
||||
NULL), tcQueueId(MessageQueueSenderIF::NO_QUEUE) {
|
||||
memset(packetBuffer, 0, sizeof(packetBuffer));
|
||||
}
|
||||
|
||||
|
@ -8,10 +8,10 @@
|
||||
#ifndef MAPPACKETEXTRACTION_H_
|
||||
#define MAPPACKETEXTRACTION_H_
|
||||
|
||||
#include <framework/datalinklayer/MapPacketExtractionIF.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/ipc/MessageQueueSenderIF.h>
|
||||
#include "MapPacketExtractionIF.h"
|
||||
#include "../objectmanager/ObjectManagerIF.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../ipc/MessageQueueSenderIF.h"
|
||||
|
||||
class StorageManagerIF;
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
#ifndef MAPPACKETEXTRACTIONIF_H_
|
||||
#define MAPPACKETEXTRACTIONIF_H_
|
||||
|
||||
#include <framework/datalinklayer/CCSDSReturnValuesIF.h>
|
||||
#include <framework/datalinklayer/TcTransferFrame.h>
|
||||
#include "CCSDSReturnValuesIF.h"
|
||||
#include "TcTransferFrame.h"
|
||||
|
||||
/**
|
||||
* This is the interface for MAP Packet Extraction classes.
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
|
||||
|
||||
#include <framework/datalinklayer/TcTransferFrame.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include "TcTransferFrame.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
TcTransferFrame::TcTransferFrame() {
|
||||
frame = NULL;
|
||||
|
@ -5,9 +5,9 @@
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#include <framework/datalinklayer/TcTransferFrameLocal.h>
|
||||
#include <framework/globalfunctions/CRC.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include "TcTransferFrameLocal.h"
|
||||
#include "../globalfunctions/CRC.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include <string.h>
|
||||
|
||||
TcTransferFrameLocal::TcTransferFrameLocal(bool bypass, bool controlCommand, uint16_t scid,
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef TCTRANSFERFRAMELOCAL_H_
|
||||
#define TCTRANSFERFRAMELOCAL_H_
|
||||
|
||||
#include <framework/datalinklayer/TcTransferFrame.h>
|
||||
#include "TcTransferFrame.h"
|
||||
|
||||
/**
|
||||
* This is a helper class to locally create TC Transfer Frames.
|
||||
|
@ -5,9 +5,9 @@
|
||||
* @author baetz
|
||||
*/
|
||||
|
||||
#include <framework/datalinklayer/BCFrame.h>
|
||||
#include <framework/datalinklayer/VirtualChannelReception.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include "BCFrame.h"
|
||||
#include "VirtualChannelReception.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
VirtualChannelReception::VirtualChannelReception(uint8_t setChannelId,
|
||||
uint8_t setSlidingWindowWidth) :
|
||||
|
@ -8,14 +8,14 @@
|
||||
#ifndef VIRTUALCHANNELRECEPTION_H_
|
||||
#define VIRTUALCHANNELRECEPTION_H_
|
||||
|
||||
#include <framework/datalinklayer/CCSDSReturnValuesIF.h>
|
||||
#include <framework/datalinklayer/Clcw.h>
|
||||
#include <framework/datalinklayer/Farm1StateIF.h>
|
||||
#include <framework/datalinklayer/Farm1StateLockout.h>
|
||||
#include <framework/datalinklayer/Farm1StateOpen.h>
|
||||
#include <framework/datalinklayer/Farm1StateWait.h>
|
||||
#include <framework/datalinklayer/MapPacketExtractionIF.h>
|
||||
#include <framework/datalinklayer/VirtualChannelReceptionIF.h>
|
||||
#include "CCSDSReturnValuesIF.h"
|
||||
#include "Clcw.h"
|
||||
#include "Farm1StateIF.h"
|
||||
#include "Farm1StateLockout.h"
|
||||
#include "Farm1StateOpen.h"
|
||||
#include "Farm1StateWait.h"
|
||||
#include "MapPacketExtractionIF.h"
|
||||
#include "VirtualChannelReceptionIF.h"
|
||||
#include <map>
|
||||
/**
|
||||
* Implementation of a TC Virtual Channel.
|
||||
|
@ -8,9 +8,9 @@
|
||||
#ifndef VIRTUALCHANNELRECEPTIONIF_H_
|
||||
#define VIRTUALCHANNELRECEPTIONIF_H_
|
||||
|
||||
#include <framework/datalinklayer/ClcwIF.h>
|
||||
#include <framework/datalinklayer/TcTransferFrame.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include "ClcwIF.h"
|
||||
#include "TcTransferFrame.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
* This is the interface for Virtual Channel reception classes.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <framework/datapool/ControllerSet.h>
|
||||
#include "ControllerSet.h"
|
||||
|
||||
ControllerSet::ControllerSet() {
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef CONTROLLERSET_H_
|
||||
#define CONTROLLERSET_H_
|
||||
|
||||
#include <framework/datapoolglob/GlobalDataSet.h>
|
||||
#include "DataSet.h"
|
||||
|
||||
class ControllerSet :public GlobDataSet {
|
||||
class ControllerSet :public DataSet {
|
||||
public:
|
||||
ControllerSet();
|
||||
virtual ~ControllerSet();
|
||||
|
131
datapool/DataPool.cpp
Normal file
131
datapool/DataPool.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include "DataPool.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../ipc/MutexFactory.h"
|
||||
|
||||
DataPool::DataPool( void ( *initFunction )( std::map<uint32_t, PoolEntryIF*>* pool_map ) ) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
if (initFunction != NULL ) {
|
||||
initFunction( &this->data_pool );
|
||||
}
|
||||
}
|
||||
|
||||
DataPool::~DataPool() {
|
||||
MutexFactory::instance()->deleteMutex(mutex);
|
||||
for ( std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.begin(); it != this->data_pool.end(); ++it ) {
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
//The function checks PID, type and array length before returning a copy of the PoolEntry. In failure case, it returns a temp-Entry with size 0 and NULL-ptr.
|
||||
template <typename T> PoolEntry<T>* DataPool::getData( uint32_t data_pool_id, uint8_t sizeOrPosition ) {
|
||||
std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( data_pool_id );
|
||||
if ( it != this->data_pool.end() ) {
|
||||
PoolEntry<T>* entry = dynamic_cast< PoolEntry<T>* >( it->second );
|
||||
if (entry != NULL ) {
|
||||
if ( sizeOrPosition <= entry->length ) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PoolEntryIF* DataPool::getRawData( uint32_t data_pool_id ) {
|
||||
std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( data_pool_id );
|
||||
if ( it != this->data_pool.end() ) {
|
||||
return it->second;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//uint8_t DataPool::getRawData( uint32_t data_pool_id, uint8_t* address, uint16_t* size, uint32_t maxSize ) {
|
||||
// std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( data_pool_id );
|
||||
// if ( it != this->data_pool.end() ) {
|
||||
// if ( it->second->getByteSize() <= maxSize ) {
|
||||
// *size = it->second->getByteSize();
|
||||
// memcpy( address, it->second->getRawData(), *size );
|
||||
// return DP_SUCCESSFUL;
|
||||
// }
|
||||
// }
|
||||
// *size = 0;
|
||||
// return DP_FAILURE;
|
||||
//}
|
||||
|
||||
ReturnValue_t DataPool::freeDataPoolLock() {
|
||||
ReturnValue_t status = mutex->unlockMutex();
|
||||
if ( status != RETURN_OK ) {
|
||||
sif::error << "DataPool::DataPool: unlock of mutex failed with error code: " << status << std::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
ReturnValue_t DataPool::lockDataPool() {
|
||||
ReturnValue_t status = mutex->lockMutex(MutexIF::NO_TIMEOUT);
|
||||
if ( status != RETURN_OK ) {
|
||||
sif::error << "DataPool::DataPool: lock of mutex failed with error code: " << status << std::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void DataPool::print() {
|
||||
sif::debug << "DataPool contains: " << std::endl;
|
||||
std::map<uint32_t, PoolEntryIF*>::iterator dataPoolIt;
|
||||
dataPoolIt = this->data_pool.begin();
|
||||
while( dataPoolIt != this->data_pool.end() ) {
|
||||
sif::debug << std::hex << dataPoolIt->first << std::dec << " |";
|
||||
dataPoolIt->second->print();
|
||||
dataPoolIt++;
|
||||
}
|
||||
}
|
||||
|
||||
template PoolEntry<uint8_t>* DataPool::getData<uint8_t>( uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<uint16_t>* DataPool::getData<uint16_t>( uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<uint32_t>* DataPool::getData<uint32_t>( uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<uint64_t>* DataPool::getData<uint64_t>(uint32_t data_pool_id,
|
||||
uint8_t size);
|
||||
template PoolEntry<int8_t>* DataPool::getData<int8_t>( uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<int16_t>* DataPool::getData<int16_t>( uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<int32_t>* DataPool::getData<int32_t>( uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<float>* DataPool::getData<float>( uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<double>* DataPool::getData<double>(uint32_t data_pool_id,
|
||||
uint8_t size);
|
||||
|
||||
|
||||
uint32_t DataPool::PIDToDataPoolId(uint32_t parameter_id) {
|
||||
return (parameter_id >> 8) & 0x00FFFFFF;
|
||||
}
|
||||
|
||||
uint8_t DataPool::PIDToArrayIndex(uint32_t parameter_id) {
|
||||
return (parameter_id & 0x000000FF);
|
||||
}
|
||||
|
||||
uint32_t DataPool::poolIdAndPositionToPid(uint32_t poolId, uint8_t index) {
|
||||
return (poolId << 8) + index;
|
||||
}
|
||||
|
||||
|
||||
//SHOULDDO: Do we need a mutex lock here... I don't think so, as we only check static const values of elements in a list that do not change.
|
||||
//there is no guarantee in the standard, but it seems to me that the implementation is safe -UM
|
||||
ReturnValue_t DataPool::getType(uint32_t parameter_id, Type* type) {
|
||||
std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( PIDToDataPoolId(parameter_id));
|
||||
if ( it != this->data_pool.end() ) {
|
||||
*type = it->second->getType();
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
*type = Type::UNKNOWN_TYPE;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
bool DataPool::exists(uint32_t parameterId) {
|
||||
uint32_t poolId = PIDToDataPoolId(parameterId);
|
||||
uint32_t index = PIDToArrayIndex(parameterId);
|
||||
std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( poolId );
|
||||
if (it != data_pool.end()) {
|
||||
if (it->second->getSize() >= index) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
135
datapool/DataPool.h
Normal file
135
datapool/DataPool.h
Normal file
@ -0,0 +1,135 @@
|
||||
/**
|
||||
* \file DataPool.h
|
||||
*
|
||||
* \date 10/17/2012
|
||||
* \author Bastian Baetz
|
||||
*
|
||||
* \brief This file contains the definition of the DataPool class and (temporarily)
|
||||
* the "extern" definition of the global dataPool instance.
|
||||
*/
|
||||
|
||||
#ifndef DATAPOOL_H_
|
||||
#define DATAPOOL_H_
|
||||
|
||||
#include "PoolEntry.h"
|
||||
#include "../globalfunctions/Type.h"
|
||||
#include "../ipc/MutexIF.h"
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* \defgroup data_pool Data Pool
|
||||
* This is the group, where all classes associated with Data Pool Handling belong to.
|
||||
* This includes classes to access Data Pool variables.
|
||||
*/
|
||||
|
||||
#define DP_SUCCESSFUL 0
|
||||
#define DP_FAILURE 1
|
||||
|
||||
/**
|
||||
* \brief This class represents the OBSW global data-pool.
|
||||
*
|
||||
* \details All variables are registered and space is allocated in an initialization
|
||||
* function, which is passed do the constructor.
|
||||
* Space for the variables is allocated on the heap (with a new call).
|
||||
* The data is found by a data pool id, which uniquely represents a variable.
|
||||
* Data pool variables should be used with a blackboard logic in mind,
|
||||
* which means read data is valid (if flagged so), but not necessarily up-to-date.
|
||||
* Variables are either single values or arrays.
|
||||
* \ingroup data_pool
|
||||
*/
|
||||
class DataPool : public HasReturnvaluesIF {
|
||||
private:
|
||||
/**
|
||||
* \brief This is the actual data pool itself.
|
||||
* \details It is represented by a map
|
||||
* with the data pool id as index and a pointer to a single PoolEntry as value.
|
||||
*/
|
||||
std::map<uint32_t, PoolEntryIF*> data_pool;
|
||||
public:
|
||||
/**
|
||||
* \brief The mutex is created in the constructor and makes access mutual exclusive.
|
||||
* \details Locking and unlocking the pool is only done by the DataSet class.
|
||||
*/
|
||||
MutexIF* mutex;
|
||||
/**
|
||||
* \brief In the classes constructor, the passed initialization function is called.
|
||||
* \details To enable filling the pool,
|
||||
* a pointer to the map is passed, allowing direct access to the pool's content.
|
||||
* On runtime, adding or removing variables is forbidden.
|
||||
*/
|
||||
DataPool( void ( *initFunction )( std::map<uint32_t, PoolEntryIF*>* pool_map ) );
|
||||
/**
|
||||
* \brief The destructor iterates through the data_pool map and calls all Entries destructors to clean up the heap.
|
||||
*/
|
||||
~DataPool();
|
||||
/**
|
||||
* \brief This is the default call to access the pool.
|
||||
* \details A pointer to the PoolEntry object is returned.
|
||||
* The call checks data pool id, type and array size. Returns NULL in case of failure.
|
||||
* \param data_pool_id The data pool id to search.
|
||||
* \param sizeOrPosition The array size (not byte size!) of the pool entry, or the position the user wants to read.
|
||||
* If smaller than the entry size, everything's ok.
|
||||
*/
|
||||
template <typename T> PoolEntry<T>* getData( uint32_t data_pool_id, uint8_t sizeOrPosition );
|
||||
/**
|
||||
* \brief An alternative call to get a data pool entry in case the type is not implicitly known
|
||||
* (i.e. in Housekeeping Telemetry).
|
||||
* \details It returns a basic interface and does NOT perform
|
||||
* a size check. The caller has to assure he does not copy too much data.
|
||||
* Returns NULL in case the entry is not found.
|
||||
* \param data_pool_id The data pool id to search.
|
||||
*/
|
||||
PoolEntryIF* getRawData( uint32_t data_pool_id );
|
||||
/**
|
||||
* \brief This is a small helper function to facilitate locking the global data pool.
|
||||
* \details It fetches the pool's mutex id and tries to acquire the mutex.
|
||||
*/
|
||||
ReturnValue_t lockDataPool();
|
||||
/**
|
||||
* \brief This is a small helper function to facilitate unlocking the global data pool.
|
||||
* \details It fetches the pool's mutex id and tries to free the mutex.
|
||||
*/
|
||||
ReturnValue_t freeDataPoolLock();
|
||||
/**
|
||||
* \brief The print call is a simple debug method.
|
||||
* \details It prints the current content of the data pool.
|
||||
* It iterates through the data_pool map and calls each entry's print() method.
|
||||
*/
|
||||
void print();
|
||||
/**
|
||||
* Extracts the data pool id from a SCOS 2000 PID.
|
||||
* @param parameter_id The passed Parameter ID.
|
||||
* @return The data pool id as used within the OBSW.
|
||||
*/
|
||||
static uint32_t PIDToDataPoolId( uint32_t parameter_id );
|
||||
/**
|
||||
* Extracts an array index out of a SCOS 2000 PID.
|
||||
* @param parameter_id The passed Parameter ID.
|
||||
* @return The index of the corresponding data pool entry.
|
||||
*/
|
||||
static uint8_t PIDToArrayIndex( uint32_t parameter_id );
|
||||
/**
|
||||
* Retransforms a data pool id and an array index to a SCOS 2000 PID.
|
||||
*/
|
||||
static uint32_t poolIdAndPositionToPid( uint32_t poolId, uint8_t index );
|
||||
|
||||
/**
|
||||
* Method to return the type of a pool variable.
|
||||
* @param parameter_id A parameterID (not pool id) of a DP member.
|
||||
* @param type Returns the type or TYPE::UNKNOWN_TYPE
|
||||
* @return RETURN_OK if parameter exists, RETURN_FAILED else.
|
||||
*/
|
||||
ReturnValue_t getType( uint32_t parameter_id, Type* type );
|
||||
|
||||
/**
|
||||
* Method to check if a PID exists.
|
||||
* Does not lock, as there's no possibility to alter the list that is checked during run-time.
|
||||
* @param parameterId The PID (not pool id!) of a parameter.
|
||||
* @return true if exists, false else.
|
||||
*/
|
||||
bool exists(uint32_t parameterId);
|
||||
};
|
||||
|
||||
//We assume someone globally instantiates a DataPool.
|
||||
extern DataPool dataPool;
|
||||
#endif /* DATAPOOL_H_ */
|
@ -1,10 +1,10 @@
|
||||
#include <framework/datapoolglob/DataPoolAdmin.h>
|
||||
#include <framework/datapoolglob/GlobalDataSet.h>
|
||||
#include <framework/datapoolglob/GlobalDataPool.h>
|
||||
#include <framework/datapoolglob/PoolRawAccess.h>
|
||||
#include <framework/ipc/CommandMessage.h>
|
||||
#include <framework/ipc/QueueFactory.h>
|
||||
#include <framework/parameters/ParameterMessage.h>
|
||||
#include "DataPool.h"
|
||||
#include "DataPoolAdmin.h"
|
||||
#include "DataSet.h"
|
||||
#include "PoolRawAccess.h"
|
||||
#include "../ipc/CommandMessage.h"
|
||||
#include "../ipc/QueueFactory.h"
|
||||
#include "../parameters/ParameterMessage.h"
|
||||
|
||||
DataPoolAdmin::DataPoolAdmin(object_id_t objectId) :
|
||||
SystemObject(objectId), storage(NULL), commandQueue(NULL), memoryHelper(
|
||||
@ -40,9 +40,9 @@ ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId,
|
||||
|
||||
uint8_t valid = data[4];
|
||||
|
||||
uint32_t poolId = glob::dataPool.PIDToDataPoolId(address);
|
||||
uint32_t poolId = ::dataPool.PIDToDataPoolId(address);
|
||||
|
||||
GlobDataSet mySet;
|
||||
DataSet mySet;
|
||||
PoolRawAccess variable(poolId, 0, &mySet, PoolVariableIF::VAR_READ_WRITE);
|
||||
ReturnValue_t status = mySet.read();
|
||||
if (status != RETURN_OK) {
|
||||
@ -92,9 +92,9 @@ void DataPoolAdmin::handleCommand() {
|
||||
|
||||
ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
|
||||
const uint8_t* data, size_t size, uint8_t** dataPointer) {
|
||||
uint32_t poolId = glob::dataPool.PIDToDataPoolId(address);
|
||||
uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address);
|
||||
GlobDataSet testSet;
|
||||
uint32_t poolId = ::dataPool.PIDToDataPoolId(address);
|
||||
uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address);
|
||||
DataSet testSet;
|
||||
PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet,
|
||||
PoolVariableIF::VAR_READ);
|
||||
ReturnValue_t status = testSet.read();
|
||||
@ -113,7 +113,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
|
||||
const uint8_t* readPosition = data;
|
||||
|
||||
for (; size > 0; size -= typeSize) {
|
||||
GlobDataSet rawSet;
|
||||
DataSet rawSet;
|
||||
PoolRawAccess variable(poolId, arrayIndex, &rawSet,
|
||||
PoolVariableIF::VAR_READ_WRITE);
|
||||
status = rawSet.read();
|
||||
@ -131,9 +131,9 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
|
||||
|
||||
ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, size_t size,
|
||||
uint8_t** dataPointer, uint8_t* copyHere) {
|
||||
uint32_t poolId = glob::dataPool.PIDToDataPoolId(address);
|
||||
uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address);
|
||||
GlobDataSet testSet;
|
||||
uint32_t poolId = ::dataPool.PIDToDataPoolId(address);
|
||||
uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address);
|
||||
DataSet testSet;
|
||||
PoolRawAccess varToGetSize(poolId, arrayIndex, &testSet,
|
||||
PoolVariableIF::VAR_READ);
|
||||
ReturnValue_t status = testSet.read();
|
||||
@ -146,7 +146,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, size_t size,
|
||||
}
|
||||
uint8_t* ptrToCopy = copyHere;
|
||||
for (; size > 0; size -= typeSize) {
|
||||
GlobDataSet rawSet;
|
||||
DataSet rawSet;
|
||||
PoolRawAccess variable(poolId, arrayIndex, &rawSet,
|
||||
PoolVariableIF::VAR_READ);
|
||||
status = rawSet.read();
|
@ -1,16 +1,15 @@
|
||||
#ifndef DATAPOOLADMIN_H_
|
||||
#define DATAPOOLADMIN_H_
|
||||
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
#include <framework/action/HasActionsIF.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
#include <framework/parameters/ReceivesParameterMessagesIF.h>
|
||||
|
||||
#include <framework/memory/MemoryHelper.h>
|
||||
#include <framework/action/SimpleActionHelper.h>
|
||||
#include <framework/datapoolglob/DataPoolParameterWrapper.h>
|
||||
#include "../memory/MemoryHelper.h"
|
||||
#include "../action/HasActionsIF.h"
|
||||
#include "../action/SimpleActionHelper.h"
|
||||
#include "../objectmanager/SystemObject.h"
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../tasks/ExecutableObjectIF.h"
|
||||
#include "../parameters/ReceivesParameterMessagesIF.h"
|
||||
#include "DataPoolParameterWrapper.h"
|
||||
#include "../ipc/MessageQueueIF.h"
|
||||
|
||||
class DataPoolAdmin: public HasActionsIF,
|
||||
public ExecutableObjectIF,
|
@ -1,8 +1,10 @@
|
||||
#include <framework/datapoolglob/GlobalDataSet.h>
|
||||
#include <framework/datapoolglob/DataPoolParameterWrapper.h>
|
||||
#include <framework/datapoolglob/PoolRawAccess.h>
|
||||
#include <framework/parameters/HasParametersIF.h>
|
||||
#include "DataPoolParameterWrapper.h"
|
||||
|
||||
//for returncodes
|
||||
#include "../parameters/HasParametersIF.h"
|
||||
|
||||
#include "DataSet.h"
|
||||
#include "PoolRawAccess.h"
|
||||
|
||||
DataPoolParameterWrapper::DataPoolParameterWrapper() :
|
||||
type(Type::UNKNOWN_TYPE), rows(0), columns(0), poolId(
|
||||
@ -18,7 +20,7 @@ ReturnValue_t DataPoolParameterWrapper::set(uint8_t domainId,
|
||||
uint16_t parameterId) {
|
||||
poolId = (domainId << 16) + parameterId;
|
||||
|
||||
GlobDataSet mySet;
|
||||
DataSet mySet;
|
||||
PoolRawAccess raw(poolId, 0, &mySet, PoolVariableIF::VAR_READ);
|
||||
ReturnValue_t status = mySet.read();
|
||||
if (status != HasReturnvaluesIF::RETURN_OK) {
|
||||
@ -55,7 +57,7 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer,
|
||||
}
|
||||
|
||||
for (uint8_t index = 0; index < rows; index++){
|
||||
GlobDataSet mySet;
|
||||
DataSet mySet;
|
||||
PoolRawAccess raw(poolId, index, &mySet,PoolVariableIF::VAR_READ);
|
||||
mySet.read();
|
||||
result = raw.serialize(buffer,size,maxSize,streamEndianness);
|
||||
@ -92,7 +94,7 @@ ReturnValue_t DataPoolParameterWrapper::deSerializeData(uint8_t startingRow,
|
||||
|
||||
for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) {
|
||||
|
||||
GlobDataSet mySet;
|
||||
DataSet mySet;
|
||||
PoolRawAccess raw(poolId, startingRow + fromRow, &mySet,
|
||||
PoolVariableIF::VAR_READ_WRITE);
|
||||
mySet.read();
|
@ -1,8 +1,8 @@
|
||||
#ifndef DATAPOOLPARAMETERWRAPPER_H_
|
||||
#define DATAPOOLPARAMETERWRAPPER_H_
|
||||
|
||||
#include <framework/globalfunctions/Type.h>
|
||||
#include <framework/parameters/ParameterWrapper.h>
|
||||
#include "../globalfunctions/Type.h"
|
||||
#include "../parameters/ParameterWrapper.h"
|
||||
|
||||
class DataPoolParameterWrapper: public SerializeIF {
|
||||
public:
|
150
datapool/DataSet.cpp
Normal file
150
datapool/DataSet.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
#include "DataSet.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
DataSet::DataSet() :
|
||||
fill_count(0), state(DATA_SET_UNINITIALISED) {
|
||||
for (unsigned count = 0; count < DATA_SET_MAX_SIZE; count++) {
|
||||
registeredVariables[count] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DataSet::~DataSet() {
|
||||
//Don't do anything with your variables, they are dead already! (Destructor is already called)
|
||||
}
|
||||
|
||||
ReturnValue_t DataSet::read() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
if (state == DATA_SET_UNINITIALISED) {
|
||||
lockDataPool();
|
||||
for (uint16_t count = 0; count < fill_count; count++) {
|
||||
if (registeredVariables[count]->getReadWriteMode()
|
||||
!= PoolVariableIF::VAR_WRITE
|
||||
&& registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
ReturnValue_t status = registeredVariables[count]->read();
|
||||
if (status != RETURN_OK) {
|
||||
result = INVALID_PARAMETER_DEFINITION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
state = DATA_SET_WAS_READ;
|
||||
freeDataPoolLock();
|
||||
} else {
|
||||
sif::error << "DataSet::read(): Call made in wrong position." << std::endl;
|
||||
result = SET_WAS_ALREADY_READ;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t DataSet::commit(uint8_t valid) {
|
||||
setValid(valid);
|
||||
return commit();
|
||||
}
|
||||
|
||||
ReturnValue_t DataSet::commit() {
|
||||
if (state == DATA_SET_WAS_READ) {
|
||||
lockDataPool();
|
||||
for (uint16_t count = 0; count < fill_count; count++) {
|
||||
if (registeredVariables[count]->getReadWriteMode()
|
||||
!= PoolVariableIF::VAR_READ
|
||||
&& registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
registeredVariables[count]->commit();
|
||||
}
|
||||
}
|
||||
state = DATA_SET_UNINITIALISED;
|
||||
freeDataPoolLock();
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
lockDataPool();
|
||||
for (uint16_t count = 0; count < fill_count; count++) {
|
||||
if (registeredVariables[count]->getReadWriteMode()
|
||||
== PoolVariableIF::VAR_WRITE
|
||||
&& registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
registeredVariables[count]->commit();
|
||||
} else if (registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
if (result != COMMITING_WITHOUT_READING) {
|
||||
sif::error <<
|
||||
"DataSet::commit(): commit-without-read "
|
||||
"call made with non write-only variable." << std::endl;
|
||||
result = COMMITING_WITHOUT_READING;
|
||||
}
|
||||
}
|
||||
}
|
||||
state = DATA_SET_UNINITIALISED;
|
||||
freeDataPoolLock();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DataSet::registerVariable(PoolVariableIF* variable) {
|
||||
if (state == DATA_SET_UNINITIALISED) {
|
||||
if (variable != NULL) {
|
||||
if (fill_count < DATA_SET_MAX_SIZE) {
|
||||
registeredVariables[fill_count] = variable;
|
||||
fill_count++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
sif::error
|
||||
<< "DataSet::registerVariable: failed. Either NULL, or set is full, or call made in wrong position."
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t DataSet::freeDataPoolLock() {
|
||||
return ::dataPool.freeDataPoolLock();
|
||||
}
|
||||
|
||||
uint8_t DataSet::lockDataPool() {
|
||||
return ::dataPool.lockDataPool();
|
||||
}
|
||||
|
||||
ReturnValue_t DataSet::serialize(uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) const {
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
for (uint16_t count = 0; count < fill_count; count++) {
|
||||
result = registeredVariables[count]->serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t DataSet::getSerializedSize() const {
|
||||
size_t size = 0;
|
||||
for (uint16_t count = 0; count < fill_count; count++) {
|
||||
size += registeredVariables[count]->getSerializedSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void DataSet::setValid(uint8_t valid) {
|
||||
for (uint16_t count = 0; count < fill_count; count++) {
|
||||
if (registeredVariables[count]->getReadWriteMode()
|
||||
!= PoolVariableIF::VAR_READ) {
|
||||
registeredVariables[count]->setValid(valid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t DataSet::deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) {
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
for (uint16_t count = 0; count < fill_count; count++) {
|
||||
result = registeredVariables[count]->deSerialize(buffer, size,
|
||||
streamEndianness);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
159
datapool/DataSet.h
Normal file
159
datapool/DataSet.h
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* \file DataSet.h
|
||||
*
|
||||
* \brief This file contains the DataSet class and a small structure called DataSetContent.
|
||||
*
|
||||
* \date 10/17/2012
|
||||
*
|
||||
* \author Bastian Baetz
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DATASET_H_
|
||||
#define DATASET_H_
|
||||
|
||||
#include "DataPool.h"
|
||||
#include "DataSetIF.h"
|
||||
#include "PoolRawAccess.h"
|
||||
#include "PoolVariable.h"
|
||||
#include "PoolVarList.h"
|
||||
#include "PoolVector.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
/**
|
||||
* \brief The DataSet class manages a set of locally checked out variables.
|
||||
*
|
||||
* \details This class manages a list, where a set of local variables (or pool variables) are
|
||||
* registered. They are checked-out (i.e. their values are looked up and copied)
|
||||
* with the read call. After the user finishes working with the pool variables,
|
||||
* he can write back all variable values to the pool with the commit call.
|
||||
* The data set manages locking and freeing the data pool, to ensure that all values
|
||||
* are read and written back at once.
|
||||
* An internal state manages usage of this class. Variables may only be registered before
|
||||
* the read call is made, and the commit call only after the read call.
|
||||
* If pool variables are writable and not committed until destruction of the set, the
|
||||
* DataSet class automatically sets the valid flag in the data pool to invalid (without)
|
||||
* changing the variable's value.
|
||||
*
|
||||
* \ingroup data_pool
|
||||
*/
|
||||
class DataSet: public DataSetIF, public HasReturnvaluesIF, public SerializeIF {
|
||||
private:
|
||||
//SHOULDDO we could use a linked list of datapool variables
|
||||
static const uint8_t DATA_SET_MAX_SIZE = 63; //!< This definition sets the maximum number of variables to register in one DataSet.
|
||||
|
||||
/**
|
||||
* \brief This array represents all pool variables registered in this set.
|
||||
* \details It has a maximum size of DATA_SET_MAX_SIZE.
|
||||
*/
|
||||
PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE];
|
||||
/**
|
||||
* \brief The fill_count attribute ensures that the variables register in the correct array
|
||||
* position and that the maximum number of variables is not exceeded.
|
||||
*/
|
||||
uint16_t fill_count;
|
||||
/**
|
||||
* States of the seet.
|
||||
*/
|
||||
enum States {
|
||||
DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED
|
||||
DATA_SET_WAS_READ //!< DATA_SET_WAS_READ
|
||||
};
|
||||
/**
|
||||
* \brief state manages the internal state of the data set, which is important e.g. for the
|
||||
* behavior on destruction.
|
||||
*/
|
||||
States state;
|
||||
/**
|
||||
* \brief This is a small helper function to facilitate locking the global data pool.
|
||||
* \details It makes use of the lockDataPool method offered by the DataPool class.
|
||||
*/
|
||||
uint8_t lockDataPool();
|
||||
/**
|
||||
* \brief This is a small helper function to facilitate unlocking the global data pool.
|
||||
* \details It makes use of the freeDataPoolLock method offered by the DataPool class.
|
||||
*/
|
||||
uint8_t freeDataPoolLock();
|
||||
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS;
|
||||
static const ReturnValue_t INVALID_PARAMETER_DEFINITION =
|
||||
MAKE_RETURN_CODE( 0x01 );
|
||||
static const ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 );
|
||||
static const ReturnValue_t COMMITING_WITHOUT_READING =
|
||||
MAKE_RETURN_CODE(0x03);
|
||||
|
||||
/**
|
||||
* \brief The constructor simply sets the fill_count to zero and sets the state to "uninitialized".
|
||||
*/
|
||||
DataSet();
|
||||
/**
|
||||
* \brief The destructor automatically manages writing the valid information of variables.
|
||||
* \details In case the data set was read out, but not committed (indicated by state),
|
||||
* the destructor parses all variables that are still registered to the set.
|
||||
* For each, the valid flag in the data pool is set to "invalid".
|
||||
*/
|
||||
~DataSet();
|
||||
/**
|
||||
* \brief The read call initializes reading out all registered variables.
|
||||
* \details It iterates through the list of registered variables and calls all read()
|
||||
* functions of the registered pool variables (which read out their values from the
|
||||
* data pool) which are not write-only. In case of an error (e.g. a wrong data type,
|
||||
* or an invalid data pool id), the operation is aborted and
|
||||
* \c INVALID_PARAMETER_DEFINITION returned.
|
||||
* The data pool is locked during the whole read operation and freed afterwards.
|
||||
* The state changes to "was written" after this operation.
|
||||
* \return - \c RETURN_OK if all variables were read successfully.
|
||||
* - \c INVALID_PARAMETER_DEFINITION if PID, size or type of the
|
||||
* requested variable is invalid.
|
||||
* - \c SET_WAS_ALREADY_READ if read() is called twice without calling
|
||||
* commit() in between
|
||||
*/
|
||||
ReturnValue_t read();
|
||||
/**
|
||||
* \brief The commit call initializes writing back the registered variables.
|
||||
* \details It iterates through the list of registered variables and calls
|
||||
* the commit() method of the remaining registered variables (which write back
|
||||
* their values to the pool).
|
||||
* The data pool is locked during the whole commit operation and freed afterwards.
|
||||
* The state changes to "was committed" after this operation.
|
||||
* If the set does contain at least one variable which is not write-only commit()
|
||||
* can only be called after read(). If the set only contains variables which are
|
||||
* write only, commit() can be called without a preceding read() call.
|
||||
* \return - \c RETURN_OK if all variables were read successfully.
|
||||
* - \c COMMITING_WITHOUT_READING if set was not read yet and contains non write-only
|
||||
* variables
|
||||
*/
|
||||
ReturnValue_t commit(void);
|
||||
/**
|
||||
* Variant of method above which sets validity of all elements of the set.
|
||||
* @param valid Validity information from PoolVariableIF.
|
||||
* \return - \c RETURN_OK if all variables were read successfully.
|
||||
* - \c COMMITING_WITHOUT_READING if set was not read yet and contains non write-only
|
||||
* variables
|
||||
*/
|
||||
ReturnValue_t commit(uint8_t valid);
|
||||
/**
|
||||
* \brief This operation is used to register the local variables in the set.
|
||||
* \details It copies all required information to the currently
|
||||
* free space in the registeredVariables list.
|
||||
*/
|
||||
void registerVariable(PoolVariableIF* variable);
|
||||
|
||||
/**
|
||||
* Set the valid information of all variables contained in the set which are not readonly
|
||||
*
|
||||
* @param valid Validity information from PoolVariableIF.
|
||||
*/
|
||||
void setValid(uint8_t valid);
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
};
|
||||
|
||||
#endif /* DATASET_H_ */
|
@ -1,168 +0,0 @@
|
||||
#include <framework/datapool/DataSetBase.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
DataSetBase::DataSetBase(PoolVariableIF** registeredVariablesArray,
|
||||
const size_t maxFillCount):
|
||||
registeredVariables(registeredVariablesArray),
|
||||
maxFillCount(maxFillCount) {
|
||||
for (uint8_t count = 0; count < maxFillCount; count++) {
|
||||
registeredVariables[count] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DataSetBase::~DataSetBase() {}
|
||||
|
||||
ReturnValue_t DataSetBase::registerVariable(
|
||||
PoolVariableIF *variable) {
|
||||
if (state != States::DATA_SET_UNINITIALISED) {
|
||||
sif::error << "DataSet::registerVariable: "
|
||||
"Call made in wrong position." << std::endl;
|
||||
return DataSetIF::DATA_SET_UNINITIALISED;
|
||||
}
|
||||
if (variable == nullptr) {
|
||||
sif::error << "DataSet::registerVariable: "
|
||||
"Pool variable is nullptr." << std::endl;
|
||||
return DataSetIF::POOL_VAR_NULL;
|
||||
}
|
||||
if (fillCount >= maxFillCount) {
|
||||
sif::error << "DataSet::registerVariable: "
|
||||
"DataSet is full." << std::endl;
|
||||
return DataSetIF::DATA_SET_FULL;
|
||||
}
|
||||
registeredVariables[fillCount] = variable;
|
||||
fillCount++;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t DataSetBase::read(uint32_t lockTimeout) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
if (state == States::DATA_SET_UNINITIALISED) {
|
||||
lockDataPool(lockTimeout);
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
result = readVariable(count);
|
||||
if(result != RETURN_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
state = States::DATA_SET_WAS_READ;
|
||||
unlockDataPool();
|
||||
}
|
||||
else {
|
||||
sif::error << "DataSet::read(): "
|
||||
"Call made in wrong position. Don't forget to commit"
|
||||
" member datasets!" << std::endl;
|
||||
result = SET_WAS_ALREADY_READ;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t DataSetBase::getFillCount() const {
|
||||
return fillCount;
|
||||
}
|
||||
|
||||
ReturnValue_t DataSetBase::readVariable(uint16_t count) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
// These checks are often performed by the respective
|
||||
// variable implementation too, but I guess a double check does not hurt.
|
||||
if (registeredVariables[count]->getReadWriteMode() !=
|
||||
PoolVariableIF::VAR_WRITE and
|
||||
registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER)
|
||||
{
|
||||
result = registeredVariables[count]->readWithoutLock();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
result = INVALID_PARAMETER_DEFINITION;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t DataSetBase::commit(uint32_t lockTimeout) {
|
||||
if (state == States::DATA_SET_WAS_READ) {
|
||||
handleAlreadyReadDatasetCommit(lockTimeout);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
else {
|
||||
return handleUnreadDatasetCommit(lockTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
void DataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) {
|
||||
lockDataPool(lockTimeout);
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
if (registeredVariables[count]->getReadWriteMode()
|
||||
!= PoolVariableIF::VAR_READ
|
||||
&& registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
registeredVariables[count]->commitWithoutLock();
|
||||
}
|
||||
}
|
||||
state = States::DATA_SET_UNINITIALISED;
|
||||
unlockDataPool();
|
||||
}
|
||||
|
||||
ReturnValue_t DataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
lockDataPool(lockTimeout);
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
if (registeredVariables[count]->getReadWriteMode()
|
||||
== PoolVariableIF::VAR_WRITE
|
||||
&& registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
registeredVariables[count]->commitWithoutLock();
|
||||
} else if (registeredVariables[count]->getDataPoolId()
|
||||
!= PoolVariableIF::NO_PARAMETER) {
|
||||
if (result != COMMITING_WITHOUT_READING) {
|
||||
sif::error << "DataSet::commit(): commit-without-read call made "
|
||||
"with non write-only variable." << std::endl;
|
||||
result = COMMITING_WITHOUT_READING;
|
||||
}
|
||||
}
|
||||
}
|
||||
state = States::DATA_SET_UNINITIALISED;
|
||||
unlockDataPool();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t DataSetBase::lockDataPool(uint32_t timeoutMs) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t DataSetBase::unlockDataPool() {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t DataSetBase::serialize(uint8_t** buffer, size_t* size,
|
||||
const size_t maxSize, SerializeIF::Endianness streamEndianness) const {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
result = registeredVariables[count]->serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t DataSetBase::deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
result = registeredVariables[count]->deSerialize(buffer, size,
|
||||
streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t DataSetBase::getSerializedSize() const {
|
||||
uint32_t size = 0;
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
size += registeredVariables[count]->getSerializedSize();
|
||||
}
|
||||
return size;
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
#ifndef FRAMEWORK_DATAPOOL_DATASETBASE_H_
|
||||
#define FRAMEWORK_DATAPOOL_DATASETBASE_H_
|
||||
#include <framework/datapool/DataSetIF.h>
|
||||
#include <framework/datapool/PoolVariableIF.h>
|
||||
#include <framework/ipc/MutexIF.h>
|
||||
|
||||
/**
|
||||
* @brief The DataSetBase class manages a set of locally checked out variables.
|
||||
* @details
|
||||
* This class manages a list, where a set of local variables (or pool variables)
|
||||
* are registered. They are checked-out (i.e. their values are looked
|
||||
* up and copied) with the read call. After the user finishes working with the
|
||||
* pool variables, he can write back all variable values to the pool with
|
||||
* the commit call. The data set manages locking and freeing the data pool,
|
||||
* to ensure that all values are read and written back at once.
|
||||
*
|
||||
* An internal state manages usage of this class. Variables may only be
|
||||
* registered before the read call is made, and the commit call only
|
||||
* after the read call.
|
||||
*
|
||||
* If pool variables are writable and not committed until destruction
|
||||
* of the set, the DataSet class automatically sets the valid flag in the
|
||||
* data pool to invalid (without) changing the variable's value.
|
||||
*
|
||||
* The base class lockDataPool und unlockDataPool implementation are empty
|
||||
* and should be implemented to protect the underlying pool type.
|
||||
* @author Bastian Baetz
|
||||
* @ingroup data_pool
|
||||
*/
|
||||
class DataSetBase: public DataSetIF,
|
||||
public SerializeIF,
|
||||
public HasReturnvaluesIF {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Creates an empty dataset. Use registerVariable or
|
||||
* supply a pointer to this dataset to PoolVariable
|
||||
* initializations to register pool variables.
|
||||
*/
|
||||
DataSetBase(PoolVariableIF** registeredVariablesArray,
|
||||
const size_t maxFillCount);
|
||||
virtual~ DataSetBase();
|
||||
|
||||
/**
|
||||
* @brief The read call initializes reading out all registered variables.
|
||||
* @details
|
||||
* It iterates through the list of registered variables and calls all read()
|
||||
* functions of the registered pool variables (which read out their values
|
||||
* from the data pool) which are not write-only.
|
||||
* In case of an error (e.g. a wrong data type, or an invalid data pool id),
|
||||
* the operation is aborted and @c INVALID_PARAMETER_DEFINITION returned.
|
||||
*
|
||||
* The data pool is locked during the whole read operation and
|
||||
* freed afterwards.The state changes to "was written" after this operation.
|
||||
* @return
|
||||
* - @c RETURN_OK if all variables were read successfully.
|
||||
* - @c INVALID_PARAMETER_DEFINITION if PID, size or type of the
|
||||
* requested variable is invalid.
|
||||
* - @c SET_WAS_ALREADY_READ if read() is called twice without calling
|
||||
* commit() in between
|
||||
*/
|
||||
virtual ReturnValue_t read(uint32_t lockTimeout =
|
||||
MutexIF::BLOCKING) override;
|
||||
/**
|
||||
* @brief The commit call initializes writing back the registered variables.
|
||||
* @details
|
||||
* It iterates through the list of registered variables and calls the
|
||||
* commit() method of the remaining registered variables (which write back
|
||||
* their values to the pool).
|
||||
*
|
||||
* The data pool is locked during the whole commit operation and
|
||||
* freed afterwards. The state changes to "was committed" after this operation.
|
||||
*
|
||||
* If the set does contain at least one variable which is not write-only
|
||||
* commit() can only be called after read(). If the set only contains
|
||||
* variables which are write only, commit() can be called without a
|
||||
* preceding read() call.
|
||||
* @return - @c RETURN_OK if all variables were read successfully.
|
||||
* - @c COMMITING_WITHOUT_READING if set was not read yet and
|
||||
* contains non write-only variables
|
||||
*/
|
||||
virtual ReturnValue_t commit(uint32_t lockTimeout =
|
||||
MutexIF::BLOCKING) override;
|
||||
|
||||
/**
|
||||
* Register the passed pool variable instance into the data set.
|
||||
* @param variable
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override;
|
||||
/**
|
||||
* Provides the means to lock the underlying data structure to ensure
|
||||
* thread-safety. Default implementation is empty
|
||||
* @return Always returns -@c RETURN_OK
|
||||
*/
|
||||
virtual ReturnValue_t lockDataPool(uint32_t timeoutMs =
|
||||
MutexIF::BLOCKING) override;
|
||||
/**
|
||||
* Provides the means to unlock the underlying data structure to ensure
|
||||
* thread-safety. Default implementation is empty
|
||||
* @return Always returns -@c RETURN_OK
|
||||
*/
|
||||
virtual ReturnValue_t unlockDataPool() override;
|
||||
|
||||
virtual uint16_t getFillCount() const;
|
||||
|
||||
/* SerializeIF implementations */
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
const size_t maxSize,
|
||||
SerializeIF::Endianness streamEndianness) const override;
|
||||
virtual size_t getSerializedSize() const override;
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief The fill_count attribute ensures that the variables
|
||||
* register in the correct array position and that the maximum
|
||||
* number of variables is not exceeded.
|
||||
*/
|
||||
uint16_t fillCount = 0;
|
||||
/**
|
||||
* States of the seet.
|
||||
*/
|
||||
enum class States {
|
||||
DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED
|
||||
DATA_SET_WAS_READ //!< DATA_SET_WAS_READ
|
||||
};
|
||||
/**
|
||||
* @brief state manages the internal state of the data set,
|
||||
* which is important e.g. for the behavior on destruction.
|
||||
*/
|
||||
States state = States::DATA_SET_UNINITIALISED;
|
||||
|
||||
/**
|
||||
* @brief This array represents all pool variables registered in this set.
|
||||
* Child classes can use a static or dynamic container to create
|
||||
* an array of registered variables and assign the first entry here.
|
||||
*/
|
||||
PoolVariableIF** registeredVariables = nullptr;
|
||||
const size_t maxFillCount = 0;
|
||||
|
||||
private:
|
||||
ReturnValue_t readVariable(uint16_t count);
|
||||
void handleAlreadyReadDatasetCommit(uint32_t lockTimeout);
|
||||
ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout);
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_DATAPOOL_DATASETBASE_H_ */
|
@ -1,62 +1,39 @@
|
||||
/**
|
||||
* \file DataSetIF.h
|
||||
*
|
||||
* \brief This file contains the small interface to access the DataSet class.
|
||||
*
|
||||
* \date 10/23/2012
|
||||
*
|
||||
* \author Bastian Baetz
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DATASETIF_H_
|
||||
#define DATASETIF_H_
|
||||
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/timemanager/Clock.h>
|
||||
class PoolVariableIF;
|
||||
|
||||
/**
|
||||
* @brief This class defines a small interface to register on a DataSet.
|
||||
* \brief This class defines a small interface to register on a DataSet.
|
||||
*
|
||||
* @details
|
||||
* Currently, the only purpose of this interface is to provide a
|
||||
* method for locally checked-out variables to register on a data set.
|
||||
* Still, it may become useful for other purposes as well.
|
||||
* @author Bastian Baetz
|
||||
* @ingroup data_pool
|
||||
* \details Currently, the only purpose of this interface is to provide a method for locally
|
||||
* checked-out variables to register on a data set. Still, it may become useful for
|
||||
* other purposes as well.
|
||||
*
|
||||
* \ingroup data_pool
|
||||
*/
|
||||
class DataSetIF {
|
||||
public:
|
||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS;
|
||||
static constexpr ReturnValue_t INVALID_PARAMETER_DEFINITION =
|
||||
MAKE_RETURN_CODE( 0x01 );
|
||||
static constexpr ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 );
|
||||
static constexpr ReturnValue_t COMMITING_WITHOUT_READING =
|
||||
MAKE_RETURN_CODE(0x03);
|
||||
|
||||
static constexpr ReturnValue_t DATA_SET_UNINITIALISED = MAKE_RETURN_CODE( 0x04 );
|
||||
static constexpr ReturnValue_t DATA_SET_FULL = MAKE_RETURN_CODE( 0x05 );
|
||||
static constexpr ReturnValue_t POOL_VAR_NULL = MAKE_RETURN_CODE( 0x06 );
|
||||
|
||||
/**
|
||||
* @brief This is an empty virtual destructor,
|
||||
* as it is proposed for C++ interfaces.
|
||||
* \brief This is an empty virtual destructor, as it is proposed for C++ interfaces.
|
||||
*/
|
||||
virtual ~DataSetIF() {}
|
||||
|
||||
virtual ReturnValue_t read(uint32_t lockTimeout) = 0;
|
||||
virtual ReturnValue_t commit(uint32_t lockTimeout) = 0;
|
||||
/**
|
||||
* @brief This operation provides a method to register local data pool
|
||||
* variables to register in a data set by passing itself
|
||||
* to this DataSet operation.
|
||||
* \brief This operation provides a method to register local data pool variables
|
||||
* to register in a data set by passing itself to this DataSet operation.
|
||||
*/
|
||||
virtual ReturnValue_t registerVariable(PoolVariableIF* variable) = 0;
|
||||
|
||||
virtual uint16_t getFillCount() const = 0;
|
||||
private:
|
||||
/**
|
||||
* @brief Most underlying data structures will have a pool like structure
|
||||
* and will require a lock and unlock mechanism to ensure
|
||||
* thread-safety
|
||||
* @return Lock operation result
|
||||
*/
|
||||
virtual ReturnValue_t lockDataPool(uint32_t timeoutMs) = 0;
|
||||
/**
|
||||
* @brief Unlock call corresponding to the lock call.
|
||||
* @return Unlock operation result
|
||||
*/
|
||||
virtual ReturnValue_t unlockDataPool() = 0;
|
||||
virtual void registerVariable( PoolVariableIF* variable ) = 0;
|
||||
};
|
||||
|
||||
#endif /* DATASETIF_H_ */
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <framework/datapool/HkSwitchHelper.h>
|
||||
#include <framework/ipc/QueueFactory.h>
|
||||
#include "HkSwitchHelper.h"
|
||||
//#include <mission/tmtcservices/HKService_03.h>
|
||||
#include "../ipc/QueueFactory.h"
|
||||
|
||||
HkSwitchHelper::HkSwitchHelper(EventReportingProxyIF* eventProxy) :
|
||||
commandActionHelper(this), eventProxy(eventProxy) {
|
||||
@ -21,14 +22,14 @@ ReturnValue_t HkSwitchHelper::initialize() {
|
||||
}
|
||||
|
||||
ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) {
|
||||
CommandMessage command;
|
||||
while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t result = commandActionHelper.handleReply(&command);
|
||||
CommandMessage message;
|
||||
while (actionQueue->receiveMessage(&message) == HasReturnvaluesIF::RETURN_OK) {
|
||||
ReturnValue_t result = commandActionHelper.handleReply(&message);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
continue;
|
||||
}
|
||||
command.setToUnknownCommand();
|
||||
actionQueue->reply(&command);
|
||||
message.setToUnknownCommand();
|
||||
actionQueue->reply(&message);
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_
|
||||
#define FRAMEWORK_DATAPOOL_HKSWITCHHELPER_H_
|
||||
|
||||
#include <framework/tasks/ExecutableObjectIF.h>
|
||||
#include <framework/action/CommandsActionsIF.h>
|
||||
#include <framework/events/EventReportingProxyIF.h>
|
||||
#include "../tasks/ExecutableObjectIF.h"
|
||||
#include "../action/CommandsActionsIF.h"
|
||||
#include "../events/EventReportingProxyIF.h"
|
||||
|
||||
//TODO this class violations separation between mission and framework
|
||||
//but it is only a transitional solution until the Datapool is
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef PIDREADER_H_
|
||||
#define PIDREADER_H_
|
||||
#include <framework/datapool/DataSetIF.h>
|
||||
#include <framework/datapoolglob/GlobalDataPool.h>
|
||||
#include <framework/datapool/PoolEntry.h>
|
||||
#include <framework/datapool/PoolVariableIF.h>
|
||||
#include <framework/serialize/SerializeAdapter.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include "DataPool.h"
|
||||
#include "DataSetIF.h"
|
||||
#include "PoolEntry.h"
|
||||
#include "PoolVariableIF.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
template<typename U, uint8_t n_var> class PIDReaderList;
|
||||
|
||||
@ -15,10 +15,10 @@ class PIDReader: public PoolVariableIF {
|
||||
protected:
|
||||
uint32_t parameterId;
|
||||
uint8_t valid;
|
||||
ReturnValue_t readWithoutLock() {
|
||||
uint8_t arrayIndex = GlobalDataPool::PIDToArrayIndex(parameterId);
|
||||
PoolEntry<T> *read_out = glob::dataPool.getData<T>(
|
||||
GlobalDataPool::PIDToDataPoolId(parameterId), arrayIndex);
|
||||
ReturnValue_t read() {
|
||||
uint8_t arrayIndex = DataPool::PIDToArrayIndex(parameterId);
|
||||
PoolEntry<T> *read_out = ::dataPool.getData<T>(
|
||||
DataPool::PIDToDataPoolId(parameterId), arrayIndex);
|
||||
if (read_out != NULL) {
|
||||
valid = read_out->valid;
|
||||
value = read_out->address[arrayIndex];
|
||||
@ -36,13 +36,9 @@ protected:
|
||||
* Reason is the possibility to access a single DP vector element, but if we commit,
|
||||
* we set validity of the whole vector.
|
||||
*/
|
||||
ReturnValue_t commit(uint32_t lockTimeout) override {
|
||||
ReturnValue_t commit() {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
ReturnValue_t commitWithoutLock() override {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty ctor for List initialization
|
||||
*/
|
||||
@ -76,19 +72,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t read(uint32_t lockTimeout) override {
|
||||
ReturnValue_t result = glob::dataPool.lockDataPool();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = readWithoutLock();
|
||||
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
|
||||
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "PIDReader::read: Could not unlock data pool!"
|
||||
<< std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Copy ctor to copy classes containing Pool Variables.
|
||||
*/
|
||||
@ -106,7 +89,7 @@ public:
|
||||
* \brief This operation returns the data pool id of the variable.
|
||||
*/
|
||||
uint32_t getDataPoolId() const {
|
||||
return GlobalDataPool::PIDToDataPoolId(parameterId);
|
||||
return DataPool::PIDToDataPoolId(parameterId);
|
||||
}
|
||||
uint32_t getParameterId() const {
|
||||
return parameterId;
|
||||
@ -131,7 +114,7 @@ public:
|
||||
return valid;
|
||||
}
|
||||
|
||||
void setValid(bool valid) {
|
||||
void setValid(uint8_t valid) {
|
||||
this->valid = valid;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_
|
||||
#define FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_
|
||||
#ifndef FRAMEWORK_DATAPOOL_PIDREADERLIST_H_
|
||||
#define FRAMEWORK_DATAPOOL_PIDREADERLIST_H_
|
||||
|
||||
#include <framework/datapool/PoolVariableIF.h>
|
||||
#include <framework/datapoolglob/PIDReader.h>
|
||||
#include "PIDReader.h"
|
||||
#include "PoolVariableIF.h"
|
||||
template <class T, uint8_t n_var>
|
||||
class PIDReaderList {
|
||||
private:
|
||||
@ -24,4 +24,4 @@ public:
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_DATAPOOLGLOB_PIDREADERLIST_H_ */
|
||||
#endif /* FRAMEWORK_DATAPOOL_PIDREADERLIST_H_ */
|
@ -1,6 +1,6 @@
|
||||
#include <framework/datapool/PoolEntry.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/globalfunctions/arrayprinter.h>
|
||||
#include "PoolEntry.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../globalfunctions/arrayprinter.h"
|
||||
#include <cstring>
|
||||
|
||||
template <typename T>
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_
|
||||
#define FRAMEWORK_DATAPOOL_POOLENTRY_H_
|
||||
|
||||
#include <framework/datapool/PoolEntryIF.h>
|
||||
#include "PoolEntryIF.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
|
||||
#define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
|
||||
|
||||
#include <framework/globalfunctions/Type.h>
|
||||
#include "../globalfunctions/Type.h"
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
|
187
datapool/PoolRawAccess.cpp
Normal file
187
datapool/PoolRawAccess.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include "DataPool.h"
|
||||
#include "PoolEntryIF.h"
|
||||
#include "PoolRawAccess.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../serialize/EndianConverter.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry,
|
||||
DataSetIF *data_set, ReadWriteMode_t setReadWriteMode) :
|
||||
dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type(
|
||||
Type::UNKNOWN_TYPE), typeSize(0), arraySize(0), sizeTillEnd(0), readWriteMode(
|
||||
setReadWriteMode) {
|
||||
memset(value, 0, sizeof(value));
|
||||
if (data_set != NULL) {
|
||||
data_set->registerVariable(this);
|
||||
}
|
||||
}
|
||||
|
||||
PoolRawAccess::~PoolRawAccess() {
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::read() {
|
||||
PoolEntryIF *read_out = ::dataPool.getRawData(dataPoolId);
|
||||
if (read_out != NULL) {
|
||||
valid = read_out->getValid();
|
||||
if (read_out->getSize() > arrayEntry) {
|
||||
arraySize = read_out->getSize();
|
||||
typeSize = read_out->getByteSize() / read_out->getSize();
|
||||
type = read_out->getType();
|
||||
if (typeSize <= sizeof(value)) {
|
||||
uint16_t arrayPosition = arrayEntry * typeSize;
|
||||
sizeTillEnd = read_out->getByteSize() - arrayPosition;
|
||||
uint8_t *ptr =
|
||||
&((uint8_t*) read_out->getRawData())[arrayPosition];
|
||||
memcpy(value, ptr, typeSize);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
//Error value type too large.
|
||||
}
|
||||
} else {
|
||||
//Error index requested too large
|
||||
}
|
||||
} else {
|
||||
//Error entry does not exist.
|
||||
}
|
||||
sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex
|
||||
<< dataPoolId << std::dec << " failed." << std::endl;
|
||||
valid = INVALID;
|
||||
typeSize = 0;
|
||||
sizeTillEnd = 0;
|
||||
memset(value, 0, sizeof(value));
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::commit() {
|
||||
PoolEntryIF *write_back = ::dataPool.getRawData(dataPoolId);
|
||||
if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
|
||||
write_back->setValid(valid);
|
||||
uint8_t array_position = arrayEntry * typeSize;
|
||||
uint8_t *ptr = &((uint8_t*) write_back->getRawData())[array_position];
|
||||
memcpy(ptr, value, typeSize);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* PoolRawAccess::getEntry() {
|
||||
return value;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t *buffer,
|
||||
size_t *writtenBytes, size_t maxSize) {
|
||||
uint8_t *data_ptr = getEntry();
|
||||
// debug << "PoolRawAccess::getEntry: Array position: " << index * size_of_type << " Size of T: " << (int)size_of_type << " ByteSize: " << byte_size << " Position: " << *size << std::endl;
|
||||
if (typeSize == 0) {
|
||||
return DATA_POOL_ACCESS_FAILED;
|
||||
}
|
||||
if (typeSize > maxSize) {
|
||||
return INCORRECT_SIZE;
|
||||
}
|
||||
EndianConverter::convertBigEndian(buffer, data_ptr, typeSize);
|
||||
*writtenBytes = typeSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
Type PoolRawAccess::getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
size_t PoolRawAccess::getSizeOfType() {
|
||||
return typeSize;
|
||||
}
|
||||
|
||||
size_t PoolRawAccess::getArraySize() {
|
||||
return arraySize;
|
||||
}
|
||||
|
||||
uint32_t PoolRawAccess::getDataPoolId() const {
|
||||
return dataPoolId;
|
||||
}
|
||||
|
||||
PoolVariableIF::ReadWriteMode_t PoolRawAccess::getReadWriteMode() const {
|
||||
return readWriteMode;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t *buffer,
|
||||
size_t setSize) {
|
||||
if (typeSize == setSize) {
|
||||
EndianConverter::convertBigEndian(value, buffer, typeSize);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
sif::error
|
||||
<< "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: Internal"
|
||||
<< (uint32_t) typeSize << ", Requested: " << setSize
|
||||
<< std::endl;
|
||||
return INCORRECT_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
bool PoolRawAccess::isValid() const {
|
||||
if (valid != INVALID)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void PoolRawAccess::setValid(uint8_t valid) {
|
||||
this->valid = valid;
|
||||
}
|
||||
|
||||
size_t PoolRawAccess::getSizeTillEnd() const {
|
||||
return sizeTillEnd;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const {
|
||||
if (typeSize + *size <= maxSize) {
|
||||
switch (streamEndianness) {
|
||||
case (Endianness::BIG):
|
||||
EndianConverter::convertBigEndian(*buffer, value, typeSize);
|
||||
break;
|
||||
case (Endianness::LITTLE):
|
||||
EndianConverter::convertLittleEndian(*buffer, value, typeSize);
|
||||
break;
|
||||
default:
|
||||
case (Endianness::MACHINE):
|
||||
memcpy(*buffer, value, typeSize);
|
||||
break;
|
||||
}
|
||||
*size += typeSize;
|
||||
(*buffer) += typeSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
}
|
||||
|
||||
size_t PoolRawAccess::getSerializedSize() const {
|
||||
return typeSize;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
|
||||
if (*size >= typeSize) {
|
||||
switch (streamEndianness) {
|
||||
case (Endianness::BIG):
|
||||
EndianConverter::convertBigEndian(value, *buffer, typeSize);
|
||||
break;
|
||||
case (Endianness::LITTLE):
|
||||
EndianConverter::convertLittleEndian(value, *buffer, typeSize);
|
||||
break;
|
||||
default:
|
||||
case (Endianness::MACHINE):
|
||||
memcpy(value, *buffer, typeSize);
|
||||
break;
|
||||
}
|
||||
*size -= typeSize;
|
||||
*buffer += typeSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
}
|
152
datapool/PoolRawAccess.h
Normal file
152
datapool/PoolRawAccess.h
Normal file
@ -0,0 +1,152 @@
|
||||
#ifndef POOLRAWACCESS_H_
|
||||
#define POOLRAWACCESS_H_
|
||||
|
||||
#include "DataSetIF.h"
|
||||
#include "PoolVariableIF.h"
|
||||
|
||||
/**
|
||||
* This class allows accessing Data Pool variables as raw bytes.
|
||||
* This is necessary to have an access method for HK data, as the PID's alone do not
|
||||
* provide a type information.
|
||||
* \ingroup data_pool
|
||||
*/
|
||||
class PoolRawAccess: public PoolVariableIF {
|
||||
private:
|
||||
/**
|
||||
* \brief To access the correct data pool entry on read and commit calls, the data pool id
|
||||
* is stored.
|
||||
*/
|
||||
uint32_t dataPoolId;
|
||||
/**
|
||||
* \brief The array entry that is fetched from the data pool.
|
||||
*/
|
||||
uint8_t arrayEntry;
|
||||
/**
|
||||
* \brief The valid information as it was stored in the data pool is copied to this attribute.
|
||||
*/
|
||||
uint8_t valid;
|
||||
/**
|
||||
* \brief This value contains the type of the data pool entry.
|
||||
*/
|
||||
Type type;
|
||||
/**
|
||||
* \brief This value contains the size of the data pool entry in bytes.
|
||||
*/
|
||||
size_t typeSize;
|
||||
/**
|
||||
* The size of the DP array (single values return 1)
|
||||
*/
|
||||
size_t arraySize;
|
||||
/**
|
||||
* The size (in bytes) from the selected entry till the end of this DataPool variable.
|
||||
*/
|
||||
size_t sizeTillEnd;
|
||||
/**
|
||||
* \brief The information whether the class is read-write or read-only is stored here.
|
||||
*/
|
||||
ReadWriteMode_t readWriteMode;
|
||||
static const uint8_t RAW_MAX_SIZE = sizeof(double);
|
||||
protected:
|
||||
/**
|
||||
* \brief This is a call to read the value from the global data pool.
|
||||
* \details When executed, this operation tries to fetch the pool entry with matching
|
||||
* data pool id from the global data pool and copies the value and the valid
|
||||
* information to its local attributes. In case of a failure (wrong type or
|
||||
* pool id not found), the variable is set to zero and invalid.
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
*/
|
||||
ReturnValue_t read();
|
||||
/**
|
||||
* \brief The commit call writes back the variable's value to the data pool.
|
||||
* \details It checks type and size, as well as if the variable is writable. If so,
|
||||
* the value is copied and the valid flag is automatically set to "valid".
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
*
|
||||
*/
|
||||
ReturnValue_t commit();
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::POOL_RAW_ACCESS_CLASS;
|
||||
static const ReturnValue_t INCORRECT_SIZE = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02);
|
||||
uint8_t value[RAW_MAX_SIZE];
|
||||
PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry,
|
||||
DataSetIF *data_set, ReadWriteMode_t setReadWriteMode =
|
||||
PoolVariableIF::VAR_READ);
|
||||
/**
|
||||
* \brief The classes destructor is empty. If commit() was not called, the local value is
|
||||
* discarded and not written back to the data pool.
|
||||
*/
|
||||
~PoolRawAccess();
|
||||
/**
|
||||
* \brief This operation returns a pointer to the entry fetched.
|
||||
* \details This means, it does not return a pointer to byte "index", but to the start byte of
|
||||
* array entry "index". Example: If the original data pool array consists of an double
|
||||
* array of size four, getEntry(1) returns &(this->value[8]).
|
||||
*/
|
||||
uint8_t* getEntry();
|
||||
/**
|
||||
* \brief This operation returns the fetched entry from the data pool and
|
||||
* flips the bytes, if necessary.
|
||||
* \details It makes use of the getEntry call of this function, but additionally flips the
|
||||
* bytes to big endian, which is the default for external communication (as House-
|
||||
* keeping telemetry). To achieve this, the data is copied directly to the passed
|
||||
* buffer, if it fits in the given maxSize.
|
||||
* \param buffer A pointer to a buffer to write to
|
||||
* \param writtenBytes The number of bytes written is returned with this value.
|
||||
* \param maxSize The maximum size that the function may write to buffer.
|
||||
* \return - \c RETURN_OK if entry could be acquired
|
||||
* - \c RETURN_FAILED else.
|
||||
*/
|
||||
ReturnValue_t getEntryEndianSafe(uint8_t *buffer, size_t *size,
|
||||
size_t maxSize);
|
||||
/**
|
||||
* With this method, the content can be set from a big endian buffer safely.
|
||||
* @param buffer Pointer to the data to set
|
||||
* @param size Size of the data to write. Must fit this->size.
|
||||
* @return - \c RETURN_OK on success
|
||||
* - \c RETURN_FAILED on failure
|
||||
*/
|
||||
ReturnValue_t setEntryFromBigEndian(const uint8_t *buffer,
|
||||
size_t setSize);
|
||||
/**
|
||||
* \brief This operation returns the type of the entry currently stored.
|
||||
*/
|
||||
Type getType();
|
||||
/**
|
||||
* \brief This operation returns the size of the entry currently stored.
|
||||
*/
|
||||
size_t getSizeOfType();
|
||||
/**
|
||||
*
|
||||
* @return the size of the datapool array
|
||||
*/
|
||||
size_t getArraySize();
|
||||
/**
|
||||
* \brief This operation returns the data pool id of the variable.
|
||||
*/
|
||||
uint32_t getDataPoolId() const;
|
||||
/**
|
||||
* This method returns if the variable is read-write or read-only.
|
||||
*/
|
||||
ReadWriteMode_t getReadWriteMode() const;
|
||||
/**
|
||||
* \brief With this call, the valid information of the variable is returned.
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
void setValid(uint8_t valid);
|
||||
/**
|
||||
* Getter for the remaining size.
|
||||
*/
|
||||
size_t getSizeTillEnd() const;
|
||||
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||
Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
};
|
||||
|
||||
#endif /* POOLRAWACCESS_H_ */
|
@ -1,188 +0,0 @@
|
||||
/**
|
||||
* @file PoolRawAccessHelper.cpp
|
||||
*
|
||||
* @date 22.12.2019
|
||||
* @author R. Mueller
|
||||
*/
|
||||
|
||||
#include <framework/datapool/PoolRawAccessHelper.h>
|
||||
#include <framework/datapoolglob/GlobalDataSet.h>
|
||||
#include <framework/serialize/SerializeAdapter.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
PoolRawAccessHelper::PoolRawAccessHelper(uint32_t * poolIdBuffer_,
|
||||
uint8_t numberOfParameters_):
|
||||
poolIdBuffer(reinterpret_cast<uint8_t * >(poolIdBuffer_)),
|
||||
numberOfParameters(numberOfParameters_), validBufferIndex(0),
|
||||
validBufferIndexBit(1) {
|
||||
}
|
||||
|
||||
PoolRawAccessHelper::~PoolRawAccessHelper() {
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccessHelper::serialize(uint8_t **buffer, size_t *size,
|
||||
const size_t max_size, SerializeIF::Endianness streamEndianness) {
|
||||
SerializationArgs serializationArgs = {buffer, size, max_size,
|
||||
streamEndianness};
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
size_t remainingParametersSize = numberOfParameters * 4;
|
||||
for(uint8_t count=0; count < numberOfParameters; count++) {
|
||||
result = serializeCurrentPoolEntryIntoBuffer(serializationArgs,
|
||||
&remainingParametersSize, false);
|
||||
if(result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if(remainingParametersSize != 0) {
|
||||
sif::debug << "PoolRawAccessHelper: "
|
||||
"Remaining parameters size not 0 !" << std::endl;
|
||||
result = RETURN_FAILED;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccessHelper::serializeWithValidityMask(uint8_t ** buffer,
|
||||
size_t * size, const size_t max_size,
|
||||
SerializeIF::Endianness streamEndianness) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
SerializationArgs argStruct = {buffer, size, max_size, streamEndianness};
|
||||
size_t remainingParametersSize = numberOfParameters * 4;
|
||||
uint8_t validityMaskSize = ceil((float)numberOfParameters/8.0);
|
||||
uint8_t validityMask[validityMaskSize];
|
||||
memset(validityMask,0, validityMaskSize);
|
||||
for(uint8_t count = 0; count < numberOfParameters; count++) {
|
||||
result = serializeCurrentPoolEntryIntoBuffer(argStruct,
|
||||
&remainingParametersSize,true,validityMask);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if(remainingParametersSize != 0) {
|
||||
sif::debug << "PoolRawAccessHelper: Remaining "
|
||||
"parameters size not 0 !" << std::endl;
|
||||
result = RETURN_FAILED;
|
||||
}
|
||||
|
||||
memcpy(*argStruct.buffer, validityMask, validityMaskSize);
|
||||
*size += validityMaskSize;
|
||||
validBufferIndex = 1;
|
||||
validBufferIndexBit = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccessHelper::serializeCurrentPoolEntryIntoBuffer(
|
||||
SerializationArgs argStruct, size_t * remainingParameters,
|
||||
bool withValidMask, uint8_t * validityMask) {
|
||||
uint32_t currentPoolId;
|
||||
// Deserialize current pool ID from pool ID buffer
|
||||
ReturnValue_t result = SerializeAdapter::deSerialize(¤tPoolId,
|
||||
&poolIdBuffer,remainingParameters, SerializeIF::Endianness::MACHINE);
|
||||
if(result != RETURN_OK) {
|
||||
sif::debug << std::hex << "PoolRawAccessHelper: Error deSeralizing "
|
||||
"pool IDs" << std::dec << std::endl;
|
||||
return result;
|
||||
}
|
||||
result = handlePoolEntrySerialization(currentPoolId, argStruct,
|
||||
withValidMask, validityMask);
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccessHelper::handlePoolEntrySerialization(
|
||||
uint32_t currentPoolId,SerializationArgs argStruct, bool withValidMask,
|
||||
uint8_t * validityMask) {
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
uint8_t arrayPosition = 0;
|
||||
uint8_t counter = 0;
|
||||
bool poolEntrySerialized = false;
|
||||
//debug << "Pool Raw Access Helper: Handling Pool ID: "
|
||||
// << std::hex << currentPoolId << std::endl;
|
||||
while(not poolEntrySerialized) {
|
||||
|
||||
if(counter > GlobDataSet::DATA_SET_MAX_SIZE) {
|
||||
sif::error << "PoolRawAccessHelper: Config error, "
|
||||
"max. number of possible data set variables exceeded"
|
||||
<< std::endl;
|
||||
return result;
|
||||
}
|
||||
counter ++;
|
||||
|
||||
GlobDataSet currentDataSet;
|
||||
//debug << "Current array position: " << (int)arrayPosition << std::endl;
|
||||
PoolRawAccess currentPoolRawAccess(currentPoolId, arrayPosition,
|
||||
¤tDataSet, PoolVariableIF::VAR_READ);
|
||||
|
||||
result = currentDataSet.read();
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << std::hex << "PoolRawAccessHelper: Error reading raw "
|
||||
"dataset with returncode 0x" << result << std::dec << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
result = checkRemainingSize(¤tPoolRawAccess, &poolEntrySerialized,
|
||||
&arrayPosition);
|
||||
if(result != RETURN_OK) {
|
||||
sif::error << "Pool Raw Access Helper: Configuration Error at pool ID "
|
||||
<< std::hex << currentPoolId
|
||||
<< ". Size till end smaller than 0" << std::dec << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
// set valid mask bit if necessary
|
||||
if(withValidMask) {
|
||||
if(currentPoolRawAccess.isValid()) {
|
||||
handleMaskModification(validityMask);
|
||||
}
|
||||
validBufferIndexBit ++;
|
||||
}
|
||||
|
||||
result = currentDataSet.serialize(argStruct.buffer, argStruct.size,
|
||||
argStruct.max_size, argStruct.streamEndianness);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "Pool Raw Access Helper: Error serializing pool data with "
|
||||
"ID 0x" << std::hex << currentPoolId << " into send buffer "
|
||||
"with return code " << result << std::dec << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccessHelper::checkRemainingSize(PoolRawAccess*
|
||||
currentPoolRawAccess, bool * isSerialized, uint8_t * arrayPosition) {
|
||||
int8_t remainingSize = currentPoolRawAccess->getSizeTillEnd() -
|
||||
currentPoolRawAccess->getSizeOfType();
|
||||
if(remainingSize == 0) {
|
||||
*isSerialized = true;
|
||||
}
|
||||
else if(remainingSize > 0) {
|
||||
*arrayPosition += 1;
|
||||
}
|
||||
else {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PoolRawAccessHelper::handleMaskModification(uint8_t * validityMask) {
|
||||
validityMask[validBufferIndex] =
|
||||
bitSetter(validityMask[validBufferIndex], validBufferIndexBit, true);
|
||||
if(validBufferIndexBit == 8) {
|
||||
validBufferIndex ++;
|
||||
validBufferIndexBit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t PoolRawAccessHelper::bitSetter(uint8_t byte, uint8_t position,
|
||||
bool value) {
|
||||
if(position < 1 or position > 8) {
|
||||
sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl;
|
||||
return byte;
|
||||
}
|
||||
uint8_t shiftNumber = position + (6 - 2 * (position - 1));
|
||||
byte |= 1UL << shiftNumber;
|
||||
return byte;
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
/**
|
||||
* @file PoolRawAccessHelper.h
|
||||
*
|
||||
* @date 22.12.2019
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_
|
||||
#define FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_
|
||||
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/datapoolglob/GlobalDataSet.h>
|
||||
#include <framework/datapoolglob/PoolRawAccess.h>
|
||||
|
||||
/**
|
||||
* @brief This helper function simplifies accessing data pool entries
|
||||
* via PoolRawAccess
|
||||
* @details Can be used for a Housekeeping Service
|
||||
* like ECSS PUS Service 3 if the type of the datapool entries is unknown.
|
||||
* The provided dataset can be serialized into a provided buffer automatically by
|
||||
* providing a buffer of pool IDs
|
||||
* @ingroup data_pool
|
||||
*/
|
||||
class PoolRawAccessHelper: public HasReturnvaluesIF {
|
||||
public:
|
||||
/**
|
||||
* Call this constructor if a dataset needs to be serialized via
|
||||
* Pool Raw Access
|
||||
* @param dataSet_ This dataset will be used to perform thread-safe reading
|
||||
* @param poolIdBuffer_ A buffer of uint32_t pool IDs
|
||||
* @param numberOfParameters_ The number of parameters / pool IDs
|
||||
*/
|
||||
PoolRawAccessHelper(uint32_t * poolIdBuffer_, uint8_t numberOfParameters_);
|
||||
virtual ~PoolRawAccessHelper();
|
||||
|
||||
/**
|
||||
* Serialize the datapool entries derived from the pool ID buffer
|
||||
* directly into a provided buffer
|
||||
* @param [out] buffer
|
||||
* @param [out] size Size of the serialized buffer
|
||||
* @param max_size
|
||||
* @param bigEndian
|
||||
* @return @c RETURN_OK On success
|
||||
* @c RETURN_FAILED on failure
|
||||
*/
|
||||
ReturnValue_t serialize(uint8_t ** buffer, size_t * size,
|
||||
const size_t max_size, SerializeIF::Endianness streamEndianness);
|
||||
|
||||
/**
|
||||
* Serializes data pool entries into provided buffer with the validity mask buffer
|
||||
* at the end of the buffer. Every bit of the validity mask denotes
|
||||
* the validity of a corresponding data pool entry from left to right.
|
||||
* @param [out] buffer
|
||||
* @param [out] size Size of the serialized buffer plus size
|
||||
* of the validity mask
|
||||
* @return @c RETURN_OK On success
|
||||
* @c RETURN_FAILED on failure
|
||||
*/
|
||||
ReturnValue_t serializeWithValidityMask(uint8_t ** buffer, size_t * size,
|
||||
const size_t max_size, SerializeIF::Endianness streamEndianness);
|
||||
|
||||
|
||||
private:
|
||||
// DataSet * dataSet;
|
||||
const uint8_t * poolIdBuffer;
|
||||
uint8_t numberOfParameters;
|
||||
|
||||
uint8_t validBufferIndex;
|
||||
uint8_t validBufferIndexBit;
|
||||
|
||||
struct SerializationArgs {
|
||||
uint8_t ** buffer;
|
||||
size_t * size;
|
||||
const size_t max_size;
|
||||
SerializeIF::Endianness streamEndianness;
|
||||
};
|
||||
/**
|
||||
* Helper function to serialize single pool entries
|
||||
* @param pPoolIdBuffer
|
||||
* @param buffer
|
||||
* @param remainingParameters
|
||||
* @param hkDataSize
|
||||
* @param max_size
|
||||
* @param bigEndian
|
||||
* @param withValidMask Can be set optionally to set a
|
||||
* provided validity mask
|
||||
* @param validityMask Can be supplied and will be set if
|
||||
* @c withValidMask is set to true
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t serializeCurrentPoolEntryIntoBuffer(
|
||||
SerializationArgs argStruct, size_t * remainingParameters,
|
||||
bool withValidMask = false, uint8_t * validityMask = nullptr);
|
||||
|
||||
ReturnValue_t handlePoolEntrySerialization(uint32_t currentPoolId,
|
||||
SerializationArgs argStruct, bool withValidMask = false,
|
||||
uint8_t * validityMask = nullptr);
|
||||
|
||||
ReturnValue_t checkRemainingSize(PoolRawAccess * currentPoolRawAccess,
|
||||
bool * isSerialized, uint8_t * arrayPosition);
|
||||
void handleMaskModification(uint8_t * validityMask);
|
||||
/**
|
||||
* Sets specific bit of a byte
|
||||
* @param byte
|
||||
* @param position Position of byte to set from 1 to 8
|
||||
* @param value Binary value to set
|
||||
* @return
|
||||
*/
|
||||
uint8_t bitSetter(uint8_t byte, uint8_t position, bool value);
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_DATAPOOL_POOLRAWACCESSHELPER_H_ */
|
@ -1,12 +1,12 @@
|
||||
#ifndef POOLVARLIST_H_
|
||||
#define POOLVARLIST_H_
|
||||
|
||||
#include <framework/datapool/PoolVariableIF.h>
|
||||
#include <framework/datapoolglob/GlobalPoolVariable.h>
|
||||
#include "PoolVariable.h"
|
||||
#include "PoolVariableIF.h"
|
||||
template <class T, uint8_t n_var>
|
||||
class PoolVarList {
|
||||
private:
|
||||
GlobPoolVar<T> variables[n_var];
|
||||
PoolVariable<T> variables[n_var];
|
||||
public:
|
||||
PoolVarList( const uint32_t set_id[n_var], DataSetIF* dataSet, PoolVariableIF::ReadWriteMode_t setReadWriteMode ) {
|
||||
//I really should have a look at the new init list c++ syntax.
|
||||
@ -20,7 +20,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
GlobPoolVar<T> &operator [](int i) { return variables[i]; }
|
||||
PoolVariable<T> &operator [](int i) { return variables[i]; }
|
||||
};
|
||||
|
||||
|
||||
|
295
datapool/PoolVariable.h
Normal file
295
datapool/PoolVariable.h
Normal file
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* \file PoolVariable.h
|
||||
*
|
||||
* \brief This file contains the PoolVariable class, which locally represents a non-array data pool variable.
|
||||
*
|
||||
* \date 10/17/2012
|
||||
*
|
||||
* \author Bastian Baetz
|
||||
*/
|
||||
|
||||
#ifndef POOLVARIABLE_H_
|
||||
#define POOLVARIABLE_H_
|
||||
|
||||
#include "DataSetIF.h"
|
||||
#include "PoolEntry.h"
|
||||
#include "PoolVariableIF.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
template<typename T, uint8_t n_var> class PoolVarList;
|
||||
|
||||
/**
|
||||
* \brief This is the access class for non-array data pool entries.
|
||||
*
|
||||
* \details To ensure safe usage of the data pool, operation is not done directly on the data pool
|
||||
* entries, but on local copies. This class provides simple type-safe access to single
|
||||
* data pool entries (i.e. entries with length = 1).
|
||||
* The class can be instantiated as read-write and read only.
|
||||
* It provides a commit-and-roll-back semantic, which means that the variable's value in
|
||||
* the data pool is not changed until the commit call is executed.
|
||||
* \tparam T The template parameter sets the type of the variable. Currently, all plain data types
|
||||
* are supported, but in principle any type is possible.
|
||||
* \ingroup data_pool
|
||||
*/
|
||||
template<typename T>
|
||||
class PoolVariable: public PoolVariableIF {
|
||||
template<typename U, uint8_t n_var> friend class PoolVarList;
|
||||
protected:
|
||||
/**
|
||||
* \brief To access the correct data pool entry on read and commit calls, the data pool id
|
||||
* is stored.
|
||||
*/
|
||||
uint32_t dataPoolId;
|
||||
/**
|
||||
* \brief The valid information as it was stored in the data pool is copied to this attribute.
|
||||
*/
|
||||
uint8_t valid;
|
||||
/**
|
||||
* \brief The information whether the class is read-write or read-only is stored here.
|
||||
*/
|
||||
ReadWriteMode_t readWriteMode;
|
||||
/**
|
||||
* \brief This is a call to read the value from the global data pool.
|
||||
* \details When executed, this operation tries to fetch the pool entry with matching
|
||||
* data pool id from the global data pool and copies the value and the valid
|
||||
* information to its local attributes. In case of a failure (wrong type or
|
||||
* pool id not found), the variable is set to zero and invalid.
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
*/
|
||||
ReturnValue_t read() {
|
||||
PoolEntry<T> *read_out = ::dataPool.getData < T > (dataPoolId, 1);
|
||||
if (read_out != NULL) {
|
||||
valid = read_out->valid;
|
||||
value = *(read_out->address);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
value = 0;
|
||||
valid = false;
|
||||
sif::error << "PoolVariable: read of DP Variable 0x" << std::hex
|
||||
<< dataPoolId << std::dec << " failed." << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief The commit call writes back the variable's value to the data pool.
|
||||
* \details It checks type and size, as well as if the variable is writable. If so,
|
||||
* the value is copied and the valid flag is automatically set to "valid".
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
*
|
||||
*/
|
||||
ReturnValue_t commit() {
|
||||
PoolEntry<T> *write_back = ::dataPool.getData < T > (dataPoolId, 1);
|
||||
if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
|
||||
write_back->valid = valid;
|
||||
*(write_back->address) = value;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Empty ctor for List initialization
|
||||
*/
|
||||
PoolVariable() :
|
||||
dataPoolId(PoolVariableIF::NO_PARAMETER), valid(
|
||||
PoolVariableIF::INVALID), readWriteMode(VAR_READ), value(0) {
|
||||
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* \brief This is the local copy of the data pool entry.
|
||||
* \details The user can work on this attribute
|
||||
* just like he would on a simple local variable.
|
||||
*/
|
||||
T value;
|
||||
/**
|
||||
* \brief In the constructor, the variable can register itself in a DataSet (if not NULL is
|
||||
* passed).
|
||||
* \details It DOES NOT fetch the current value from the data pool, but sets the value
|
||||
* attribute to default (0). The value is fetched within the read() operation.
|
||||
* \param set_id This is the id in the global data pool this instance of the access class
|
||||
* corresponds to.
|
||||
* \param dataSet The data set in which the variable shall register itself. If NULL,
|
||||
* the variable is not registered.
|
||||
* \param setWritable If this flag is set to true, changes in the value attribute can be
|
||||
* written back to the data pool, otherwise not.
|
||||
*/
|
||||
PoolVariable(uint32_t set_id, DataSetIF *dataSet,
|
||||
ReadWriteMode_t setReadWriteMode) :
|
||||
dataPoolId(set_id), valid(PoolVariableIF::INVALID), readWriteMode(
|
||||
setReadWriteMode), value(0) {
|
||||
if (dataSet != NULL) {
|
||||
dataSet->registerVariable(this);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copy ctor to copy classes containing Pool Variables.
|
||||
*/
|
||||
PoolVariable(const PoolVariable &rhs) :
|
||||
dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode(
|
||||
rhs.readWriteMode), value(rhs.value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief The classes destructor is empty.
|
||||
* \details If commit() was not called, the local value is
|
||||
* discarded and not written back to the data pool.
|
||||
*/
|
||||
~PoolVariable() {
|
||||
|
||||
}
|
||||
/**
|
||||
* \brief This operation returns the data pool id of the variable.
|
||||
*/
|
||||
uint32_t getDataPoolId() const {
|
||||
return dataPoolId;
|
||||
}
|
||||
/**
|
||||
* This operation sets the data pool id of the variable.
|
||||
* The method is necessary to set id's of data pool member variables with bad initialization.
|
||||
*/
|
||||
void setDataPoolId(uint32_t poolId) {
|
||||
dataPoolId = poolId;
|
||||
}
|
||||
/**
|
||||
* This method returns if the variable is write-only, read-write or read-only.
|
||||
*/
|
||||
ReadWriteMode_t getReadWriteMode() const {
|
||||
return readWriteMode;
|
||||
}
|
||||
/**
|
||||
* \brief With this call, the valid information of the variable is returned.
|
||||
*/
|
||||
bool isValid() const {
|
||||
if (valid)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t getValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
void setValid(uint8_t valid) {
|
||||
this->valid = valid;
|
||||
}
|
||||
|
||||
operator T() {
|
||||
return value;
|
||||
}
|
||||
|
||||
operator T() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
PoolVariable<T>& operator=(T newValue) {
|
||||
value = newValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PoolVariable<T>& operator=(PoolVariable<T> newPoolVariable) {
|
||||
value = newPoolVariable.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const override {
|
||||
return SerializeAdapter::serialize<T>(&value, buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const override {
|
||||
return SerializeAdapter::getSerializedSize(&value);
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override {
|
||||
return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
|
||||
}
|
||||
};
|
||||
|
||||
typedef PoolVariable<uint8_t> db_uint8_t;
|
||||
typedef PoolVariable<uint16_t> db_uint16_t;
|
||||
typedef PoolVariable<uint32_t> db_uint32_t;
|
||||
typedef PoolVariable<int8_t> db_int8_t;
|
||||
typedef PoolVariable<int16_t> db_int16_t;
|
||||
typedef PoolVariable<int32_t> db_int32_t;
|
||||
typedef PoolVariable<uint8_t> db_bool_t;
|
||||
typedef PoolVariable<float> db_float_t;
|
||||
typedef PoolVariable<double> db_double_t;
|
||||
//Alternative (but I thing this is not as useful: code duplication, differences too small):
|
||||
|
||||
//template <typename T>
|
||||
//class PoolReader : public PoolVariableIF {
|
||||
//private:
|
||||
// uint32_t parameter_id;
|
||||
// uint8_t valid;
|
||||
//public:
|
||||
// T value;
|
||||
// PoolReader( uint32_t set_id, DataSetIF* set ) : parameter_id(set_id), valid(false), value(0) {
|
||||
// set->registerVariable( this );
|
||||
// }
|
||||
//
|
||||
// ~PoolReader() {};
|
||||
//
|
||||
// uint8_t commit() {
|
||||
// return HasReturnvaluesIF::RETURN_OK;
|
||||
// }
|
||||
//
|
||||
// uint8_t read() {
|
||||
// PoolEntry<T>* read_out = ::dataPool.getData<T>( parameter_id, 1 );
|
||||
// if ( read_out != NULL ) {
|
||||
// valid = read_out->valid;
|
||||
// value = *(read_out->address);
|
||||
// return HasReturnvaluesIF::RETURN_OK;
|
||||
// } else {
|
||||
// value = 0;
|
||||
// valid = false;
|
||||
// return CHECKOUT_FAILED;
|
||||
// }
|
||||
// }
|
||||
// uint32_t getParameterId() { return parameter_id; }
|
||||
// bool isWritable() { return false; };
|
||||
// bool isValid() { if (valid) return true; else return false; }
|
||||
//};
|
||||
//
|
||||
//template <typename T>
|
||||
//class PoolWriter : public PoolVariableIF {
|
||||
//private:
|
||||
// uint32_t parameter_id;
|
||||
//public:
|
||||
// T value;
|
||||
// PoolWriter( uint32_t set_id, DataSetIF* set ) : parameter_id(set_id), value(0) {
|
||||
// set->registerVariable( this );
|
||||
// }
|
||||
//
|
||||
// ~PoolWriter() {};
|
||||
//
|
||||
// uint8_t commit() {
|
||||
// PoolEntry<T>* write_back = ::dataPool.getData<T>( parameter_id, 1 );
|
||||
// if ( write_back != NULL ) {
|
||||
// write_back->valid = true;
|
||||
// *(write_back->address) = value;
|
||||
// return HasReturnvaluesIF::RETURN_OK;
|
||||
// } else {
|
||||
// return CHECKOUT_FAILED;
|
||||
// }
|
||||
// }
|
||||
// uint8_t read() {
|
||||
// PoolEntry<T>* read_out = ::dataPool.getData<T>( parameter_id, 1 );
|
||||
// if ( read_out != NULL ) {
|
||||
// value = *(read_out->address);
|
||||
// return HasReturnvaluesIF::RETURN_OK;
|
||||
// } else {
|
||||
// value = 0;
|
||||
// return CHECKOUT_FAILED;
|
||||
// }
|
||||
// }
|
||||
// uint32_t getParameterId() { return parameter_id; }
|
||||
// bool isWritable() { return true; };
|
||||
// bool isValid() { return false; }
|
||||
//};
|
||||
|
||||
#endif /* POOLVARIABLE_H_ */
|
@ -1,99 +1,71 @@
|
||||
#ifndef FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_
|
||||
#define FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_
|
||||
/*
|
||||
* \file PoolVariableIF.h
|
||||
*
|
||||
* \brief This file contains the interface definition for pool variables.
|
||||
*
|
||||
* \date 10/17/2012
|
||||
*
|
||||
* \author Bastian Baetz
|
||||
*/
|
||||
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/serialize/SerializeIF.h>
|
||||
#ifndef POOLVARIABLEIF_H_
|
||||
#define POOLVARIABLEIF_H_
|
||||
|
||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
||||
#include "../serialize/SerializeIF.h"
|
||||
|
||||
/**
|
||||
* @brief This interface is used to control data pool
|
||||
* variable representations.
|
||||
* @details
|
||||
* To securely handle data pool variables, all pool entries are locally
|
||||
* managed by data pool variable access classes, which are called pool
|
||||
* variables. To ensure a common state of a set of variables needed in a
|
||||
* function, these local pool variables again are managed by other classes,
|
||||
* like the DataSet classes. This interface provides unified access to
|
||||
* local pool variables for such manager classes.
|
||||
* @author Bastian Baetz
|
||||
* @ingroup data_pool
|
||||
* \brief This interface is used to control local data pool variable representations.
|
||||
*
|
||||
* \details To securely handle data pool variables, all pool entries are locally managed by
|
||||
* data pool variable access classes, which are called pool variables. To ensure a
|
||||
* common state of a set of variables needed in a function, these local pool variables
|
||||
* again are managed by other classes, e.g. the DataSet. This interface provides unified
|
||||
* access to local pool variables for such manager classes.
|
||||
* \ingroup data_pool
|
||||
*/
|
||||
class PoolVariableIF : public SerializeIF {
|
||||
friend class DataSetBase;
|
||||
friend class GlobDataSet;
|
||||
friend class LocalDataSet;
|
||||
friend class DataSet;
|
||||
protected:
|
||||
/**
|
||||
* \brief The commit call shall write back a newly calculated local value to the data pool.
|
||||
*/
|
||||
virtual ReturnValue_t commit() = 0;
|
||||
/**
|
||||
* \brief The read call shall read the value of this parameter from the data pool and store
|
||||
* the content locally.
|
||||
*/
|
||||
virtual ReturnValue_t read() = 0;
|
||||
public:
|
||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::POOL_VARIABLE_IF;
|
||||
static constexpr ReturnValue_t INVALID_READ_WRITE_MODE = MAKE_RETURN_CODE(0xA0);
|
||||
|
||||
static constexpr bool VALID = 1;
|
||||
static constexpr bool INVALID = 0;
|
||||
static constexpr uint32_t NO_PARAMETER = 0xffffffff;
|
||||
|
||||
static const uint8_t VALID = 1;
|
||||
static const uint8_t INVALID = 0;
|
||||
static const uint32_t NO_PARAMETER = 0;
|
||||
enum ReadWriteMode_t {
|
||||
VAR_READ, VAR_WRITE, VAR_READ_WRITE
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This is an empty virtual destructor,
|
||||
* as it is proposed for C++ interfaces.
|
||||
* \brief This is an empty virtual destructor, as it is proposed for C++ interfaces.
|
||||
*/
|
||||
virtual ~PoolVariableIF() {}
|
||||
virtual ~PoolVariableIF() {
|
||||
}
|
||||
/**
|
||||
* @brief This method returns if the variable is write-only,
|
||||
* read-write or read-only.
|
||||
* \brief This method returns if the variable is write-only, read-write or read-only.
|
||||
*/
|
||||
virtual ReadWriteMode_t getReadWriteMode() const = 0;
|
||||
/**
|
||||
* @brief This operation shall return the data pool id of the variable.
|
||||
* \brief This operation shall return the data pool id of the variable.
|
||||
*/
|
||||
virtual uint32_t getDataPoolId() const = 0;
|
||||
/**
|
||||
* @brief With this call, the valid information of the
|
||||
* variable is returned.
|
||||
* \brief With this call, the valid information of the variable is returned.
|
||||
*/
|
||||
virtual bool isValid() const = 0;
|
||||
/**
|
||||
* @brief With this call, the valid information of the variable is set.
|
||||
* \brief With this call, the valid information of the variable is set.
|
||||
*/
|
||||
virtual void setValid(bool validity) = 0;
|
||||
virtual void setValid(uint8_t validity) = 0;
|
||||
|
||||
/**
|
||||
* @brief The commit call shall write back a newly calculated local
|
||||
* value to the data pool.
|
||||
* @details
|
||||
* It is assumed that these calls are implemented in a thread-safe manner!
|
||||
*/
|
||||
virtual ReturnValue_t commit(uint32_t lockTimeout) = 0;
|
||||
/**
|
||||
* @brief The read call shall read the value of this parameter from
|
||||
* the data pool and store the content locally.
|
||||
* @details
|
||||
* It is assumbed that these calls are implemented in a thread-safe manner!
|
||||
*/
|
||||
virtual ReturnValue_t read(uint32_t lockTimeout) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief Same as commit with the difference that comitting will be
|
||||
* performed without a lock
|
||||
* @return
|
||||
* This can be used if the lock protection is handled externally
|
||||
* to avoid the overhead of locking and unlocking consecutively.
|
||||
* Declared protected to avoid free public usage.
|
||||
*/
|
||||
virtual ReturnValue_t readWithoutLock() = 0;
|
||||
/**
|
||||
* @brief Same as commit with the difference that comitting will be
|
||||
* performed without a lock
|
||||
* @return
|
||||
* This can be used if the lock protection is handled externally
|
||||
* to avoid the overhead of locking and unlocking consecutively.
|
||||
* Declared protected to avoid free public usage.
|
||||
*/
|
||||
virtual ReturnValue_t commitWithoutLock() = 0;
|
||||
};
|
||||
|
||||
using pool_rwm_t = PoolVariableIF::ReadWriteMode_t;
|
||||
|
||||
#endif /* POOLVARIABLEIF_H_ */
|
||||
|
233
datapool/PoolVector.h
Normal file
233
datapool/PoolVector.h
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* \file PoolVector.h
|
||||
*
|
||||
* \brief This file contains the PoolVector class, the header only class to handle data pool vectors.
|
||||
*
|
||||
* \date 10/23/2012
|
||||
*
|
||||
* \author Bastian Baetz
|
||||
*/
|
||||
|
||||
#ifndef POOLVECTOR_H_
|
||||
#define POOLVECTOR_H_
|
||||
|
||||
#include "DataSetIF.h"
|
||||
#include "PoolEntry.h"
|
||||
#include "PoolVariableIF.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
/**
|
||||
* \brief This is the access class for array-type data pool entries.
|
||||
*
|
||||
* \details To ensure safe usage of the data pool, operation is not done directly on the data pool
|
||||
* entries, but on local copies. This class provides simple type- and length-safe access
|
||||
* to vector-style data pool entries (i.e. entries with length > 1).
|
||||
* The class can be instantiated as read-write and read only.
|
||||
* It provides a commit-and-roll-back semantic, which means that no array entry in
|
||||
* the data pool is changed until the commit call is executed.
|
||||
* There are two template parameters:
|
||||
* \tparam T This template parameter specifies the data type of an array entry. Currently, all
|
||||
* plain data types are supported, but in principle any type is possible.
|
||||
* \tparam vector_size This template parameter specifies the vector size of this entry.
|
||||
* Using a template parameter for this is not perfect, but avoids dynamic memory allocation.
|
||||
* \ingroup data_pool
|
||||
*/
|
||||
template<typename T, uint16_t vector_size>
|
||||
class PoolVector: public PoolVariableIF {
|
||||
private:
|
||||
/**
|
||||
* \brief To access the correct data pool entry on read and commit calls, the data pool id
|
||||
* is stored.
|
||||
*/
|
||||
uint32_t dataPoolId;
|
||||
/**
|
||||
* \brief The valid information as it was stored in the data pool is copied to this attribute.
|
||||
*/
|
||||
uint8_t valid;
|
||||
/**
|
||||
* \brief The information whether the class is read-write or read-only is stored here.
|
||||
*/
|
||||
ReadWriteMode_t readWriteMode;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* \brief This is a call to read the array's values from the global data pool.
|
||||
* \details When executed, this operation tries to fetch the pool entry with matching
|
||||
* data pool id from the global data pool and copies all array values and the valid
|
||||
* information to its local attributes. In case of a failure (wrong type, size or
|
||||
* pool id not found), the variable is set to zero and invalid.
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
*/
|
||||
ReturnValue_t read() {
|
||||
PoolEntry<T>* read_out = ::dataPool.getData<T>(this->dataPoolId,
|
||||
vector_size);
|
||||
if (read_out != NULL) {
|
||||
this->valid = read_out->valid;
|
||||
memcpy(this->value, read_out->address, read_out->getByteSize());
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
|
||||
} else {
|
||||
memset(this->value, 0, vector_size * sizeof(T));
|
||||
sif::error << "PoolVector: read of DP Variable 0x" << std::hex
|
||||
<< dataPoolId << std::dec << " failed." << std::endl;
|
||||
this->valid = INVALID;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief The commit call copies the array values back to the data pool.
|
||||
* \details It checks type and size, as well as if the variable is writable. If so,
|
||||
* the value is copied and the valid flag is automatically set to "valid".
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
*
|
||||
*/
|
||||
ReturnValue_t commit() {
|
||||
PoolEntry<T>* write_back = ::dataPool.getData<T>(this->dataPoolId,
|
||||
vector_size);
|
||||
if ((write_back != NULL) && (this->readWriteMode != VAR_READ)) {
|
||||
write_back->valid = valid;
|
||||
memcpy(write_back->address, this->value, write_back->getByteSize());
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* \brief This is the local copy of the data pool entry.
|
||||
* \detials The user can work on this attribute
|
||||
* just like he would on a local array of this type.
|
||||
*/
|
||||
T value[vector_size];
|
||||
/**
|
||||
* \brief In the constructor, the variable can register itself in a DataSet (if not NULL is
|
||||
* passed).
|
||||
* \details It DOES NOT fetch the current value from the data pool, but sets the value
|
||||
* attribute to default (0). The value is fetched within the read() operation.
|
||||
* \param set_id This is the id in the global data pool this instance of the access class
|
||||
* corresponds to.
|
||||
* \param dataSet The data set in which the variable shall register itself. If NULL,
|
||||
* the variable is not registered.
|
||||
* \param setWritable If this flag is set to true, changes in the value attribute can be
|
||||
* written back to the data pool, otherwise not.
|
||||
*/
|
||||
PoolVector(uint32_t set_id, DataSetIF* set,
|
||||
ReadWriteMode_t setReadWriteMode) :
|
||||
dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) {
|
||||
memset(this->value, 0, vector_size * sizeof(T));
|
||||
if (set != NULL) {
|
||||
set->registerVariable(this);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copy ctor to copy classes containing Pool Variables.
|
||||
*/
|
||||
// PoolVector(const PoolVector& rhs) {
|
||||
// PoolVector<T, vector_size> temp(rhs.dataPoolId, rhs.)
|
||||
// memcpy(value, rhs.value, sizeof(T)*vector_size);
|
||||
// }
|
||||
/**
|
||||
* \brief The classes destructor is empty.
|
||||
* \details If commit() was not called, the local value is
|
||||
* discarded and not written back to the data pool.
|
||||
*/
|
||||
~PoolVector() {
|
||||
}
|
||||
;
|
||||
/**
|
||||
* \brief The operation returns the number of array entries in this variable.
|
||||
*/
|
||||
uint8_t getSize() {
|
||||
return vector_size;
|
||||
}
|
||||
/**
|
||||
* \brief This operation returns the data pool id of the variable.
|
||||
*/
|
||||
uint32_t getDataPoolId() const {
|
||||
return dataPoolId;
|
||||
}
|
||||
/**
|
||||
* This operation sets the data pool id of the variable.
|
||||
* The method is necessary to set id's of data pool member variables with bad initialization.
|
||||
*/
|
||||
void setDataPoolId(uint32_t poolId) {
|
||||
dataPoolId = poolId;
|
||||
}
|
||||
/**
|
||||
* This method returns if the variable is write-only, read-write or read-only.
|
||||
*/
|
||||
ReadWriteMode_t getReadWriteMode() const {
|
||||
return readWriteMode;
|
||||
}
|
||||
;
|
||||
/**
|
||||
* \brief With this call, the valid information of the variable is returned.
|
||||
*/
|
||||
bool isValid() const {
|
||||
if (valid != INVALID)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void setValid(uint8_t valid) {
|
||||
this->valid = valid;
|
||||
}
|
||||
|
||||
uint8_t getValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
T &operator [](int i) {
|
||||
return value[i];
|
||||
}
|
||||
|
||||
const T &operator [](int i) const {
|
||||
return value[i];
|
||||
}
|
||||
|
||||
PoolVector<T, vector_size> &operator=(
|
||||
PoolVector<T, vector_size> newPoolVector) {
|
||||
|
||||
for (uint16_t i = 0; i < vector_size; i++) {
|
||||
this->value[i] = newPoolVector.value[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) const {
|
||||
uint16_t i;
|
||||
ReturnValue_t result;
|
||||
for (i = 0; i < vector_size; i++) {
|
||||
result = SerializeAdapter::serialize(&(value[i]), buffer, size,
|
||||
maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
return vector_size * SerializeAdapter::getSerializedSize(value);
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) {
|
||||
uint16_t i;
|
||||
ReturnValue_t result;
|
||||
for (i = 0; i < vector_size; i++) {
|
||||
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size,
|
||||
streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* POOLVECTOR_H_ */
|
@ -1,132 +0,0 @@
|
||||
#include <framework/datapoolglob/GlobalDataPool.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/ipc/MutexFactory.h>
|
||||
|
||||
GlobalDataPool::GlobalDataPool(
|
||||
void(*initFunction)(GlobPoolMap* pool_map)) {
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
if (initFunction != NULL ) {
|
||||
initFunction( &this->globDataPool );
|
||||
}
|
||||
}
|
||||
|
||||
GlobalDataPool::~GlobalDataPool() {
|
||||
MutexFactory::instance()->deleteMutex(mutex);
|
||||
for(GlobPoolMapIter it = this->globDataPool.begin();
|
||||
it != this->globDataPool.end(); ++it )
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
// The function checks PID, type and array length before returning a copy of
|
||||
// the PoolEntry. In failure case, it returns a temp-Entry with size 0 and NULL-ptr.
|
||||
template <typename T> PoolEntry<T>* GlobalDataPool::getData( uint32_t data_pool_id,
|
||||
uint8_t sizeOrPosition ) {
|
||||
GlobPoolMapIter it = this->globDataPool.find( data_pool_id );
|
||||
if ( it != this->globDataPool.end() ) {
|
||||
PoolEntry<T>* entry = dynamic_cast< PoolEntry<T>* >( it->second );
|
||||
if (entry != nullptr ) {
|
||||
if ( sizeOrPosition <= entry->length ) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PoolEntryIF* GlobalDataPool::getRawData( uint32_t data_pool_id ) {
|
||||
GlobPoolMapIter it = this->globDataPool.find( data_pool_id );
|
||||
if ( it != this->globDataPool.end() ) {
|
||||
return it->second;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t GlobalDataPool::unlockDataPool() {
|
||||
ReturnValue_t status = mutex->unlockMutex();
|
||||
if(status != RETURN_OK) {
|
||||
sif::error << "DataPool::DataPool: unlock of mutex failed with"
|
||||
" error code: " << status << std::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
ReturnValue_t GlobalDataPool::lockDataPool(uint32_t timeoutMs) {
|
||||
ReturnValue_t status = mutex->lockMutex(timeoutMs);
|
||||
if(status != RETURN_OK) {
|
||||
sif::error << "DataPool::DataPool: lock of mutex failed "
|
||||
"with error code: " << status << std::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void GlobalDataPool::print() {
|
||||
sif::debug << "DataPool contains: " << std::endl;
|
||||
std::map<uint32_t, PoolEntryIF*>::iterator dataPoolIt;
|
||||
dataPoolIt = this->globDataPool.begin();
|
||||
while( dataPoolIt != this->globDataPool.end() ) {
|
||||
sif::debug << std::hex << dataPoolIt->first << std::dec << " |";
|
||||
dataPoolIt->second->print();
|
||||
dataPoolIt++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GlobalDataPool::PIDToDataPoolId(uint32_t parameter_id) {
|
||||
return (parameter_id >> 8) & 0x00FFFFFF;
|
||||
}
|
||||
|
||||
uint8_t GlobalDataPool::PIDToArrayIndex(uint32_t parameter_id) {
|
||||
return (parameter_id & 0x000000FF);
|
||||
}
|
||||
|
||||
uint32_t GlobalDataPool::poolIdAndPositionToPid(uint32_t poolId, uint8_t index) {
|
||||
return (poolId << 8) + index;
|
||||
}
|
||||
|
||||
|
||||
//SHOULDDO: Do we need a mutex lock here... I don't think so,
|
||||
//as we only check static const values of elements in a list that do not change.
|
||||
//there is no guarantee in the standard, but it seems to me that the implementation is safe -UM
|
||||
ReturnValue_t GlobalDataPool::getType(uint32_t parameter_id, Type* type) {
|
||||
GlobPoolMapIter it = this->globDataPool.find( PIDToDataPoolId(parameter_id));
|
||||
if ( it != this->globDataPool.end() ) {
|
||||
*type = it->second->getType();
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
*type = Type::UNKNOWN_TYPE;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
bool GlobalDataPool::exists(uint32_t parameterId) {
|
||||
uint32_t poolId = PIDToDataPoolId(parameterId);
|
||||
uint32_t index = PIDToArrayIndex(parameterId);
|
||||
GlobPoolMapIter it = this->globDataPool.find( poolId );
|
||||
if (it != globDataPool.end()) {
|
||||
if (it->second->getSize() >= index) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template PoolEntry<uint8_t>* GlobalDataPool::getData<uint8_t>(
|
||||
uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<uint16_t>* GlobalDataPool::getData<uint16_t>(
|
||||
uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<uint32_t>* GlobalDataPool::getData<uint32_t>(
|
||||
uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<uint64_t>* GlobalDataPool::getData<uint64_t>(
|
||||
uint32_t data_pool_id, uint8_t size);
|
||||
template PoolEntry<int8_t>* GlobalDataPool::getData<int8_t>(
|
||||
uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<int16_t>* GlobalDataPool::getData<int16_t>(
|
||||
uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<int32_t>* GlobalDataPool::getData<int32_t>(
|
||||
uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<float>* GlobalDataPool::getData<float>(
|
||||
uint32_t data_pool_id, uint8_t size );
|
||||
template PoolEntry<double>* GlobalDataPool::getData<double>(
|
||||
uint32_t data_pool_id, uint8_t size);
|
@ -1,149 +0,0 @@
|
||||
#ifndef GLOBALDATAPOOL_H_
|
||||
#define GLOBALDATAPOOL_H_
|
||||
|
||||
#include <framework/datapool/PoolEntry.h>
|
||||
#include <framework/globalfunctions/Type.h>
|
||||
#include <framework/ipc/MutexIF.h>
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* @defgroup data_pool Global data pool
|
||||
* This is the group, where all classes associated with global
|
||||
* data pool handling belong to.
|
||||
* This includes classes to access Data Pool variables.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Typedefs for the global pool representations
|
||||
*/
|
||||
using GlobPoolMap = std::map<uint32_t, PoolEntryIF*>;
|
||||
using GlobPoolMapIter = GlobPoolMap::iterator;
|
||||
|
||||
/**
|
||||
* @brief This class represents the OBSW global data-pool.
|
||||
*
|
||||
* @details
|
||||
* All variables are registered and space is allocated in an initialization
|
||||
* function, which is passed do the constructor. Space for the variables is
|
||||
* allocated on the heap (with a new call).
|
||||
*
|
||||
* The data is found by a data pool id, which uniquely represents a variable.
|
||||
* Data pool variables should be used with a blackboard logic in mind,
|
||||
* which means read data is valid (if flagged so),
|
||||
* but not necessarily up-to-date.
|
||||
*
|
||||
* Variables are either single values or arrays.
|
||||
* @author Bastian Baetz
|
||||
* @ingroup data_pool
|
||||
*/
|
||||
class GlobalDataPool : public HasReturnvaluesIF {
|
||||
private:
|
||||
/**
|
||||
* @brief This is the actual data pool itself.
|
||||
* @details It is represented by a map with the data pool id as index
|
||||
* and a pointer to a single PoolEntry as value.
|
||||
*/
|
||||
GlobPoolMap globDataPool;
|
||||
|
||||
/**
|
||||
* @brief The mutex is created in the constructor and makes
|
||||
* access mutual exclusive.
|
||||
* @details Locking and unlocking the pool is only done by the DataSet class.
|
||||
*/
|
||||
MutexIF* mutex;
|
||||
public:
|
||||
/**
|
||||
* @brief In the classes constructor,
|
||||
* the passed initialization function is called.
|
||||
* @details
|
||||
* To enable filling the pool, a pointer to the map is passed,
|
||||
* allowing direct access to the pool's content.
|
||||
* On runtime, adding or removing variables is forbidden.
|
||||
*/
|
||||
GlobalDataPool( void ( *initFunction )( GlobPoolMap* pool_map ) );
|
||||
|
||||
/**
|
||||
* @brief The destructor iterates through the data_pool map and
|
||||
* calls all entries destructors to clean up the heap.
|
||||
*/
|
||||
~GlobalDataPool();
|
||||
|
||||
/**
|
||||
* @brief This is the default call to access the pool.
|
||||
* @details
|
||||
* A pointer to the PoolEntry object is returned.
|
||||
* The call checks data pool id, type and array size.
|
||||
* Returns NULL in case of failure.
|
||||
* @param data_pool_id The data pool id to search.
|
||||
* @param sizeOrPosition The array size (not byte size!) of the pool entry,
|
||||
* or the position the user wants to read.
|
||||
* If smaller than the entry size, everything's ok.
|
||||
*/
|
||||
template <typename T> PoolEntry<T>* getData( uint32_t data_pool_id,
|
||||
uint8_t sizeOrPosition );
|
||||
|
||||
/**
|
||||
* @brief An alternative call to get a data pool entry in case the type is not implicitly known
|
||||
* (i.e. in Housekeeping Telemetry).
|
||||
* @details It returns a basic interface and does NOT perform
|
||||
* a size check. The caller has to assure he does not copy too much data.
|
||||
* Returns NULL in case the entry is not found.
|
||||
* @param data_pool_id The data pool id to search.
|
||||
*/
|
||||
PoolEntryIF* getRawData( uint32_t data_pool_id );
|
||||
/**
|
||||
* @brief This is a small helper function to facilitate locking the global data pool.
|
||||
* @details It fetches the pool's mutex id and tries to acquire the mutex.
|
||||
*/
|
||||
ReturnValue_t lockDataPool(uint32_t timeoutMs = MutexIF::BLOCKING);
|
||||
/**
|
||||
* @brief This is a small helper function to facilitate unlocking the global data pool.
|
||||
* @details It fetches the pool's mutex id and tries to free the mutex.
|
||||
*/
|
||||
ReturnValue_t unlockDataPool();
|
||||
/**
|
||||
* @brief The print call is a simple debug method.
|
||||
* @details It prints the current content of the data pool.
|
||||
* It iterates through the data_pool map and calls each entry's print() method.
|
||||
*/
|
||||
void print();
|
||||
/**
|
||||
* Extracts the data pool id from a SCOS 2000 PID.
|
||||
* @param parameter_id The passed Parameter ID.
|
||||
* @return The data pool id as used within the OBSW.
|
||||
*/
|
||||
static uint32_t PIDToDataPoolId( uint32_t parameter_id );
|
||||
/**
|
||||
* Extracts an array index out of a SCOS 2000 PID.
|
||||
* @param parameter_id The passed Parameter ID.
|
||||
* @return The index of the corresponding data pool entry.
|
||||
*/
|
||||
static uint8_t PIDToArrayIndex( uint32_t parameter_id );
|
||||
/**
|
||||
* Retransforms a data pool id and an array index to a SCOS 2000 PID.
|
||||
*/
|
||||
static uint32_t poolIdAndPositionToPid( uint32_t poolId, uint8_t index );
|
||||
|
||||
/**
|
||||
* Method to return the type of a pool variable.
|
||||
* @param parameter_id A parameterID (not pool id) of a DP member.
|
||||
* @param type Returns the type or TYPE::UNKNOWN_TYPE
|
||||
* @return RETURN_OK if parameter exists, RETURN_FAILED else.
|
||||
*/
|
||||
ReturnValue_t getType( uint32_t parameter_id, Type* type );
|
||||
|
||||
/**
|
||||
* Method to check if a PID exists. Does not lock, as there's no
|
||||
* possibility to alter the list that is checked during run-time.
|
||||
* @param parameterId The PID (not pool id!) of a parameter.
|
||||
* @return true if exists, false else.
|
||||
*/
|
||||
bool exists(uint32_t parameterId);
|
||||
};
|
||||
|
||||
//We assume someone globally instantiates a DataPool.
|
||||
namespace glob {
|
||||
extern GlobalDataPool dataPool;
|
||||
}
|
||||
|
||||
#endif /* DATAPOOL_H_ */
|
@ -1,44 +0,0 @@
|
||||
#include <framework/datapoolglob/GlobalDataPool.h>
|
||||
#include <framework/datapoolglob/GlobalDataSet.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
GlobDataSet::GlobDataSet(): DataSetBase(
|
||||
reinterpret_cast<PoolVariableIF**>(®isteredVariables),
|
||||
DATA_SET_MAX_SIZE) {}
|
||||
|
||||
// Don't do anything with your variables, they are dead already!
|
||||
// (Destructor is already called)
|
||||
GlobDataSet::~GlobDataSet() {}
|
||||
|
||||
ReturnValue_t GlobDataSet::commit(bool valid, uint32_t lockTimeout) {
|
||||
setEntriesValid(valid);
|
||||
setSetValid(valid);
|
||||
return commit(lockTimeout);
|
||||
}
|
||||
|
||||
ReturnValue_t GlobDataSet::commit(uint32_t lockTimeout) {
|
||||
return DataSetBase::commit(lockTimeout);
|
||||
}
|
||||
|
||||
ReturnValue_t GlobDataSet::unlockDataPool() {
|
||||
return glob::dataPool.unlockDataPool();
|
||||
}
|
||||
|
||||
ReturnValue_t GlobDataSet::lockDataPool(uint32_t timeoutMs) {
|
||||
return glob::dataPool.lockDataPool(timeoutMs);
|
||||
}
|
||||
|
||||
void GlobDataSet::setEntriesValid(bool valid) {
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
if (registeredVariables[count]->getReadWriteMode()
|
||||
!= PoolVariableIF::VAR_READ) {
|
||||
registeredVariables[count]->setValid(valid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlobDataSet::setSetValid(bool valid) {
|
||||
this->valid = valid;
|
||||
}
|
||||
|
||||
|
@ -1,96 +0,0 @@
|
||||
#ifndef FRAMEWORK_DATAPOOLGLOB_DATASET_H_
|
||||
#define FRAMEWORK_DATAPOOLGLOB_DATASET_H_
|
||||
|
||||
#include <framework/datapool/DataSetBase.h>
|
||||
|
||||
/**
|
||||
* @brief The DataSet class manages a set of locally checked out variables
|
||||
* for the global data pool.
|
||||
* @details
|
||||
* This class uses the read-commit() semantic provided by the DataSetBase class.
|
||||
* It extends the base class by using the global data pool,
|
||||
* having a valid state and implementing lock und unlock calls for the global
|
||||
* datapool.
|
||||
*
|
||||
* For more information on how this class works, see the DataSetBase
|
||||
* documentation.
|
||||
* @author Bastian Baetz
|
||||
* @ingroup data_pool
|
||||
*/
|
||||
class GlobDataSet: public DataSetBase {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Creates an empty GlobDataSet. Use registerVariable or
|
||||
* supply a pointer to this dataset to PoolVariable
|
||||
* initializations to register pool variables.
|
||||
*/
|
||||
GlobDataSet();
|
||||
|
||||
/**
|
||||
* @brief The destructor automatically manages writing the valid
|
||||
* information of variables.
|
||||
* @details
|
||||
* In case the data set was read out, but not committed(indicated by state),
|
||||
* the destructor parses all variables that are still registered to the set.
|
||||
* For each, the valid flag in the data pool is set to "invalid".
|
||||
*/
|
||||
~GlobDataSet();
|
||||
|
||||
/**
|
||||
* Variant of method above which sets validity of all elements of the set.
|
||||
* @param valid Validity information from PoolVariableIF.
|
||||
* @return - @c RETURN_OK if all variables were read successfully.
|
||||
* - @c COMMITING_WITHOUT_READING if set was not read yet and
|
||||
* contains non write-only variables
|
||||
*/
|
||||
ReturnValue_t commit(bool valid, uint32_t lockTimeout = MutexIF::BLOCKING);
|
||||
ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override;
|
||||
|
||||
/**
|
||||
* Set all entries
|
||||
* @param valid
|
||||
*/
|
||||
void setSetValid(bool valid);
|
||||
|
||||
/**
|
||||
* Set the valid information of all variables contained in the set which
|
||||
* are not read-only
|
||||
*
|
||||
* @param valid Validity information from PoolVariableIF.
|
||||
*/
|
||||
void setEntriesValid(bool valid);
|
||||
|
||||
//!< This definition sets the maximum number of variables to
|
||||
//! register in one DataSet.
|
||||
static const uint8_t DATA_SET_MAX_SIZE = 63;
|
||||
|
||||
private:
|
||||
/**
|
||||
* If the valid state of a dataset is always relevant to the whole
|
||||
* data set we can use this flag.
|
||||
*/
|
||||
bool valid = false;
|
||||
|
||||
/**
|
||||
* @brief This is a small helper function to facilitate locking
|
||||
* the global data pool.
|
||||
* @details
|
||||
* It makes use of the lockDataPool method offered by the DataPool class.
|
||||
*/
|
||||
ReturnValue_t lockDataPool(uint32_t timeoutMs) override;
|
||||
/**
|
||||
* @brief This is a small helper function to facilitate
|
||||
* unlocking the global data pool
|
||||
* @details
|
||||
* It makes use of the freeDataPoolLock method offered by the DataPool class.
|
||||
*/
|
||||
ReturnValue_t unlockDataPool() override;
|
||||
|
||||
void handleAlreadyReadDatasetCommit();
|
||||
ReturnValue_t handleUnreadDatasetCommit();
|
||||
|
||||
PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE];
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_DATAPOOLGLOB_DATASET_H_ */
|
@ -1,213 +0,0 @@
|
||||
#ifndef GLOBALPOOLVARIABLE_H_
|
||||
#define GLOBALPOOLVARIABLE_H_
|
||||
|
||||
#include <framework/datapool/DataSetIF.h>
|
||||
#include <framework/datapoolglob/GlobalDataPool.h>
|
||||
#include <framework/datapool/PoolVariableIF.h>
|
||||
#include <framework/datapool/PoolEntry.h>
|
||||
#include <framework/serialize/SerializeAdapter.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
template<typename T, uint8_t n_var> class PoolVarList;
|
||||
|
||||
|
||||
/**
|
||||
* @brief This is the access class for non-array data pool entries.
|
||||
*
|
||||
* @details
|
||||
* To ensure safe usage of the data pool, operation is not done directly
|
||||
* on the data pool entries, but on local copies. This class provides simple
|
||||
* type-safe access to single data pool entries (i.e. entries with length = 1).
|
||||
* The class can be instantiated as read-write and read only.
|
||||
* It provides a commit-and-roll-back semantic, which means that the
|
||||
* variable's value in the data pool is not changed until the
|
||||
* commit call is executed.
|
||||
* @tparam T The template parameter sets the type of the variable.
|
||||
* Currently, all plain data types are supported, but in principle
|
||||
* any type is possible.
|
||||
* @ingroup data_pool
|
||||
*/
|
||||
template<typename T>
|
||||
class GlobPoolVar: public PoolVariableIF {
|
||||
template<typename U, uint8_t n_var> friend class PoolVarList;
|
||||
static_assert(not std::is_same<T, bool>::value,
|
||||
"Do not use boolean for the PoolEntry type, use uint8_t instead!"
|
||||
"There is no boolean type in CCSDS.");
|
||||
public:
|
||||
/**
|
||||
* @brief In the constructor, the variable can register itself in a
|
||||
* DataSet (if nullptr is not passed).
|
||||
* @details
|
||||
* It DOES NOT fetch the current value from the data pool, but
|
||||
* sets the value attribute to default (0).
|
||||
* The value is fetched within the read() operation.
|
||||
* @param set_id This is the id in the global data pool
|
||||
* this instance of the access class corresponds to.
|
||||
* @param dataSet The data set in which the variable shall register
|
||||
* itself. If NULL, the variable is not registered.
|
||||
* @param setWritable If this flag is set to true, changes in the value
|
||||
* attribute can be written back to the data pool, otherwise not.
|
||||
*/
|
||||
GlobPoolVar(uint32_t set_id, DataSetIF* dataSet,
|
||||
ReadWriteMode_t setReadWriteMode);
|
||||
|
||||
/**
|
||||
* @brief This is the local copy of the data pool entry.
|
||||
* @details The user can work on this attribute
|
||||
* just like he would on a simple local variable.
|
||||
*/
|
||||
T value = 0;
|
||||
|
||||
/**
|
||||
* @brief Copy ctor to copy classes containing Pool Variables.
|
||||
* (Robin): This only copies member variables, which is done
|
||||
* by the default copy ctor. maybe we can ommit this ctor?
|
||||
*/
|
||||
GlobPoolVar(const GlobPoolVar& rhs);
|
||||
|
||||
/**
|
||||
* @brief The classes destructor is empty.
|
||||
* @details If commit() was not called, the local value is
|
||||
* discarded and not written back to the data pool.
|
||||
*/
|
||||
~GlobPoolVar() {}
|
||||
|
||||
/**
|
||||
* @brief This is a call to read the value from the global data pool.
|
||||
* @details
|
||||
* When executed, this operation tries to fetch the pool entry with matching
|
||||
* data pool id from the global data pool and copies the value and the valid
|
||||
* information to its local attributes. In case of a failure (wrong type or
|
||||
* pool id not found), the variable is set to zero and invalid.
|
||||
* The read call is protected with a lock.
|
||||
* It is recommended to use DataSets to read and commit multiple variables
|
||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||
*/
|
||||
ReturnValue_t read(uint32_t lockTimeout) override;
|
||||
/**
|
||||
* @brief The commit call writes back the variable's value to the data pool.
|
||||
* @details
|
||||
* It checks type and size, as well as if the variable is writable. If so,
|
||||
* the value is copied and the valid flag is automatically set to "valid".
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
* The commit call is protected with a lock.
|
||||
* It is recommended to use DataSets to read and commit multiple variables
|
||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||
*/
|
||||
ReturnValue_t commit(uint32_t lockTimeout) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Like #read, but without a lock protection of the global pool.
|
||||
* @details
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
* This can be used if the lock is handled externally to avoid the overhead
|
||||
* of consecutive lock und unlock operations.
|
||||
* Declared protected to discourage free public usage.
|
||||
*/
|
||||
ReturnValue_t readWithoutLock() override;
|
||||
/**
|
||||
* @brief Like #commit, but without a lock protection of the global pool.
|
||||
* @details
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
* This can be used if the lock is handled externally to avoid the overhead
|
||||
* of consecutive lock und unlock operations.
|
||||
* Declared protected to discourage free public usage.
|
||||
*/
|
||||
ReturnValue_t commitWithoutLock() override;
|
||||
/**
|
||||
* @brief To access the correct data pool entry on read and commit calls,
|
||||
* the data pool is stored.
|
||||
*/
|
||||
uint32_t dataPoolId;
|
||||
|
||||
/**
|
||||
* @brief The valid information as it was stored in the data pool is
|
||||
* copied to this attribute.
|
||||
*/
|
||||
uint8_t valid;
|
||||
|
||||
/**
|
||||
* @brief The information whether the class is read-write or read-only
|
||||
* is stored here.
|
||||
*/
|
||||
pool_rwm_t readWriteMode;
|
||||
|
||||
/**
|
||||
* Empty ctor for List initialization
|
||||
*/
|
||||
GlobPoolVar();
|
||||
public:
|
||||
/**
|
||||
* \brief This operation returns the data pool id of the variable.
|
||||
*/
|
||||
uint32_t getDataPoolId() const override;
|
||||
|
||||
/**
|
||||
* This method returns if the variable is write-only, read-write or read-only.
|
||||
*/
|
||||
ReadWriteMode_t getReadWriteMode() const override;
|
||||
/**
|
||||
* This operation sets the data pool id of the variable.
|
||||
* The method is necessary to set id's of data pool member variables with bad initialization.
|
||||
*/
|
||||
void setDataPoolId(uint32_t poolId);
|
||||
|
||||
/**
|
||||
* \brief With this call, the valid information of the variable is returned.
|
||||
*/
|
||||
bool isValid() const override;
|
||||
|
||||
uint8_t getValid();
|
||||
|
||||
void setValid(bool valid) override;
|
||||
|
||||
operator T() {
|
||||
return value;
|
||||
}
|
||||
|
||||
operator T() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
GlobPoolVar<T> &operator=(T newValue) {
|
||||
value = newValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
GlobPoolVar<T> &operator=(GlobPoolVar<T> newPoolVariable) {
|
||||
value = newPoolVariable.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
const size_t max_size,
|
||||
SerializeIF::Endianness streamEndianness) const override {
|
||||
return SerializeAdapter::serialize(&value, buffer, size, max_size,
|
||||
streamEndianness);
|
||||
}
|
||||
|
||||
virtual size_t getSerializedSize() const {
|
||||
return SerializeAdapter::getSerializedSize(&value);
|
||||
}
|
||||
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) {
|
||||
return SerializeAdapter::deSerialize(&value, buffer, size,
|
||||
streamEndianness);
|
||||
}
|
||||
};
|
||||
|
||||
#include <framework/datapoolglob/GlobalPoolVariable.tpp>
|
||||
|
||||
typedef GlobPoolVar<uint8_t> gp_bool_t;
|
||||
typedef GlobPoolVar<uint8_t> gp_uint8_t;
|
||||
typedef GlobPoolVar<uint16_t> gp_uint16_t;
|
||||
typedef GlobPoolVar<uint32_t> gp_uint32_t;
|
||||
typedef GlobPoolVar<int8_t> gp_int8_t;
|
||||
typedef GlobPoolVar<int16_t> gp_int16_t;
|
||||
typedef GlobPoolVar<int32_t> gp_int32_t;
|
||||
typedef GlobPoolVar<float> gp_float_t;
|
||||
typedef GlobPoolVar<double> gp_double_t;
|
||||
|
||||
#endif /* POOLVARIABLE_H_ */
|
@ -1,117 +0,0 @@
|
||||
#ifndef GLOBALPOOLVARIABLE_TPP_
|
||||
#define GLOBALPOOLVARIABLE_TPP_
|
||||
|
||||
template <class T>
|
||||
inline GlobPoolVar<T>::GlobPoolVar(uint32_t set_id,
|
||||
DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode):
|
||||
dataPoolId(set_id), valid(PoolVariableIF::INVALID),
|
||||
readWriteMode(setReadWriteMode)
|
||||
{
|
||||
if (dataSet != nullptr) {
|
||||
dataSet->registerVariable(this);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline ReturnValue_t GlobPoolVar<T>::read(uint32_t lockTimeout) {
|
||||
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = readWithoutLock();
|
||||
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
|
||||
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
|
||||
<< std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline ReturnValue_t GlobPoolVar<T>::commit(uint32_t lockTimeout) {
|
||||
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = commitWithoutLock();
|
||||
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
|
||||
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
|
||||
<< std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline ReturnValue_t GlobPoolVar<T>::readWithoutLock() {
|
||||
PoolEntry<T>* read_out = glob::dataPool.getData<T>(dataPoolId, 1);
|
||||
if (read_out != NULL) {
|
||||
valid = read_out->valid;
|
||||
value = *(read_out->address);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
value = 0;
|
||||
valid = false;
|
||||
sif::error << "PoolVariable: read of DP Variable 0x" << std::hex
|
||||
<< dataPoolId << std::dec << " failed." << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline ReturnValue_t GlobPoolVar<T>::commitWithoutLock() {
|
||||
PoolEntry<T>* write_back = glob::dataPool.getData<T>(dataPoolId, 1);
|
||||
if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
|
||||
write_back->valid = valid;
|
||||
*(write_back->address) = value;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline GlobPoolVar<T>::GlobPoolVar():
|
||||
dataPoolId(PoolVariableIF::NO_PARAMETER),
|
||||
valid(PoolVariableIF::INVALID),
|
||||
readWriteMode(VAR_READ), value(0) {}
|
||||
|
||||
template <class T>
|
||||
inline GlobPoolVar<T>::GlobPoolVar(const GlobPoolVar& rhs) :
|
||||
dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode(
|
||||
rhs.readWriteMode), value(rhs.value) {}
|
||||
|
||||
template <class T>
|
||||
inline pool_rwm_t GlobPoolVar<T>::getReadWriteMode() const {
|
||||
return readWriteMode;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline uint32_t GlobPoolVar<T>::getDataPoolId() const {
|
||||
return dataPoolId;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void GlobPoolVar<T>::setDataPoolId(uint32_t poolId) {
|
||||
dataPoolId = poolId;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool GlobPoolVar<T>::isValid() const {
|
||||
if (valid)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline uint8_t GlobPoolVar<T>::getValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void GlobPoolVar<T>::setValid(bool valid) {
|
||||
this->valid = valid;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,185 +0,0 @@
|
||||
#ifndef GLOBALPOOLVECTOR_H_
|
||||
#define GLOBALPOOLVECTOR_H_
|
||||
|
||||
#include <framework/datapool/DataSetIF.h>
|
||||
#include <framework/datapool/PoolEntry.h>
|
||||
#include <framework/datapool/PoolVariableIF.h>
|
||||
#include <framework/serialize/SerializeAdapter.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
/**
|
||||
* @brief This is the access class for array-type data pool entries.
|
||||
*
|
||||
* @details
|
||||
* To ensure safe usage of the data pool, operation is not done directly on the
|
||||
* data pool entries, but on local copies. This class provides simple type-
|
||||
* and length-safe access to vector-style data pool entries (i.e. entries with
|
||||
* length > 1). The class can be instantiated as read-write and read only.
|
||||
*
|
||||
* It provides a commit-and-roll-back semantic, which means that no array
|
||||
* entry in the data pool is changed until the commit call is executed.
|
||||
* There are two template parameters:
|
||||
* @tparam T
|
||||
* This template parameter specifies the data type of an array entry. Currently,
|
||||
* all plain data types are supported, but in principle any type is possible.
|
||||
* @tparam vector_size
|
||||
* This template parameter specifies the vector size of this entry. Using a
|
||||
* template parameter for this is not perfect, but avoids
|
||||
* dynamic memory allocation.
|
||||
* @ingroup data_pool
|
||||
*/
|
||||
template<typename T, uint16_t vectorSize>
|
||||
class GlobPoolVector: public PoolVariableIF {
|
||||
public:
|
||||
/**
|
||||
* @brief In the constructor, the variable can register itself in a
|
||||
* DataSet (if no nullptr is passed).
|
||||
* @details
|
||||
* It DOES NOT fetch the current value from the data pool, but sets the
|
||||
* value attribute to default (0). The value is fetched within the
|
||||
* read() operation.
|
||||
* @param set_id
|
||||
* This is the id in the global data pool this instance of the access
|
||||
* class corresponds to.
|
||||
* @param dataSet
|
||||
* The data set in which the variable shall register itself. If nullptr,
|
||||
* the variable is not registered.
|
||||
* @param setWritable
|
||||
* If this flag is set to true, changes in the value attribute can be
|
||||
* written back to the data pool, otherwise not.
|
||||
*/
|
||||
GlobPoolVector(uint32_t set_id, DataSetIF* set,
|
||||
ReadWriteMode_t setReadWriteMode);
|
||||
|
||||
/**
|
||||
* @brief This is the local copy of the data pool entry.
|
||||
* @details The user can work on this attribute
|
||||
* just like he would on a local array of this type.
|
||||
*/
|
||||
T value[vectorSize];
|
||||
/**
|
||||
* @brief The classes destructor is empty.
|
||||
* @details If commit() was not called, the local value is
|
||||
* discarded and not written back to the data pool.
|
||||
*/
|
||||
~GlobPoolVector() {};
|
||||
/**
|
||||
* @brief The operation returns the number of array entries
|
||||
* in this variable.
|
||||
*/
|
||||
uint8_t getSize() {
|
||||
return vectorSize;
|
||||
}
|
||||
/**
|
||||
* @brief This operation returns the data pool id of the variable.
|
||||
*/
|
||||
uint32_t getDataPoolId() const {
|
||||
return dataPoolId;
|
||||
}
|
||||
/**
|
||||
* @brief This operation sets the data pool id of the variable.
|
||||
* @details
|
||||
* The method is necessary to set id's of data pool member variables
|
||||
* with bad initialization.
|
||||
*/
|
||||
void setDataPoolId(uint32_t poolId) {
|
||||
dataPoolId = poolId;
|
||||
}
|
||||
/**
|
||||
* This method returns if the variable is write-only, read-write or read-only.
|
||||
*/
|
||||
ReadWriteMode_t getReadWriteMode() const {
|
||||
return readWriteMode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief With this call, the valid information of the variable is returned.
|
||||
*/
|
||||
bool isValid() const {
|
||||
if (valid != INVALID)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
void setValid(bool valid) {this->valid = valid;}
|
||||
uint8_t getValid() {return valid;}
|
||||
|
||||
T &operator [](int i) {return value[i];}
|
||||
const T &operator [](int i) const {return value[i];}
|
||||
|
||||
virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
|
||||
size_t max_size, Endianness streamEndianness) const override;
|
||||
virtual size_t getSerializedSize() const override;
|
||||
virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
/**
|
||||
* @brief This is a call to read the array's values
|
||||
* from the global data pool.
|
||||
* @details
|
||||
* When executed, this operation tries to fetch the pool entry with matching
|
||||
* data pool id from the global data pool and copies all array values
|
||||
* and the valid information to its local attributes.
|
||||
* In case of a failure (wrong type, size or pool id not found), the
|
||||
* variable is set to zero and invalid.
|
||||
* The read call is protected by a lock of the global data pool.
|
||||
* It is recommended to use DataSets to read and commit multiple variables
|
||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||
*/
|
||||
ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override;
|
||||
/**
|
||||
* @brief The commit call copies the array values back to the data pool.
|
||||
* @details
|
||||
* It checks type and size, as well as if the variable is writable. If so,
|
||||
* the value is copied and the valid flag is automatically set to "valid".
|
||||
* The commit call is protected by a lock of the global data pool.
|
||||
* It is recommended to use DataSets to read and commit multiple variables
|
||||
* at once to avoid the overhead of unnecessary lock und unlock operations.
|
||||
*/
|
||||
ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Like #read, but without a lock protection of the global pool.
|
||||
* @details
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
* This can be used if the lock is handled externally to avoid the overhead
|
||||
* of consecutive lock und unlock operations.
|
||||
* Declared protected to discourage free public usage.
|
||||
*/
|
||||
ReturnValue_t readWithoutLock() override;
|
||||
/**
|
||||
* @brief Like #commit, but without a lock protection of the global pool.
|
||||
* @details
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
* This can be used if the lock is handled externally to avoid the overhead
|
||||
* of consecutive lock und unlock operations.
|
||||
* Declared protected to discourage free public usage.
|
||||
*/
|
||||
ReturnValue_t commitWithoutLock() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief To access the correct data pool entry on read and commit calls,
|
||||
* the data pool id is stored.
|
||||
*/
|
||||
uint32_t dataPoolId;
|
||||
/**
|
||||
* @brief The valid information as it was stored in the data pool
|
||||
* is copied to this attribute.
|
||||
*/
|
||||
uint8_t valid;
|
||||
/**
|
||||
* @brief The information whether the class is read-write or
|
||||
* read-only is stored here.
|
||||
*/
|
||||
ReadWriteMode_t readWriteMode;
|
||||
};
|
||||
|
||||
#include <framework/datapoolglob/GlobalPoolVector.tpp>
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
using gp_vec_t = GlobPoolVector<T, vectorSize>;
|
||||
|
||||
#endif /* POOLVECTOR_H_ */
|
@ -1,117 +0,0 @@
|
||||
#ifndef GLOBALPOOLVECTOR_TPP_
|
||||
#define GLOBALPOOLVECTOR_TPP_
|
||||
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline GlobPoolVector<T, vectorSize>::GlobPoolVector(uint32_t set_id,
|
||||
DataSetIF* set, ReadWriteMode_t setReadWriteMode) :
|
||||
dataPoolId(set_id), valid(false), readWriteMode(setReadWriteMode) {
|
||||
memset(this->value, 0, vectorSize * sizeof(T));
|
||||
if (set != nullptr) {
|
||||
set->registerVariable(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline ReturnValue_t GlobPoolVector<T, vectorSize>::read(uint32_t lockTimeout) {
|
||||
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = readWithoutLock();
|
||||
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
|
||||
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
|
||||
<< std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline ReturnValue_t GlobPoolVector<T, vectorSize>::commit(
|
||||
uint32_t lockTimeout) {
|
||||
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = commitWithoutLock();
|
||||
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
|
||||
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
|
||||
<< std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline ReturnValue_t GlobPoolVector<T, vectorSize>::readWithoutLock() {
|
||||
PoolEntry<T>* read_out = glob::dataPool.getData<T>(this->dataPoolId,
|
||||
vectorSize);
|
||||
if (read_out != nullptr) {
|
||||
this->valid = read_out->valid;
|
||||
memcpy(this->value, read_out->address, read_out->getByteSize());
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
|
||||
} else {
|
||||
memset(this->value, 0, vectorSize * sizeof(T));
|
||||
sif::error << "PoolVector: Read of DP Variable 0x" << std::hex
|
||||
<< std::setw(8) << std::setfill('0') << dataPoolId <<
|
||||
std::dec << " failed." << std::endl;
|
||||
this->valid = INVALID;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline ReturnValue_t GlobPoolVector<T, vectorSize>::commitWithoutLock() {
|
||||
PoolEntry<T>* writeBack = glob::dataPool.getData<T>(this->dataPoolId,
|
||||
vectorSize);
|
||||
if ((writeBack != nullptr) && (this->readWriteMode != VAR_READ)) {
|
||||
writeBack->valid = valid;
|
||||
memcpy(writeBack->address, this->value, writeBack->getByteSize());
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline ReturnValue_t GlobPoolVector<T, vectorSize>::serialize(uint8_t** buffer,
|
||||
size_t* size, size_t max_size,
|
||||
SerializeIF::Endianness streamEndianness) const {
|
||||
uint16_t i;
|
||||
ReturnValue_t result;
|
||||
for (i = 0; i < vectorSize; i++) {
|
||||
result = SerializeAdapter::serialize(&(value[i]), buffer, size,
|
||||
max_size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline size_t GlobPoolVector<T, vectorSize>::getSerializedSize() const {
|
||||
return vectorSize * SerializeAdapter::getSerializedSize(value);
|
||||
}
|
||||
|
||||
template<typename T, uint16_t vectorSize>
|
||||
inline ReturnValue_t GlobPoolVector<T, vectorSize>::deSerialize(
|
||||
const uint8_t** buffer, size_t* size,
|
||||
SerializeIF::Endianness streamEndianness) {
|
||||
uint16_t i;
|
||||
ReturnValue_t result;
|
||||
for (i = 0; i < vectorSize; i++) {
|
||||
result = SerializeAdapter::deSerialize(&(value[i]), buffer, size,
|
||||
streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,239 +0,0 @@
|
||||
#include <framework/datapoolglob/GlobalDataPool.h>
|
||||
#include <framework/datapoolglob/PoolRawAccess.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/serialize/EndianConverter.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry,
|
||||
DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode) :
|
||||
dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false),
|
||||
type(Type::UNKNOWN_TYPE), typeSize(0), arraySize(0), sizeTillEnd(0),
|
||||
readWriteMode(setReadWriteMode) {
|
||||
memset(value, 0, sizeof(value));
|
||||
if (dataSet != nullptr) {
|
||||
dataSet->registerVariable(this);
|
||||
}
|
||||
}
|
||||
|
||||
PoolRawAccess::~PoolRawAccess() {}
|
||||
|
||||
ReturnValue_t PoolRawAccess::read(uint32_t lockTimeout) {
|
||||
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = readWithoutLock();
|
||||
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
|
||||
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
|
||||
<< std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::readWithoutLock() {
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
PoolEntryIF* readOut = glob::dataPool.getRawData(dataPoolId);
|
||||
if (readOut != nullptr) {
|
||||
result = handleReadOut(readOut);
|
||||
if(result == RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
result = READ_ENTRY_NON_EXISTENT;
|
||||
}
|
||||
handleReadError(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::handleReadOut(PoolEntryIF* readOut) {
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
valid = readOut->getValid();
|
||||
if (readOut->getSize() > arrayEntry) {
|
||||
arraySize = readOut->getSize();
|
||||
typeSize = readOut->getByteSize() / readOut->getSize();
|
||||
type = readOut->getType();
|
||||
if (typeSize <= sizeof(value)) {
|
||||
uint16_t arrayPosition = arrayEntry * typeSize;
|
||||
sizeTillEnd = readOut->getByteSize() - arrayPosition;
|
||||
uint8_t* ptr = &((uint8_t*) readOut->getRawData())[arrayPosition];
|
||||
memcpy(value, ptr, typeSize);
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
result = READ_TYPE_TOO_LARGE;
|
||||
}
|
||||
} else {
|
||||
//debug << "PoolRawAccess: Size: " << (int)read_out->getSize() << std::endl;
|
||||
result = READ_INDEX_TOO_LARGE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PoolRawAccess::handleReadError(ReturnValue_t result) {
|
||||
sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId
|
||||
<< std::dec << " failed, ";
|
||||
if(result == READ_TYPE_TOO_LARGE) {
|
||||
sif::error << "type too large." << std::endl;
|
||||
}
|
||||
else if(result == READ_INDEX_TOO_LARGE) {
|
||||
sif::error << "index too large." << std::endl;
|
||||
}
|
||||
else if(result == READ_ENTRY_NON_EXISTENT) {
|
||||
sif::error << "entry does not exist." << std::endl;
|
||||
}
|
||||
|
||||
valid = INVALID;
|
||||
typeSize = 0;
|
||||
sizeTillEnd = 0;
|
||||
memset(value, 0, sizeof(value));
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::commit(uint32_t lockTimeout) {
|
||||
ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = commitWithoutLock();
|
||||
ReturnValue_t unlockResult = glob::dataPool.unlockDataPool();
|
||||
if(unlockResult != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "GlobPoolVar::read: Could not unlock global data pool"
|
||||
<< std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::commitWithoutLock() {
|
||||
PoolEntryIF* write_back = glob::dataPool.getRawData(dataPoolId);
|
||||
if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
|
||||
write_back->setValid(valid);
|
||||
uint8_t array_position = arrayEntry * typeSize;
|
||||
uint8_t* ptr = &((uint8_t*) write_back->getRawData())[array_position];
|
||||
memcpy(ptr, value, typeSize);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* PoolRawAccess::getEntry() {
|
||||
return value;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer,
|
||||
size_t* writtenBytes, size_t max_size) {
|
||||
uint8_t* data_ptr = getEntry();
|
||||
// debug << "PoolRawAccess::getEntry: Array position: " <<
|
||||
// index * size_of_type << " Size of T: " << (int)size_of_type <<
|
||||
// " ByteSize: " << byte_size << " Position: " << *size << std::endl;
|
||||
if (typeSize == 0)
|
||||
return DATA_POOL_ACCESS_FAILED;
|
||||
if (typeSize > max_size)
|
||||
return INCORRECT_SIZE;
|
||||
EndianConverter::convertBigEndian(buffer, data_ptr, typeSize);
|
||||
*writtenBytes = typeSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size,
|
||||
size_t maxSize, Endianness streamEndianness) const {
|
||||
if (typeSize + *size <= maxSize) {
|
||||
switch(streamEndianness) {
|
||||
case(Endianness::BIG):
|
||||
EndianConverter::convertBigEndian(*buffer, value, typeSize);
|
||||
break;
|
||||
case(Endianness::LITTLE):
|
||||
EndianConverter::convertLittleEndian(*buffer, value, typeSize);
|
||||
break;
|
||||
case(Endianness::MACHINE):
|
||||
default:
|
||||
memcpy(*buffer, value, typeSize);
|
||||
break;
|
||||
}
|
||||
*size += typeSize;
|
||||
(*buffer) += typeSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
return SerializeIF::BUFFER_TOO_SHORT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Type PoolRawAccess::getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
size_t PoolRawAccess::getSizeOfType() {
|
||||
return typeSize;
|
||||
}
|
||||
|
||||
size_t PoolRawAccess::getArraySize(){
|
||||
return arraySize;
|
||||
}
|
||||
|
||||
uint32_t PoolRawAccess::getDataPoolId() const {
|
||||
return dataPoolId;
|
||||
}
|
||||
|
||||
PoolVariableIF::ReadWriteMode_t PoolRawAccess::getReadWriteMode() const {
|
||||
return readWriteMode;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t *buffer,
|
||||
size_t setSize) {
|
||||
if (typeSize == setSize) {
|
||||
EndianConverter::convertBigEndian(value, buffer, typeSize);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
sif::error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: "
|
||||
"Internal" << (uint32_t) typeSize << ", Requested: " << setSize
|
||||
<< std::endl;
|
||||
return INCORRECT_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
bool PoolRawAccess::isValid() const {
|
||||
if (valid != INVALID)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void PoolRawAccess::setValid(bool valid) {
|
||||
this->valid = valid;
|
||||
}
|
||||
|
||||
size_t PoolRawAccess::getSizeTillEnd() const {
|
||||
return sizeTillEnd;
|
||||
}
|
||||
|
||||
|
||||
size_t PoolRawAccess::getSerializedSize() const {
|
||||
return typeSize;
|
||||
}
|
||||
|
||||
ReturnValue_t PoolRawAccess::deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) {
|
||||
|
||||
if (*size >= typeSize) {
|
||||
switch(streamEndianness) {
|
||||
case(Endianness::BIG):
|
||||
EndianConverter::convertBigEndian(value, *buffer, typeSize);
|
||||
break;
|
||||
case(Endianness::LITTLE):
|
||||
EndianConverter::convertLittleEndian(value, *buffer, typeSize);
|
||||
break;
|
||||
case(Endianness::MACHINE):
|
||||
default:
|
||||
memcpy(value, *buffer, typeSize);
|
||||
break;
|
||||
}
|
||||
*size -= typeSize;
|
||||
*buffer += typeSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
else {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
}
|
@ -1,220 +0,0 @@
|
||||
#ifndef POOLRAWACCESS_H_
|
||||
#define POOLRAWACCESS_H_
|
||||
|
||||
#include <framework/datapool/DataSetIF.h>
|
||||
#include <framework/datapool/PoolEntryIF.h>
|
||||
#include <framework/datapool/PoolVariableIF.h>
|
||||
#include <framework/globalfunctions/Type.h>
|
||||
|
||||
/**
|
||||
* @brief This class allows accessing Data Pool variables as raw bytes.
|
||||
* @details
|
||||
* This is necessary to have an access method for HK data, as the PID's alone
|
||||
* do not provide type information. Please note that the the raw pool access
|
||||
* read() and commit() calls are not thread-safe.
|
||||
*
|
||||
* Please supply a data set and use the data set read(), commit() calls for
|
||||
* thread-safe data pool access.
|
||||
* @ingroup data_pool
|
||||
*/
|
||||
class PoolRawAccess: public PoolVariableIF, HasReturnvaluesIF {
|
||||
public:
|
||||
/**
|
||||
* This constructor is used to access a data pool entry with a
|
||||
* given ID if the target type is not known. A DataSet object is supplied
|
||||
* and the data pool entry with the given ID is registered to that data set.
|
||||
* Please note that a pool raw access buffer only has a buffer
|
||||
* with a size of double. As such, for vector entries which have
|
||||
* @param data_pool_id Target data pool entry ID
|
||||
* @param arrayEntry
|
||||
* @param data_set Dataset to register data pool entry to
|
||||
* @param setReadWriteMode
|
||||
* @param registerVectors If set to true, the constructor checks if
|
||||
* there are multiple vector entries to registers
|
||||
* and registers all of them recursively into the data_set
|
||||
*
|
||||
*/
|
||||
PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry,
|
||||
DataSetIF* data_set, ReadWriteMode_t setReadWriteMode =
|
||||
PoolVariableIF::VAR_READ);
|
||||
|
||||
/**
|
||||
* @brief This operation returns a pointer to the entry fetched.
|
||||
* @details Return pointer to the buffer containing the raw data
|
||||
* Size and number of data can be retrieved by other means.
|
||||
*/
|
||||
uint8_t* getEntry();
|
||||
/**
|
||||
* @brief This operation returns the fetched entry from the data pool and
|
||||
* flips the bytes, if necessary.
|
||||
* @details It makes use of the getEntry call of this function, but additionally flips the
|
||||
* bytes to big endian, which is the default for external communication (as House-
|
||||
* keeping telemetry). To achieve this, the data is copied directly to the passed
|
||||
* buffer, if it fits in the given max_size.
|
||||
* @param buffer A pointer to a buffer to write to
|
||||
* @param writtenBytes The number of bytes written is returned with this value.
|
||||
* @param max_size The maximum size that the function may write to buffer.
|
||||
* @return - @c RETURN_OK if entry could be acquired
|
||||
* - @c RETURN_FAILED else.
|
||||
*/
|
||||
ReturnValue_t getEntryEndianSafe(uint8_t *buffer, size_t *size,
|
||||
size_t maxSize);
|
||||
|
||||
/**
|
||||
* @brief Serialize raw pool entry into provided buffer directly
|
||||
* @param buffer Provided buffer. Raw pool data will be copied here
|
||||
* @param size [out] Increment provided size value by serialized size
|
||||
* @param max_size Maximum allowed serialization size
|
||||
* @param bigEndian Specify endianess
|
||||
* @return - @c RETURN_OK if serialization was successfull
|
||||
* - @c SerializeIF::BUFFER_TOO_SHORT if range check failed
|
||||
*/
|
||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size,
|
||||
size_t maxSize, Endianness streamEndianness) const override;
|
||||
|
||||
size_t getSerializedSize() const override;
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
|
||||
Endianness streamEndianness) override;
|
||||
|
||||
/**
|
||||
* With this method, the content can be set from a big endian buffer safely.
|
||||
* @param buffer Pointer to the data to set
|
||||
* @param size Size of the data to write. Must fit this->size.
|
||||
* @return - @c RETURN_OK on success
|
||||
* - @c RETURN_FAILED on failure
|
||||
*/
|
||||
ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer,
|
||||
size_t setSize);
|
||||
/**
|
||||
* @brief This operation returns the type of the entry currently stored.
|
||||
*/
|
||||
Type getType();
|
||||
/**
|
||||
* @brief This operation returns the size of the entry currently stored.
|
||||
*/
|
||||
size_t getSizeOfType();
|
||||
/**
|
||||
*
|
||||
* @return the size of the datapool array
|
||||
*/
|
||||
size_t getArraySize();
|
||||
/**
|
||||
* @brief This operation returns the data pool id of the variable.
|
||||
*/
|
||||
uint32_t getDataPoolId() const;
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::POOL_RAW_ACCESS_CLASS;
|
||||
static const ReturnValue_t INCORRECT_SIZE = MAKE_RETURN_CODE(0x01);
|
||||
static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02);
|
||||
static const ReturnValue_t READ_TYPE_TOO_LARGE = MAKE_RETURN_CODE(0x03);
|
||||
static const ReturnValue_t READ_INDEX_TOO_LARGE = MAKE_RETURN_CODE(0x04);
|
||||
static const ReturnValue_t READ_ENTRY_NON_EXISTENT = MAKE_RETURN_CODE(0x05);
|
||||
static const uint8_t RAW_MAX_SIZE = sizeof(double);
|
||||
uint8_t value[RAW_MAX_SIZE];
|
||||
|
||||
|
||||
/**
|
||||
* @brief The classes destructor is empty. If commit() was not called, the local value is
|
||||
* discarded and not written back to the data pool.
|
||||
*/
|
||||
~PoolRawAccess();
|
||||
|
||||
/**
|
||||
* This method returns if the variable is read-write or read-only.
|
||||
*/
|
||||
ReadWriteMode_t getReadWriteMode() const;
|
||||
/**
|
||||
* @brief With this call, the valid information of the variable is returned.
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
void setValid(bool valid);
|
||||
/**
|
||||
* Getter for the remaining size.
|
||||
*/
|
||||
size_t getSizeTillEnd() const;
|
||||
|
||||
/**
|
||||
* @brief This is a call to read the value from the global data pool.
|
||||
* @details
|
||||
* When executed, this operation tries to fetch the pool entry with matching
|
||||
* data pool id from the global data pool and copies the value and the valid
|
||||
* information to its local attributes. In case of a failure (wrong type or
|
||||
* pool id not found), the variable is set to zero and invalid.
|
||||
* The call is protected by a lock of the global data pool.
|
||||
* @return -@c RETURN_OK Read successfull
|
||||
* -@c READ_TYPE_TOO_LARGE
|
||||
* -@c READ_INDEX_TOO_LARGE
|
||||
* -@c READ_ENTRY_NON_EXISTENT
|
||||
*/
|
||||
ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override;
|
||||
/**
|
||||
* @brief The commit call writes back the variable's value to the data pool.
|
||||
* @details
|
||||
* It checks type and size, as well as if the variable is writable. If so,
|
||||
* the value is copied and the valid flag is automatically set to "valid".
|
||||
* The call is protected by a lock of the global data pool.
|
||||
*
|
||||
*/
|
||||
ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Like #read, but without a lock protection of the global pool.
|
||||
* @details
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
* This can be used if the lock is handled externally to avoid the overhead
|
||||
* of consecutive lock und unlock operations.
|
||||
* Declared protected to discourage free public usage.
|
||||
*/
|
||||
ReturnValue_t readWithoutLock() override;
|
||||
/**
|
||||
* @brief Like #commit, but without a lock protection of the global pool.
|
||||
* @details
|
||||
* The operation does NOT provide any mutual exclusive protection by itself.
|
||||
* This can be used if the lock is handled externally to avoid the overhead
|
||||
* of consecutive lock und unlock operations.
|
||||
* Declared protected to discourage free public usage.
|
||||
*/
|
||||
ReturnValue_t commitWithoutLock() override;
|
||||
|
||||
ReturnValue_t handleReadOut(PoolEntryIF* read_out);
|
||||
void handleReadError(ReturnValue_t result);
|
||||
private:
|
||||
/**
|
||||
* @brief To access the correct data pool entry on read and commit calls, the data pool id
|
||||
* is stored.
|
||||
*/
|
||||
uint32_t dataPoolId;
|
||||
/**
|
||||
* @brief The array entry that is fetched from the data pool.
|
||||
*/
|
||||
uint8_t arrayEntry;
|
||||
/**
|
||||
* @brief The valid information as it was stored in the data pool is copied to this attribute.
|
||||
*/
|
||||
uint8_t valid;
|
||||
/**
|
||||
* @brief This value contains the type of the data pool entry.
|
||||
*/
|
||||
Type type;
|
||||
/**
|
||||
* @brief This value contains the size of the data pool entry type in bytes.
|
||||
*/
|
||||
size_t typeSize;
|
||||
/**
|
||||
* The size of the DP array (single values return 1)
|
||||
*/
|
||||
size_t arraySize;
|
||||
/**
|
||||
* The size (in bytes) from the selected entry till the end of this DataPool variable.
|
||||
*/
|
||||
size_t sizeTillEnd;
|
||||
/**
|
||||
* @brief The information whether the class is read-write or read-only is stored here.
|
||||
*/
|
||||
ReadWriteMode_t readWriteMode;
|
||||
};
|
||||
|
||||
#endif /* POOLRAWACCESS_H_ */
|
@ -1,77 +0,0 @@
|
||||
#ifndef FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_
|
||||
#define FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_
|
||||
#include <framework/datapool/PoolEntryIF.h>
|
||||
#include <framework/ipc/MessageQueueSenderIF.h>
|
||||
#include <framework/housekeeping/HousekeepingMessage.h>
|
||||
#include <map>
|
||||
|
||||
class LocalDataPoolManager;
|
||||
class DataSetIF;
|
||||
/**
|
||||
* @brief Type definition for local pool entries.
|
||||
*/
|
||||
using lp_id_t = uint32_t;
|
||||
using LocalDataPool = std::map<lp_id_t, PoolEntryIF*>;
|
||||
using LocalDataPoolMapIter = LocalDataPool::iterator;
|
||||
|
||||
/**
|
||||
* @brief This interface is implemented by classes which posses a local
|
||||
* data pool (not the managing class). It defines the relationship
|
||||
* between the local data pool owner and the LocalDataPoolManager.
|
||||
* @details
|
||||
* Any class implementing this interface shall also have a LocalDataPoolManager
|
||||
* member class which contains the actual pool data structure
|
||||
* and exposes the public interface for it.
|
||||
* This is required because the pool entries are templates, which makes
|
||||
* specifying an interface rather difficult. The local data pool can be
|
||||
* accessed by using the LocalPoolVariable, LocalPoolVector or LocalDataSet
|
||||
* classes.
|
||||
*
|
||||
* Architectural Note:
|
||||
* This could be circumvented by using a wrapper/accessor function or
|
||||
* implementing the templated function in this interface..
|
||||
* The first solution sounds better than the second but
|
||||
* the LocalPoolVariable classes are templates as well, so this just shifts
|
||||
* the problem somewhere else. Interfaces are nice, but the most
|
||||
* pragmatic solution I found was to offer the client the full interface
|
||||
* of the LocalDataPoolManager.
|
||||
*/
|
||||
class HasLocalDataPoolIF {
|
||||
public:
|
||||
virtual~ HasLocalDataPoolIF() {};
|
||||
|
||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF;
|
||||
|
||||
/** Command queue for housekeeping messages. */
|
||||
virtual MessageQueueId_t getCommandQueue() const = 0;
|
||||
|
||||
/** Is used by pool owner to initialize the pool map once */
|
||||
virtual ReturnValue_t initializePoolEntries(
|
||||
LocalDataPool& localDataPoolMap) = 0;
|
||||
|
||||
/** Can be used to get a handle to the local data pool manager. */
|
||||
virtual LocalDataPoolManager* getHkManagerHandle() = 0;
|
||||
|
||||
/**
|
||||
* This function is used by the pool manager to get a valid dataset
|
||||
* from a SID
|
||||
* @param sid Corresponding structure ID
|
||||
* @return
|
||||
*/
|
||||
virtual DataSetIF* getDataSetHandle(sid_t sid) = 0;
|
||||
|
||||
/* These function can be implemented by pool owner, as they are required
|
||||
* by the housekeeping message interface */
|
||||
virtual ReturnValue_t addDataSet(sid_t sid) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
};
|
||||
virtual ReturnValue_t removeDataSet(sid_t sid) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
};
|
||||
virtual ReturnValue_t changeCollectionInterval(sid_t sid,
|
||||
dur_seconds_t newInterval) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ */
|
@ -1,218 +0,0 @@
|
||||
#include <framework/datapoollocal/LocalDataPoolManager.h>
|
||||
#include <framework/datapoollocal/LocalDataSet.h>
|
||||
#include <framework/housekeeping/AcceptsHkPacketsIF.h>
|
||||
#include <framework/ipc/MutexFactory.h>
|
||||
#include <framework/ipc/MutexHelper.h>
|
||||
#include <framework/ipc/QueueFactory.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
|
||||
MessageQueueIF* queueToUse, bool appendValidityBuffer):
|
||||
appendValidityBuffer(appendValidityBuffer) {
|
||||
if(owner == nullptr) {
|
||||
sif::error << "HkManager: Invalid supplied owner!" << std::endl;
|
||||
return;
|
||||
}
|
||||
this->owner = owner;
|
||||
mutex = MutexFactory::instance()->createMutex();
|
||||
if(mutex == nullptr) {
|
||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
||||
"Could not create mutex." << std::endl;
|
||||
}
|
||||
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
if(ipcStore == nullptr) {
|
||||
sif::error << "LocalDataPoolManager::LocalDataPoolManager: "
|
||||
"Could not set IPC store." << std::endl;
|
||||
}
|
||||
hkQueue = queueToUse;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse,
|
||||
object_id_t hkDestination) {
|
||||
if(queueToUse == nullptr) {
|
||||
sif::error << "LocalDataPoolManager::initialize: Supplied queue "
|
||||
"invalid!" << std::endl;
|
||||
}
|
||||
hkQueue = queueToUse;
|
||||
|
||||
if(hkDestination == objects::NO_OBJECT) {
|
||||
return initializeHousekeepingPoolEntriesOnce();
|
||||
}
|
||||
|
||||
AcceptsHkPacketsIF* hkReceiver =
|
||||
objectManager->get<AcceptsHkPacketsIF>(hkDestination);
|
||||
if(hkReceiver != nullptr) {
|
||||
setHkPacketDestination(hkReceiver->getHkQueue());
|
||||
}
|
||||
else {
|
||||
sif::warning << "LocalDataPoolManager::initialize: Could not retrieve"
|
||||
" queue ID from HK destination object ID. " << std::flush;
|
||||
sif::warning << "Make sure it exists and the object impements "
|
||||
"AcceptsHkPacketsIF!" << std::endl;
|
||||
}
|
||||
return initializeHousekeepingPoolEntriesOnce();
|
||||
}
|
||||
|
||||
void LocalDataPoolManager::setHkPacketDestination(
|
||||
MessageQueueId_t hkDestination) {
|
||||
this->hkDestination = hkDestination;
|
||||
}
|
||||
|
||||
LocalDataPoolManager::~LocalDataPoolManager() {}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
|
||||
if(not mapInitialized) {
|
||||
ReturnValue_t result = owner->initializePoolEntries(localPoolMap);
|
||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
||||
mapInitialized = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
sif::warning << "HousekeepingManager: The map should only be initialized "
|
||||
"once!" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage(
|
||||
CommandMessage* message) {
|
||||
Command_t command = message->getCommand();
|
||||
switch(command) {
|
||||
// I think those are the only commands which can be handled here..
|
||||
case(HousekeepingMessage::ADD_HK_REPORT_STRUCT):
|
||||
case(HousekeepingMessage::ADD_DIAGNOSTICS_REPORT_STRUCT):
|
||||
// We should use OwnsLocalPoolDataIF to specify those functions..
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES):
|
||||
case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES):
|
||||
//return generateSetStructurePacket(message->getSid());
|
||||
case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT):
|
||||
case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT):
|
||||
//return generateHousekeepingPacket(message->getSid());
|
||||
default:
|
||||
return CommandMessageIF::UNKNOWN_COMMAND;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::printPoolEntry(
|
||||
lp_id_t localPoolId) {
|
||||
auto poolIter = localPoolMap.find(localPoolId);
|
||||
if (poolIter == localPoolMap.end()) {
|
||||
sif::debug << "HousekeepingManager::fechPoolEntry:"
|
||||
" Pool entry not found." << std::endl;
|
||||
return POOL_ENTRY_NOT_FOUND;
|
||||
}
|
||||
poolIter->second->print();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
MutexIF* LocalDataPoolManager::getMutexHandle() {
|
||||
return mutex;
|
||||
}
|
||||
|
||||
const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const {
|
||||
return owner;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
||||
MessageQueueId_t sendTo) {
|
||||
LocalDataSet* dataSetToSerialize = dynamic_cast<LocalDataSet*>(
|
||||
owner->getDataSetHandle(sid));
|
||||
if(dataSetToSerialize == nullptr) {
|
||||
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
||||
" Set ID not found" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
store_address_t storeId;
|
||||
ReturnValue_t result = serializeHkPacketIntoStore(&storeId,
|
||||
dataSetToSerialize);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// and now we set a HK message and send it the HK packet destination.
|
||||
CommandMessage hkMessage;
|
||||
HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId);
|
||||
if(hkQueue == nullptr) {
|
||||
return QUEUE_OR_DESTINATION_NOT_SET;
|
||||
}
|
||||
|
||||
if(sendTo != MessageQueueIF::NO_QUEUE) {
|
||||
result = hkQueue->sendMessage(sendTo, &hkMessage);
|
||||
}
|
||||
else {
|
||||
if(hkDestination == MessageQueueIF::NO_QUEUE) {
|
||||
sif::warning << "LocalDataPoolManager::generateHousekeepingPacket:"
|
||||
" Destination is not set properly!" << std::endl;
|
||||
return QUEUE_OR_DESTINATION_NOT_SET;
|
||||
}
|
||||
else {
|
||||
result = hkQueue->sendMessage(hkDestination, &hkMessage);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) {
|
||||
LocalDataSet* dataSet = dynamic_cast<LocalDataSet*>(
|
||||
owner->getDataSetHandle(sid));
|
||||
if(dataSet == nullptr) {
|
||||
sif::warning << "HousekeepingManager::generateHousekeepingPacket:"
|
||||
" Set ID not found" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
size_t expectedSize = dataSet->getFillCount() * sizeof(lp_id_t);
|
||||
uint8_t* storePtr = nullptr;
|
||||
store_address_t storeId;
|
||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId,
|
||||
expectedSize,&storePtr);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "HousekeepingManager::generateHousekeepingPacket: "
|
||||
"Could not get free element from IPC store." << std::endl;
|
||||
return result;
|
||||
}
|
||||
size_t size = 0;
|
||||
result = dataSet->serializeLocalPoolIds(&storePtr, &size,
|
||||
expectedSize, SerializeIF::Endianness::BIG);
|
||||
if(expectedSize != size) {
|
||||
sif::error << "HousekeepingManager::generateSetStructurePacket: "
|
||||
"Expected size is not equal to serialized size" << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LocalDataPoolManager::setMinimalSamplingFrequency(float frequencySeconds) {
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore(
|
||||
store_address_t *storeId, LocalDataSet* dataSet) {
|
||||
size_t hkSize = dataSet->getSerializedSize();
|
||||
uint8_t* storePtr = nullptr;
|
||||
ReturnValue_t result = ipcStore->getFreeElement(storeId, hkSize,&storePtr);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "HousekeepingManager::generateHousekeepingPacket: "
|
||||
"Could not get free element from IPC store." << std::endl;
|
||||
return result;
|
||||
}
|
||||
size_t size = 0;
|
||||
|
||||
if(appendValidityBuffer) {
|
||||
result = dataSet->serializeWithValidityBuffer(&storePtr,
|
||||
&size, hkSize, SerializeIF::Endianness::MACHINE);
|
||||
}
|
||||
else {
|
||||
result = dataSet->serialize(&storePtr, &size, hkSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
}
|
||||
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "HousekeepingManager::serializeHkPacketIntoStore: "
|
||||
"Serialization proccess failed!" << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataPoolManager::performHkOperation() {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
@ -1,229 +0,0 @@
|
||||
#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
||||
#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_
|
||||
|
||||
#include <framework/datapool/DataSetIF.h>
|
||||
#include <framework/objectmanager/SystemObjectIF.h>
|
||||
#include <framework/ipc/MutexIF.h>
|
||||
|
||||
#include <framework/housekeeping/HousekeepingMessage.h>
|
||||
#include <framework/datapool/PoolEntry.h>
|
||||
#include <framework/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <framework/ipc/CommandMessage.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
#include <framework/ipc/MutexHelper.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
class LocalDataSet;
|
||||
|
||||
/**
|
||||
* @brief This class is the managing instance for local data pool.
|
||||
* @details
|
||||
* The actual data pool structure is a member of this class. Any class which
|
||||
* has a local data pool shall have this class as a member and implement
|
||||
* the HasLocalDataPoolIF.
|
||||
*
|
||||
* Users of the data pool use the helper classes LocalDataSet,
|
||||
* LocalPoolVariable and LocalPoolVector to access pool entries in
|
||||
* a thread-safe and efficient way.
|
||||
*
|
||||
* The local data pools employ a blackboard logic: Only the most recent
|
||||
* value is stored. The helper classes offer a read() and commit() interface
|
||||
* through the PoolVariableIF which is used to read and update values.
|
||||
* Each pool entry has a valid state too.
|
||||
*
|
||||
*/
|
||||
class LocalDataPoolManager {
|
||||
template<typename T>
|
||||
friend class LocalPoolVar;
|
||||
template<typename T, uint16_t vecSize>
|
||||
friend class LocalPoolVector;
|
||||
friend class LocalDataSet;
|
||||
public:
|
||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER;
|
||||
|
||||
static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x0);
|
||||
static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x1);
|
||||
|
||||
static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x2);
|
||||
//static constexpr ReturnValue_t SET_NOT_FOUND = MAKE_RETURN_CODE(0x3);
|
||||
|
||||
/**
|
||||
* This constructor is used by a class which wants to implement
|
||||
* a personal local data pool. The queueToUse can be supplied if it
|
||||
* is already known.
|
||||
*
|
||||
* initialize() has to be called in any case before using the object!
|
||||
* @param owner
|
||||
* @param queueToUse
|
||||
* @param appendValidityBuffer
|
||||
*/
|
||||
LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
||||
bool appendValidityBuffer = true);
|
||||
virtual~ LocalDataPoolManager();
|
||||
|
||||
/**
|
||||
* Initializes the map by calling the map initialization function of the
|
||||
* owner and assigns the queue to use.
|
||||
* @param queueToUse
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t initialize(MessageQueueIF* queueToUse,
|
||||
object_id_t hkDestination);
|
||||
|
||||
/**
|
||||
* This should be called in the periodic handler of the owner.
|
||||
* It performs all the periodic functionalities of the data pool manager.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t performHkOperation();
|
||||
/**
|
||||
* This function is used to set the default HK packet destination.
|
||||
* This destination will usually only be set once.
|
||||
* @param hkDestination
|
||||
*/
|
||||
void setHkPacketDestination(MessageQueueId_t hkDestination);
|
||||
|
||||
/**
|
||||
* Generate a housekeeping packet with a given SID.
|
||||
* @param sid
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t generateHousekeepingPacket(sid_t sid, MessageQueueId_t sendTo
|
||||
= MessageQueueIF::NO_QUEUE);
|
||||
ReturnValue_t generateSetStructurePacket(sid_t sid);
|
||||
|
||||
ReturnValue_t handleHousekeepingMessage(CommandMessage* message);
|
||||
|
||||
/**
|
||||
* This function is used to fill the local data pool map with pool
|
||||
* entries. It should only be called once by the pool owner.
|
||||
* @param localDataPoolMap
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t initializeHousekeepingPoolEntriesOnce();
|
||||
|
||||
const HasLocalDataPoolIF* getOwner() const;
|
||||
|
||||
ReturnValue_t printPoolEntry(lp_id_t localPoolId);
|
||||
|
||||
/**
|
||||
* Different types of housekeeping reporting are possible.
|
||||
* 1. PERIODIC: HK packets are generated in fixed intervals
|
||||
* 2. UPDATED: HK packets are generated if a value was updated
|
||||
* 3. REQUESTED: HK packets are only generated if explicitely requested
|
||||
*/
|
||||
enum class ReportingType: uint8_t {
|
||||
PERIODIC,
|
||||
ON_UPDATE,
|
||||
REQUESTED
|
||||
};
|
||||
|
||||
/* Copying forbidden */
|
||||
LocalDataPoolManager(const LocalDataPoolManager &) = delete;
|
||||
LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete;
|
||||
|
||||
private:
|
||||
LocalDataPool localPoolMap;
|
||||
/** Every housekeeping data manager has a mutex to protect access
|
||||
* to it's data pool. */
|
||||
MutexIF* mutex = nullptr;
|
||||
/** The class which actually owns the manager (and its datapool). */
|
||||
HasLocalDataPoolIF* owner = nullptr;
|
||||
|
||||
/**
|
||||
* The data pool manager will keep an internal map of HK receivers.
|
||||
*/
|
||||
struct HkReceiver {
|
||||
LocalDataSet* dataSet = nullptr;
|
||||
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
|
||||
ReportingType reportingType = ReportingType::PERIODIC;
|
||||
bool reportingStatus = true;
|
||||
/** Different members of this union will be used depending on reporting
|
||||
* type */
|
||||
union hkParameter {
|
||||
/** This parameter will be used for the PERIODIC type */
|
||||
dur_seconds_t collectionInterval = 0;
|
||||
/** This parameter will be used for the ON_UPDATE type */
|
||||
bool hkDataChanged;
|
||||
};
|
||||
};
|
||||
|
||||
/** Using a multimap as the same object might request multiple datasets */
|
||||
using HkReceiversMap = std::multimap<object_id_t, struct HkReceiver>;
|
||||
|
||||
HkReceiversMap hkReceiversMap;
|
||||
|
||||
/** This is the map holding the actual data. Should only be initialized
|
||||
* once ! */
|
||||
bool mapInitialized = false;
|
||||
/** This specifies whether a validity buffer is appended at the end
|
||||
* of generated housekeeping packets. */
|
||||
bool appendValidityBuffer = true;
|
||||
|
||||
/**
|
||||
* @brief Queue used for communication, for example commands.
|
||||
* Is also used to send messages. Can be set either in the constructor
|
||||
* or in the initialize() function.
|
||||
*/
|
||||
MessageQueueIF* hkQueue = nullptr;
|
||||
|
||||
/**
|
||||
* HK replies will always be a reply to the commander, but HK packet
|
||||
* can be sent to another destination by specifying this message queue
|
||||
* ID, for example to a dedicated housekeeping service implementation.
|
||||
*/
|
||||
MessageQueueId_t hkDestination = MessageQueueIF::NO_QUEUE;
|
||||
|
||||
/** Global IPC store is used to store all packets. */
|
||||
StorageManagerIF* ipcStore = nullptr;
|
||||
/**
|
||||
* Get the pointer to the mutex. Can be used to lock the data pool
|
||||
* eternally. Use with care and don't forget to unlock locked mutexes!
|
||||
* For now, only friend classes can accss this function.
|
||||
* @return
|
||||
*/
|
||||
MutexIF* getMutexHandle();
|
||||
|
||||
/**
|
||||
* Read a variable by supplying its local pool ID and assign the pool
|
||||
* entry to the supplied PoolEntry pointer. The type of the pool entry
|
||||
* is deduced automatically. This call is not thread-safe!
|
||||
* For now, only friend classes like LocalPoolVar may access this
|
||||
* function.
|
||||
* @tparam T Type of the pool entry
|
||||
* @param localPoolId Pool ID of the variable to read
|
||||
* @param poolVar [out] Corresponding pool entry will be assigned to the
|
||||
* supplied pointer.
|
||||
* @return
|
||||
*/
|
||||
template <class T> ReturnValue_t fetchPoolEntry(lp_id_t localPoolId,
|
||||
PoolEntry<T> **poolEntry);
|
||||
|
||||
void setMinimalSamplingFrequency(float frequencySeconds);
|
||||
ReturnValue_t serializeHkPacketIntoStore(store_address_t* storeId,
|
||||
LocalDataSet* dataSet);
|
||||
};
|
||||
|
||||
|
||||
template<class T> inline
|
||||
ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
|
||||
PoolEntry<T> **poolEntry) {
|
||||
auto poolIter = localPoolMap.find(localPoolId);
|
||||
if (poolIter == localPoolMap.end()) {
|
||||
sif::warning << "HousekeepingManager::fechPoolEntry: Pool entry "
|
||||
"not found." << std::endl;
|
||||
return POOL_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
*poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second);
|
||||
if(*poolEntry == nullptr) {
|
||||
sif::debug << "HousekeepingManager::fetchPoolEntry:"
|
||||
" Pool entry not found." << std::endl;
|
||||
return POOL_ENTRY_TYPE_CONFLICT;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ */
|
@ -1,106 +0,0 @@
|
||||
#include <framework/datapoollocal/LocalDataPoolManager.h>
|
||||
#include <framework/datapoollocal/LocalDataSet.h>
|
||||
#include <framework/serialize/SerializeAdapter.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner,
|
||||
const size_t maxNumberOfVariables):
|
||||
DataSetBase(poolVarList.data(), maxNumberOfVariables) {
|
||||
poolVarList.reserve(maxNumberOfVariables);
|
||||
poolVarList.resize(maxNumberOfVariables);
|
||||
if(hkOwner == nullptr) {
|
||||
sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
hkManager = hkOwner->getHkManagerHandle();
|
||||
}
|
||||
|
||||
LocalDataSet::LocalDataSet(object_id_t ownerId,
|
||||
const size_t maxNumberOfVariables):
|
||||
DataSetBase(poolVarList.data(), maxNumberOfVariables) {
|
||||
poolVarList.reserve(maxNumberOfVariables);
|
||||
poolVarList.resize(maxNumberOfVariables);
|
||||
HasLocalDataPoolIF* hkOwner = objectManager->get<HasLocalDataPoolIF>(
|
||||
ownerId);
|
||||
if(hkOwner == nullptr) {
|
||||
sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
hkManager = hkOwner->getHkManagerHandle();
|
||||
}
|
||||
|
||||
LocalDataSet::~LocalDataSet() {
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataSet::lockDataPool(uint32_t timeoutMs) {
|
||||
MutexIF* mutex = hkManager->getMutexHandle();
|
||||
return mutex->lockMutex(timeoutMs);
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer,
|
||||
size_t *size, size_t maxSize,
|
||||
SerializeIF::Endianness streamEndianness) const {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
||||
uint8_t validityMaskSize = std::ceil(static_cast<float>(fillCount)/8.0);
|
||||
uint8_t validityMask[validityMaskSize];
|
||||
uint8_t validBufferIndex = 0;
|
||||
uint8_t validBufferIndexBit = 0;
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
if(registeredVariables[count]->isValid()) {
|
||||
// set validity buffer here.
|
||||
this->bitSetter(validityMask + validBufferIndex,
|
||||
validBufferIndexBit);
|
||||
if(validBufferIndexBit == 7) {
|
||||
validBufferIndex ++;
|
||||
validBufferIndexBit = 0;
|
||||
}
|
||||
else {
|
||||
validBufferIndexBit ++;
|
||||
}
|
||||
}
|
||||
result = registeredVariables[count]->serialize(buffer, size, maxSize,
|
||||
streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// copy validity buffer to end
|
||||
std::memcpy(*buffer, validityMask, validityMaskSize);
|
||||
*size += validityMaskSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataSet::unlockDataPool() {
|
||||
MutexIF* mutex = hkManager->getMutexHandle();
|
||||
return mutex->unlockMutex();
|
||||
}
|
||||
|
||||
ReturnValue_t LocalDataSet::serializeLocalPoolIds(uint8_t** buffer,
|
||||
size_t* size, size_t maxSize,
|
||||
SerializeIF::Endianness streamEndianness) const {
|
||||
for (uint16_t count = 0; count < fillCount; count++) {
|
||||
lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId();
|
||||
auto result = SerializeAdapter::serialize(¤tPoolId, buffer,
|
||||
size, maxSize, streamEndianness);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "LocalDataSet::serializeLocalPoolIds: Serialization"
|
||||
" error!" << std::endl;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void LocalDataSet::bitSetter(uint8_t* byte, uint8_t position) const {
|
||||
if(position > 7) {
|
||||
sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl;
|
||||
return;
|
||||
}
|
||||
uint8_t shiftNumber = position + (7 - 2 * position);
|
||||
*byte |= 1 << shiftNumber;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user