updating code from Flying Laptop
This is the framework of Flying Laptop OBSW version A.13.0.
This commit is contained in:
parent
1d22a6c97e
commit
575f70ba03
202
LICENSE
Normal file
202
LICENSE
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
21
NOTICE
Normal file
21
NOTICE
Normal file
@ -0,0 +1,21 @@
|
||||
Flight Software Framework
|
||||
|
||||
The initial version of the Flight Software Framework was developed during
|
||||
the Flying Laptop Project by the Universität Stuttgart in coorporation
|
||||
with Airbus Defence and Space GmbH.
|
||||
|
||||
Copyrights in the Flight Software Framework are retained by their contributors.
|
||||
No copyright assignment is required to contribute to the Flight Software Framework.
|
||||
|
||||
Some files include explicit copyright notices and/or license notices.
|
||||
For full authorship information, see the version control history.
|
||||
|
||||
Except as otherwise noted (below and/or in individual files), the
|
||||
Flight Software Framework is licensed under the Apache License, Version 2.0.
|
||||
|
||||
The Flight Software Framework includes modules written by third parties.
|
||||
The following third party modules are included, and carry
|
||||
their own copyright notices and license terms:
|
||||
|
||||
under contrib/:
|
||||
* sgp4: sgp4 code developed by david vallado under public domain, see https://www.celestrak.com/publications/AIAA/2006-6753/
|
5
THANKYOU
5
THANKYOU
@ -1,5 +0,0 @@
|
||||
Besides Bastian Bätz and Ulrich Mohr, who were the main developers for Flying Laptop's Onboard Software, the following PhD Students contributed to the project:
|
||||
|
||||
Rouven Witt, who developed the FDIR concept and kept morale high as the team's Spaßbeauftragter.
|
||||
Marek Dittmar, who started work on the ACS code and later tried to keep the development in time.
|
||||
Nico Bucher, who performed software tests and as such was invaluable during the development.
|
@ -1,8 +1,7 @@
|
||||
|
||||
#include <framework/action/ActionHelper.h>
|
||||
#include <framework/action/HasActionsIF.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueue* useThisQueue) :
|
||||
ActionHelper::ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue) :
|
||||
owner(setOwner), queueToUse(useThisQueue), ipcStore(
|
||||
NULL) {
|
||||
}
|
||||
@ -41,6 +40,10 @@ void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, Retur
|
||||
queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
|
||||
void ActionHelper::setQueueToUse(MessageQueueIF* queue) {
|
||||
queueToUse = queue;
|
||||
}
|
||||
|
||||
void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId,
|
||||
store_address_t dataAddress) {
|
||||
const uint8_t* dataPtr = NULL;
|
||||
@ -62,31 +65,38 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act
|
||||
}
|
||||
}
|
||||
|
||||
void ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data) {
|
||||
ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender) {
|
||||
CommandMessage reply;
|
||||
store_address_t storeAddress;
|
||||
uint8_t *dataPtr;
|
||||
uint32_t maxSize = data->getSerializedSize();
|
||||
if (maxSize == 0) {
|
||||
return;
|
||||
//No error, there's simply nothing to report.
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
uint32_t size = 0;
|
||||
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize,
|
||||
&dataPtr);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
//TODO event?
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
result = data->serialize(&dataPtr, &size, maxSize, true);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
ipcStore->deleteData(storeAddress);
|
||||
//TODO event?
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
//We don't need to report the objectId, as we receive REQUESTED data before the completion success message.
|
||||
//True aperiodic replies need to be reported with another dedicated message.
|
||||
ActionMessage::setDataReply(&reply, replyId, storeAddress);
|
||||
if (queueToUse->sendMessage(reportTo, &reply) != HasReturnvaluesIF::RETURN_OK){
|
||||
|
||||
//TODO Service Implementation sucks at the moment
|
||||
if (hideSender){
|
||||
result = MessageQueueSenderIF::sendMessage(reportTo, &reply);
|
||||
} else {
|
||||
result = queueToUse->sendMessage(reportTo, &reply);
|
||||
}
|
||||
if ( result != HasReturnvaluesIF::RETURN_OK){
|
||||
ipcStore->deleteData(storeAddress);
|
||||
}
|
||||
//We don't neeed the objectId, as we receive REQUESTED data before the completion success message.
|
||||
//True aperiodic replies need to be reported with dedicated DH message.
|
||||
return result;
|
||||
}
|
||||
|
@ -1,25 +1,26 @@
|
||||
|
||||
#ifndef ACTIONHELPER_H_
|
||||
#define ACTIONHELPER_H_
|
||||
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/serialize/SerializeIF.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
|
||||
class HasActionsIF;
|
||||
//TODO: Change MessageQueueId usage.
|
||||
|
||||
class ActionHelper {
|
||||
public:
|
||||
ActionHelper(HasActionsIF* setOwner, MessageQueue* useThisQueue);
|
||||
ActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
virtual ~ActionHelper();
|
||||
ReturnValue_t handleActionMessage(CommandMessage* command);
|
||||
ReturnValue_t initialize();
|
||||
void step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data);
|
||||
ReturnValue_t reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender = false);
|
||||
void setQueueToUse(MessageQueueIF *queue);
|
||||
protected:
|
||||
static const uint8_t STEP_OFFSET = 1;
|
||||
HasActionsIF* owner;
|
||||
MessageQueue* queueToUse;
|
||||
MessageQueueIF* queueToUse;
|
||||
StorageManagerIF* ipcStore;
|
||||
virtual void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress);
|
||||
void resetHelper();
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#ifndef ACTIONMESSAGE_H_
|
||||
#define ACTIONMESSAGE_H_
|
||||
|
||||
@ -11,7 +10,7 @@ class ActionMessage {
|
||||
private:
|
||||
ActionMessage();
|
||||
public:
|
||||
static const uint8_t MESSAGE_ID = FUNCTION_MESSAGE_ID;
|
||||
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,4 +1,3 @@
|
||||
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/action/CommandActionHelper.h>
|
||||
#include <framework/action/CommandsActionsIF.h>
|
||||
|
@ -1,13 +1,12 @@
|
||||
|
||||
#ifndef COMMANDACTIONHELPER_H_
|
||||
#define COMMANDACTIONHELPER_H_
|
||||
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/ipc/MessageQueue.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>
|
||||
|
||||
class CommandsActionsIF;
|
||||
|
||||
@ -25,7 +24,7 @@ public:
|
||||
uint8_t getCommandCount() const;
|
||||
private:
|
||||
CommandsActionsIF* owner;
|
||||
MessageQueue* queueToUse;
|
||||
MessageQueueIF* queueToUse;
|
||||
StorageManagerIF* ipcStore;
|
||||
uint8_t commandCount;
|
||||
MessageQueueId_t lastTarget;
|
||||
|
@ -1,10 +1,9 @@
|
||||
|
||||
#ifndef COMMANDSACTIONSIF_H_
|
||||
#define COMMANDSACTIONSIF_H_
|
||||
|
||||
#include <framework/action/CommandActionHelper.h>
|
||||
#include <framework/ipc/MessageQueue.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
|
||||
/**
|
||||
* Interface to separate commanding actions of other objects.
|
||||
@ -18,11 +17,11 @@
|
||||
class CommandsActionsIF {
|
||||
friend class CommandActionHelper;
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = COMMANDS_ACTIONS_IF;
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::COMMANDS_ACTIONS_IF;
|
||||
static const ReturnValue_t OBJECT_HAS_NO_FUNCTIONS = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t ALREADY_COMMANDING = MAKE_RETURN_CODE(2);
|
||||
virtual ~CommandsActionsIF() {}
|
||||
virtual MessageQueue* getCommandQueuePtr() = 0;
|
||||
virtual MessageQueueIF* getCommandQueuePtr() = 0;
|
||||
protected:
|
||||
virtual void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) = 0;
|
||||
virtual void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) = 0;
|
||||
|
@ -1,21 +1,14 @@
|
||||
/*
|
||||
* HasActionsIF.h
|
||||
*
|
||||
* Created on: 20.02.2014
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef HASACTIONSIF_H_
|
||||
#define HASACTIONSIF_H_
|
||||
|
||||
#include <framework/action/ActionHelper.h>
|
||||
#include <framework/action/ActionMessage.h>
|
||||
#include <framework/action/SimpleActionHelper.h>
|
||||
#include <framework/ipc/MessageQueue.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/ipc/MessageQueueIF.h>
|
||||
class HasActionsIF {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = HAS_ACTIONS_IF;
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF;
|
||||
static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2);
|
||||
static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3);
|
||||
|
@ -1,8 +1,7 @@
|
||||
|
||||
#include <framework/action/HasActionsIF.h>
|
||||
#include <framework/action/SimpleActionHelper.h>
|
||||
SimpleActionHelper::SimpleActionHelper(HasActionsIF* setOwner,
|
||||
MessageQueue* useThisQueue) :
|
||||
MessageQueueIF* useThisQueue) :
|
||||
ActionHelper(setOwner, useThisQueue), isExecuting(false), lastCommander(
|
||||
0), lastAction(0), stepCount(0) {
|
||||
}
|
||||
@ -24,8 +23,8 @@ void SimpleActionHelper::finish(ReturnValue_t result) {
|
||||
resetHelper();
|
||||
}
|
||||
|
||||
void SimpleActionHelper::reportData(SerializeIF* data) {
|
||||
ActionHelper::reportData(lastCommander, lastAction, data);
|
||||
ReturnValue_t SimpleActionHelper::reportData(SerializeIF* data) {
|
||||
return ActionHelper::reportData(lastCommander, lastAction, data);
|
||||
}
|
||||
|
||||
void SimpleActionHelper::resetHelper() {
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#ifndef SIMPLEACTIONHELPER_H_
|
||||
#define SIMPLEACTIONHELPER_H_
|
||||
|
||||
@ -6,11 +5,11 @@
|
||||
|
||||
class SimpleActionHelper: public ActionHelper {
|
||||
public:
|
||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueue* useThisQueue);
|
||||
SimpleActionHelper(HasActionsIF* setOwner, MessageQueueIF* useThisQueue);
|
||||
virtual ~SimpleActionHelper();
|
||||
void step(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void finish(ReturnValue_t result = HasReturnvaluesIF::RETURN_OK);
|
||||
void reportData(SerializeIF* data);
|
||||
ReturnValue_t reportData(SerializeIF* data);
|
||||
void resetHelper();
|
||||
protected:
|
||||
void prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress);
|
||||
|
@ -17,7 +17,7 @@ template<typename T, typename count_t = uint8_t>
|
||||
class ArrayList {
|
||||
template<typename U, typename count> friend class SerialArrayListAdapter;
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = ARRAY_LIST;
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST;
|
||||
static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01);
|
||||
|
||||
/**
|
||||
@ -80,13 +80,17 @@ public:
|
||||
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) {
|
||||
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) {
|
||||
bool operator!=(const typename ArrayList<T, count_t>::Iterator& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
}
|
||||
@ -116,9 +120,10 @@ public:
|
||||
*
|
||||
* @param storage the array to use as backend
|
||||
* @param maxSize size of storage
|
||||
* @param size size of data already present in storage
|
||||
*/
|
||||
ArrayList(T *storage, count_t maxSize) :
|
||||
size(0), entries(storage), maxSize_(maxSize), allocated(false) {
|
||||
ArrayList(T *storage, count_t maxSize, count_t size = 0) :
|
||||
size(size), entries(storage), maxSize_(maxSize), allocated(false) {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,6 +175,12 @@ public:
|
||||
*/
|
||||
T *back() {
|
||||
return &entries[size - 1];
|
||||
//Alternative solution
|
||||
//return const_cast<T*>(static_cast<const T*>(*this).back());
|
||||
}
|
||||
|
||||
const T* back() const{
|
||||
return &entries[size-1];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -212,11 +223,6 @@ public:
|
||||
count_t remaining() {
|
||||
return (maxSize_ - size);
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
* pointer to the array in which the entries are stored
|
||||
*/
|
||||
T *entries;
|
||||
private:
|
||||
/**
|
||||
* This is the copy constructor
|
||||
@ -230,7 +236,11 @@ private:
|
||||
size(other.size), entries(other.entries), maxSize_(other.maxSize_), allocated(
|
||||
false) {
|
||||
}
|
||||
private:
|
||||
protected:
|
||||
/**
|
||||
* pointer to the array in which the entries are stored
|
||||
*/
|
||||
T *entries;
|
||||
/**
|
||||
* remembering the maximum size
|
||||
*/
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* BinaryTree.h
|
||||
*
|
||||
* Created on: 09.03.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_CONTAINER_BINARYTREE_H_
|
||||
#define FRAMEWORK_CONTAINER_BINARYTREE_H_
|
||||
|
||||
@ -99,9 +92,6 @@ public:
|
||||
}
|
||||
iterator insert(bool insertLeft, iterator parentNode, Node* newNode ) {
|
||||
newNode->parent = parentNode.element;
|
||||
//TODO: Why do I delete the child references of the node? This kills reconnection :-p
|
||||
// newNode->left = NULL;
|
||||
// newNode->right = NULL;
|
||||
if (parentNode.element != NULL) {
|
||||
if (insertLeft) {
|
||||
parentNode.element->left = newNode;
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
}
|
||||
static const uint8_t INTERFACE_ID = FIFO_CLASS;
|
||||
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);
|
||||
};
|
||||
|
@ -9,7 +9,7 @@
|
||||
template<typename key_t, typename T>
|
||||
class FixedMap: public SerializeIF {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = FIXED_MAP;
|
||||
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,10 +1,3 @@
|
||||
/*
|
||||
* FixedOrderedMultimap.h
|
||||
*
|
||||
* Created on: 22.01.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
||||
#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_H_
|
||||
|
||||
@ -15,7 +8,7 @@
|
||||
template<typename key_t, typename T, typename KEY_COMPARE = std::less<key_t>>
|
||||
class FixedOrderedMultimap {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = FIXED_MAP;
|
||||
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);
|
||||
|
700
container/IndexedRingMemoryArray.h
Normal file
700
container/IndexedRingMemoryArray.h
Normal file
@ -0,0 +1,700 @@
|
||||
#ifndef FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_
|
||||
#define FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_
|
||||
|
||||
#include <framework/container/ArrayList.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/serialize/SerialArrayListAdapter.h>
|
||||
#include <framework/globalfunctions/crc_ccitt.h>
|
||||
#include <cmath>
|
||||
|
||||
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");
|
||||
public:
|
||||
Index():blockStartAddress(0),size(0),storedPackets(0){}
|
||||
|
||||
Index(uint32_t startAddress):blockStartAddress(startAddress),size(0),storedPackets(0){
|
||||
|
||||
}
|
||||
|
||||
void setBlockStartAddress(uint32_t newAddress){
|
||||
this->blockStartAddress = newAddress;
|
||||
}
|
||||
|
||||
uint32_t getBlockStartAddress() const {
|
||||
return blockStartAddress;
|
||||
}
|
||||
|
||||
const T* getIndexType() const {
|
||||
return &indexType;
|
||||
}
|
||||
|
||||
T* modifyIndexType(){
|
||||
return &indexType;
|
||||
}
|
||||
/**
|
||||
* Updates the index Type. Uses = operator
|
||||
* @param indexType Type to copy from
|
||||
*/
|
||||
void setIndexType(T* indexType) {
|
||||
this->indexType = *indexType;
|
||||
}
|
||||
|
||||
uint32_t getSize() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
void setSize(uint32_t size) {
|
||||
this->size = size;
|
||||
}
|
||||
|
||||
void addSize(uint32_t size){
|
||||
this->size += size;
|
||||
}
|
||||
|
||||
void setStoredPackets(uint32_t newStoredPackets){
|
||||
this->storedPackets = newStoredPackets;
|
||||
}
|
||||
|
||||
void addStoredPackets(uint32_t packets){
|
||||
this->storedPackets += packets;
|
||||
}
|
||||
|
||||
uint32_t getStoredPackets() const{
|
||||
return this->storedPackets;
|
||||
}
|
||||
|
||||
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size,
|
||||
const uint32_t max_size, bool bigEndian) const {
|
||||
ReturnValue_t result = AutoSerializeAdapter::serialize(&blockStartAddress,buffer,size,max_size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
result = indexType.serialize(buffer,size,max_size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
result = AutoSerializeAdapter::serialize(&this->storedPackets,buffer,size,max_size,bigEndian);
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size,
|
||||
bool bigEndian){
|
||||
ReturnValue_t result = AutoSerializeAdapter::deSerialize(&blockStartAddress,buffer,size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
result = indexType.deSerialize(buffer,size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
result = AutoSerializeAdapter::deSerialize(&this->size,buffer,size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
result = AutoSerializeAdapter::deSerialize(&this->storedPackets,buffer,size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t getSerializedSize() const {
|
||||
uint32_t size = AutoSerializeAdapter::getSerializedSize(&blockStartAddress);
|
||||
size += indexType.getSerializedSize();
|
||||
size += AutoSerializeAdapter::getSerializedSize(&this->size);
|
||||
size += AutoSerializeAdapter::getSerializedSize(&this->storedPackets);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
bool operator==(const Index<T>& other){
|
||||
return ((blockStartAddress == other.getBlockStartAddress()) && (size==other.getSize())) && (indexType == *(other.getIndexType()));
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t blockStartAddress;
|
||||
uint32_t size;
|
||||
uint32_t storedPackets;
|
||||
T indexType;
|
||||
};
|
||||
|
||||
|
||||
|
||||
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){
|
||||
|
||||
//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
|
||||
uint32_t serializedSize = 0;
|
||||
if(additionalInfo!=NULL){
|
||||
serializedSize += additionalInfo->getSerializedSize();
|
||||
}
|
||||
//Size of current iterator type
|
||||
Index<T> tempIndex;
|
||||
serializedSize += tempIndex.getSerializedSize();
|
||||
|
||||
//Add Size of Array
|
||||
serializedSize += sizeof(uint32_t); //size of array
|
||||
serializedSize += (tempIndex.getSerializedSize() * maxNrOfIndices); //size of elements
|
||||
serializedSize += sizeof(uint16_t); //size of crc
|
||||
|
||||
//Calculate new size after index
|
||||
if(serializedSize > totalSize){
|
||||
error << "IndexedRingMemory: Store is too small for index" << std::endl;
|
||||
}
|
||||
uint32_t useableSize = totalSize - serializedSize;
|
||||
//Update the totalSize for calculations
|
||||
totalSize = useableSize;
|
||||
|
||||
//True StartAddress
|
||||
uint32_t trueStartAddress = indexAddress + serializedSize;
|
||||
|
||||
//Calculate True number of Blocks and reset size of true Number of Blocks
|
||||
uint32_t trueNumberOfBlocks = floor(static_cast<double>(totalSize) / static_cast<double>(bytesPerBlock));
|
||||
|
||||
//allocate memory now
|
||||
this->entries = new Index<T>[trueNumberOfBlocks];
|
||||
this->size = trueNumberOfBlocks;
|
||||
this->maxSize_ = trueNumberOfBlocks;
|
||||
this->allocated = true;
|
||||
|
||||
//Check trueNumberOfBlocks
|
||||
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) {
|
||||
it->setBlockStartAddress(address);
|
||||
it->setSize(0);
|
||||
it->setStoredPackets(0);
|
||||
address += bytesPerBlock;
|
||||
}
|
||||
|
||||
|
||||
//Initialize iterators
|
||||
currentWriteBlock = this->begin();
|
||||
currentReadBlock = this->begin();
|
||||
lastBlockToRead = this->begin();
|
||||
|
||||
//Check last blockSize
|
||||
uint32_t lastBlockSize = (trueStartAddress + useableSize) - (this->back()->getBlockStartAddress());
|
||||
if((lastBlockSize<bytesPerBlock) && (this->size > 1)){
|
||||
//remove the last Block so the second last block has more size
|
||||
this->size -= 1;
|
||||
debug << "IndexedRingMemory: Last Block is smaller than bytesPerBlock, removed last block" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the whole index, the iterators and executes the given reset function on every index type
|
||||
* @param typeResetFnc static reset function which accepts a pointer to the index Type
|
||||
*/
|
||||
void reset(void (*typeResetFnc)(T*)){
|
||||
currentReadBlock = this->begin();
|
||||
currentWriteBlock = this->begin();
|
||||
lastBlockToRead = this->begin();
|
||||
currentReadSize = 0;
|
||||
currentReadBlockSizeCached = 0;
|
||||
lastBlockToReadSize = 0;
|
||||
for(typename IndexedRingMemoryArray<T>::Iterator it = this->begin();it!=this->end();++it){
|
||||
it->setSize(0);
|
||||
it->setStoredPackets(0);
|
||||
(*typeResetFnc)(it->modifyIndexType());
|
||||
}
|
||||
}
|
||||
|
||||
void resetBlock(typename IndexedRingMemoryArray<T>::Iterator it,void (*typeResetFnc)(T*)){
|
||||
it->setSize(0);
|
||||
it->setStoredPackets(0);
|
||||
(*typeResetFnc)(it->modifyIndexType());
|
||||
}
|
||||
|
||||
/*
|
||||
* Reading
|
||||
*/
|
||||
|
||||
void setCurrentReadBlock(typename IndexedRingMemoryArray<T>::Iterator it){
|
||||
currentReadBlock = it;
|
||||
currentReadBlockSizeCached = it->getSize();
|
||||
}
|
||||
|
||||
void resetRead(){
|
||||
currentReadBlock = this->begin();
|
||||
currentReadSize = 0;
|
||||
currentReadBlockSizeCached = this->begin()->getSize();
|
||||
lastBlockToRead = currentWriteBlock;
|
||||
lastBlockToReadSize = currentWriteBlock->getSize();
|
||||
}
|
||||
/**
|
||||
* Sets the last block to read to this iterator.
|
||||
* Can be used to dump until block x
|
||||
* @param it The iterator for the last read block
|
||||
*/
|
||||
void setLastBlockToRead(typename IndexedRingMemoryArray<T>::Iterator it){
|
||||
lastBlockToRead = it;
|
||||
lastBlockToReadSize = it->getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the read pointer to the first written Block, which is the first non empty block in front of the write block
|
||||
* Can be the currentWriteBlock as well
|
||||
*/
|
||||
void readOldest(){
|
||||
resetRead();
|
||||
currentReadBlock = getNextNonEmptyBlock();
|
||||
currentReadBlockSizeCached = currentReadBlock->getSize();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current read iterator to the next Block and resets the current read size
|
||||
* The current size of the block will be cached to avoid race condition between write and read
|
||||
* If the end of the ring is reached the read pointer will be set to the begin
|
||||
*/
|
||||
void readNext(){
|
||||
currentReadSize = 0;
|
||||
if((this->size != 0) && (currentReadBlock.value ==this->back())){
|
||||
currentReadBlock = this->begin();
|
||||
}else{
|
||||
currentReadBlock++;
|
||||
}
|
||||
|
||||
currentReadBlockSizeCached = currentReadBlock->getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address which is currently read from
|
||||
* @return Address to read from
|
||||
*/
|
||||
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
|
||||
* @param readSize The size that was read
|
||||
* @return Returns true if the read can go on
|
||||
*/
|
||||
bool addReadSize(uint32_t readSize) {
|
||||
if(currentReadBlock == lastBlockToRead){
|
||||
//The current read block is the last to read
|
||||
if((currentReadSize+readSize)<lastBlockToReadSize){
|
||||
//the block has more data -> return true
|
||||
currentReadSize += readSize;
|
||||
return true;
|
||||
}else{
|
||||
//Reached end of read -> return false
|
||||
currentReadSize = lastBlockToReadSize;
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
//We are not in the last Block
|
||||
if((currentReadSize + readSize)<currentReadBlockSizeCached){
|
||||
//The current Block has more data
|
||||
currentReadSize += readSize;
|
||||
return true;
|
||||
}else{
|
||||
//The current block is written completely
|
||||
readNext();
|
||||
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
|
||||
for(;it!=lastBlockToRead;++it){
|
||||
if(it == this->end()){
|
||||
//This is the end, next block is the begin
|
||||
it = this->begin();
|
||||
if(it == lastBlockToRead){
|
||||
//Break if the begin is the lastBlockToRead
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(it->getSize()!=0){
|
||||
//This is a non empty block. Go on reading with this block
|
||||
currentReadBlock = it;
|
||||
currentReadBlockSizeCached = it->getSize();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//reached lastBlockToRead and every block was empty, check if the last block is also empty
|
||||
if(lastBlockToReadSize!=0){
|
||||
//go on with last Block
|
||||
currentReadBlock = lastBlockToRead;
|
||||
currentReadBlockSizeCached = lastBlockToReadSize;
|
||||
return true;
|
||||
}
|
||||
//There is no non empty block left
|
||||
return false;
|
||||
}
|
||||
//Size is larger than 0
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint32_t getRemainigSizeOfCurrentReadBlock() const{
|
||||
if(currentReadBlock == lastBlockToRead){
|
||||
return (lastBlockToReadSize - currentReadSize);
|
||||
}else{
|
||||
return (currentReadBlockSizeCached - currentReadSize);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getAddressOfCurrentReadBlock() const {
|
||||
return currentReadBlock->getBlockStartAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next non empty Block after the current write block,
|
||||
* @return Returns the iterator to the block. If there is non, the current write block is returned
|
||||
*/
|
||||
typename IndexedRingMemoryArray<T>::Iterator getNextNonEmptyBlock() const {
|
||||
for(typename IndexedRingMemoryArray<T>::Iterator it = getNextWrite();it!=currentWriteBlock;++it){
|
||||
if(it == this->end()){
|
||||
it = this->begin();
|
||||
if(it == currentWriteBlock){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(it->getSize()!=0){
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return currentWriteBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the oldest Index type
|
||||
* @return Type of Index
|
||||
*/
|
||||
T* getOldest(){
|
||||
return (getNextNonEmptyBlock()->modifyIndexType());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Writing
|
||||
*/
|
||||
uint32_t getAddressOfCurrentWriteBlock() const{
|
||||
return currentWriteBlock->getBlockStartAddress();
|
||||
}
|
||||
|
||||
uint32_t getSizeOfCurrentWriteBlock() const{
|
||||
return currentWriteBlock->getSize();
|
||||
}
|
||||
|
||||
uint32_t getCurrentWriteAddress() const{
|
||||
return getAddressOfCurrentWriteBlock() + getSizeOfCurrentWriteBlock();
|
||||
}
|
||||
|
||||
void clearCurrentWriteBlock(){
|
||||
currentWriteBlock->setSize(0);
|
||||
currentWriteBlock->setStoredPackets(0);
|
||||
}
|
||||
|
||||
void addCurrentWriteBlock(uint32_t size, uint32_t storedPackets){
|
||||
currentWriteBlock->addSize(size);
|
||||
currentWriteBlock->addStoredPackets(storedPackets);
|
||||
}
|
||||
|
||||
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
|
||||
* @return Returns true if size to write is smaller the remaining size of the block
|
||||
*/
|
||||
bool hasCurrentWriteBlockEnoughSpace(uint32_t sizeToWrite){
|
||||
typename IndexedRingMemoryArray<T>::Iterator next = getNextWrite();
|
||||
uint32_t addressOfNextBlock = next->getBlockStartAddress();
|
||||
uint32_t availableSize = ((addressOfNextBlock+totalSize) - (getAddressOfCurrentWriteBlock()+getSizeOfCurrentWriteBlock()))%totalSize;
|
||||
return (sizeToWrite < availableSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the store is full if overwrite old is false
|
||||
* @return Returns true if it is writeable and false if not
|
||||
*/
|
||||
bool isNextBlockWritable(){
|
||||
//First check if this is the end of the list
|
||||
typename IndexedRingMemoryArray<T>::Iterator next;
|
||||
next = getNextWrite();
|
||||
if((next->getSize()!=0) && (!overwriteOld)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates current write Block Index Type
|
||||
* @param infoOfNewBlock
|
||||
*/
|
||||
void updateCurrentBlock(T* infoOfNewBlock){
|
||||
currentWriteBlock->setIndexType(infoOfNewBlock);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Succeed to next block, returns FAILED if overwrite is false and the store is full
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t writeNext(){
|
||||
//Check Next Block
|
||||
if(!isNextBlockWritable()){
|
||||
//The Index is full and does not overwrite old
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
//Next block can be written, update Metadata
|
||||
currentWriteBlock = getNextWrite();
|
||||
currentWriteBlock->setSize(0);
|
||||
currentWriteBlock->setStoredPackets(0);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the Index and calculates the CRC.
|
||||
* Parameters according to HasSerializeIF
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param max_size
|
||||
* @param bigEndian
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size,
|
||||
const uint32_t max_size, bool bigEndian) const{
|
||||
uint8_t* crcBuffer = *buffer;
|
||||
uint32_t oldSize = *size;
|
||||
if(additionalInfo!=NULL){
|
||||
additionalInfo->serialize(buffer,size,max_size,bigEndian);
|
||||
}
|
||||
ReturnValue_t result = currentWriteBlock->serialize(buffer,size,max_size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t i = 0;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) {
|
||||
result = SerializeAdapter<Index<T> >::serialize(&this->entries[i], buffer, size,
|
||||
max_size, bigEndian);
|
||||
++i;
|
||||
}
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
uint16_t crc = Calculate_CRC(crcBuffer,(*size-oldSize));
|
||||
result = AutoSerializeAdapter::serialize(&crc,buffer,size,max_size,bigEndian);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the serialized Size of the index
|
||||
* @return The serialized size of the index
|
||||
*/
|
||||
uint32_t getSerializedSize() const {
|
||||
|
||||
uint32_t size = 0;
|
||||
if(additionalInfo!=NULL){
|
||||
size += additionalInfo->getSerializedSize();
|
||||
}
|
||||
size += currentWriteBlock->getSerializedSize();
|
||||
size += AutoSerializeAdapter::getSerializedSize(&this->size);
|
||||
size += (this->entries[0].getSerializedSize()) * this->size;
|
||||
uint16_t crc = 0;
|
||||
size += AutoSerializeAdapter::getSerializedSize(&crc);
|
||||
return size;
|
||||
}
|
||||
/**
|
||||
* DeSerialize the Indexed Ring from a buffer, deSerializes the current write iterator
|
||||
* CRC Has to be checked before!
|
||||
* @param buffer
|
||||
* @param size
|
||||
* @param bigEndian
|
||||
* @return
|
||||
*/
|
||||
|
||||
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size,
|
||||
bool bigEndian){
|
||||
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
if(additionalInfo!=NULL){
|
||||
result = additionalInfo->deSerialize(buffer,size,bigEndian);
|
||||
}
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
|
||||
Index<T> tempIndex;
|
||||
result = tempIndex.deSerialize(buffer,size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
uint32_t tempSize = 0;
|
||||
result = AutoSerializeAdapter::deSerialize(&tempSize,buffer,size,bigEndian);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
if(this->size != tempSize){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
uint32_t i = 0;
|
||||
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) {
|
||||
result = SerializeAdapter<Index<T> >::deSerialize(
|
||||
&this->entries[i], buffer, size,
|
||||
bigEndian);
|
||||
++i;
|
||||
}
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
typename IndexedRingMemoryArray<T>::Iterator cmp(&tempIndex);
|
||||
for(typename IndexedRingMemoryArray<T>::Iterator it= this->begin();it!=this->end();++it){
|
||||
if(*(cmp.value) == *(it.value)){
|
||||
currentWriteBlock = it;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
}
|
||||
//Reached if current write block iterator is not found
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
uint32_t getIndexAddress() const {
|
||||
return indexAddress;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Statistics
|
||||
*/
|
||||
uint32_t getStoredPackets() const {
|
||||
uint32_t size = 0;
|
||||
for(typename IndexedRingMemoryArray<T>::Iterator it= this->begin();it!=this->end();++it){
|
||||
size += it->getStoredPackets();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t getTotalSize() const {
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
uint32_t getCurrentSize() const{
|
||||
uint32_t size = 0;
|
||||
for(typename IndexedRingMemoryArray<T>::Iterator it= this->begin();it!=this->end();++it){
|
||||
size += it->getSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool isEmpty() const{
|
||||
return getCurrentSize()==0;
|
||||
}
|
||||
|
||||
double getPercentageFilled() const{
|
||||
uint32_t filledSize = 0;
|
||||
for(typename IndexedRingMemoryArray<T>::Iterator it= this->begin();it!=this->end();++it){
|
||||
filledSize += it->getSize();
|
||||
}
|
||||
|
||||
return (double)filledSize/(double)this->totalSize;
|
||||
}
|
||||
|
||||
typename IndexedRingMemoryArray<T>::Iterator getCurrentWriteBlock() const{
|
||||
return currentWriteBlock;
|
||||
}
|
||||
/**
|
||||
* Get the next block of the currentWriteBlock.
|
||||
* Returns the first one if currentWriteBlock is the last one
|
||||
* @return Iterator pointing to the next block after currentWriteBlock
|
||||
*/
|
||||
typename IndexedRingMemoryArray<T>::Iterator getNextWrite() const{
|
||||
typename IndexedRingMemoryArray<T>::Iterator next(currentWriteBlock);
|
||||
if((this->size != 0) && (currentWriteBlock.value == this->back())){
|
||||
next = this->begin();
|
||||
}else{
|
||||
++next;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
/**
|
||||
* Get the block in front of the Iterator
|
||||
* Returns the last block if it is the first block
|
||||
* @param it iterator which you want the previous block from
|
||||
* @return pointing to the block before it
|
||||
*/
|
||||
typename IndexedRingMemoryArray<T>::Iterator getPreviousBlock(typename IndexedRingMemoryArray<T>::Iterator it) {
|
||||
if(this->begin() == it){
|
||||
typename IndexedRingMemoryArray<T>::Iterator next((this->back()));
|
||||
return next;
|
||||
}
|
||||
typename IndexedRingMemoryArray<T>::Iterator next(it);
|
||||
--next;
|
||||
return next;
|
||||
}
|
||||
private:
|
||||
//The total size used by the blocks (without index)
|
||||
uint32_t totalSize;
|
||||
|
||||
//The address of the index
|
||||
const uint32_t indexAddress;
|
||||
|
||||
//The iterators for writing and reading
|
||||
typename IndexedRingMemoryArray<T>::Iterator currentWriteBlock;
|
||||
typename IndexedRingMemoryArray<T>::Iterator currentReadBlock;
|
||||
|
||||
//How much of the current read block is read already
|
||||
uint32_t currentReadSize;
|
||||
|
||||
//Cached Size of current read block
|
||||
uint32_t currentReadBlockSizeCached;
|
||||
|
||||
//Last block of current write (should be write block)
|
||||
typename IndexedRingMemoryArray<T>::Iterator lastBlockToRead;
|
||||
//current size of last Block to read
|
||||
uint32_t lastBlockToReadSize;
|
||||
|
||||
//Additional Info to be serialized with the index
|
||||
SerializeIF* additionalInfo;
|
||||
|
||||
//Does it overwrite old blocks?
|
||||
const bool overwriteOld;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_CONTAINER_INDEXEDRINGMEMORY_H_ */
|
@ -1,27 +0,0 @@
|
||||
/**
|
||||
* @file LinkedElementDecorator.h
|
||||
* @brief This file defines the LinkedElementDecorator class.
|
||||
* @date 22.07.2014
|
||||
* @author baetz
|
||||
*/
|
||||
#ifndef LINKEDELEMENTDECORATOR_H_
|
||||
#define LINKEDELEMENTDECORATOR_H_
|
||||
|
||||
#include <framework/container/SinglyLinkedList.h>
|
||||
#include <utility>
|
||||
|
||||
//TODO: This generates multiple inheritance from non-IF parents.
|
||||
template<typename T, typename IF_T>
|
||||
class LinkedElementDecorator : public LinkedElement<IF_T>, public T {
|
||||
public:
|
||||
template<typename... Args>
|
||||
LinkedElementDecorator(Args... args) : LinkedElement<IF_T>(this), T(std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
virtual ~LinkedElementDecorator() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* LINKEDELEMENTDECORATOR_H_ */
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* PlacementFactory.h
|
||||
*
|
||||
* Created on: 10.03.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_
|
||||
#define FRAMEWORK_CONTAINER_PLACEMENTFACTORY_H_
|
||||
|
||||
@ -30,7 +23,8 @@ public:
|
||||
}
|
||||
template<typename T>
|
||||
ReturnValue_t destroy(T* thisElement) {
|
||||
//TODO: Shouldn't we call the destructor here first, in case something was allocated by the object (shouldn't do that, however).
|
||||
//Need to call destructor first, in case something was allocated by the object (shouldn't do that, however).
|
||||
thisElement->~T();
|
||||
uint8_t* pointer = (uint8_t*) (thisElement);
|
||||
return dataBackend->deleteData(pointer, sizeof(T));
|
||||
}
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* RingBufferBase.h
|
||||
*
|
||||
* Created on: 06.02.2015
|
||||
* Author |