Merge remote-tracking branch 'upstream/master' into mueller_binSemaphoreInit

This commit is contained in:
Robin Müller 2020-07-28 12:26:56 +02:00
commit a9c8bea857
114 changed files with 3386 additions and 2215 deletions

View File

@ -71,18 +71,18 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep
CommandMessage reply; CommandMessage reply;
store_address_t storeAddress; store_address_t storeAddress;
uint8_t *dataPtr; uint8_t *dataPtr;
uint32_t maxSize = data->getSerializedSize(); size_t maxSize = data->getSerializedSize();
if (maxSize == 0) { if (maxSize == 0) {
//No error, there's simply nothing to report. //No error, there's simply nothing to report.
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
uint32_t size = 0; size_t size = 0;
ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize, ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize,
&dataPtr); &dataPtr);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = data->serialize(&dataPtr, &size, maxSize, true); result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
ipcStore->deleteData(storeAddress); ipcStore->deleteData(storeAddress);
return result; return result;

View File

@ -4,30 +4,31 @@
#include <framework/action/HasActionsIF.h> #include <framework/action/HasActionsIF.h>
#include <framework/objectmanager/ObjectManagerIF.h> #include <framework/objectmanager/ObjectManagerIF.h>
CommandActionHelper::CommandActionHelper(CommandsActionsIF* setOwner) : CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner) :
owner(setOwner), queueToUse(NULL), ipcStore( owner(setOwner), queueToUse(NULL), ipcStore(
NULL), commandCount(0), lastTarget(0) { NULL), commandCount(0), lastTarget(0) {
} }
CommandActionHelper::~CommandActionHelper() { CommandActionHelper::~CommandActionHelper() {
} }
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
ActionId_t actionId, SerializeIF* data) { ActionId_t actionId, SerializeIF *data) {
HasActionsIF* receiver = objectManager->get<HasActionsIF>(commandTo); HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
if (receiver == NULL) { if (receiver == NULL) {
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS; return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
} }
store_address_t storeId; store_address_t storeId;
uint8_t* storePointer; uint8_t *storePointer;
uint32_t maxSize = data->getSerializedSize(); size_t maxSize = data->getSerializedSize();
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize,
&storePointer); &storePointer);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
uint32_t size = 0; size_t size = 0;
result = data->serialize(&storePointer, &size, maxSize, true); result = data->serialize(&storePointer, &size, maxSize,
SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
@ -35,11 +36,11 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
} }
ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo,
ActionId_t actionId, const uint8_t* data, uint32_t size) { ActionId_t actionId, const uint8_t *data, uint32_t size) {
// if (commandCount != 0) { // if (commandCount != 0) {
// return CommandsFunctionsIF::ALREADY_COMMANDING; // return CommandsFunctionsIF::ALREADY_COMMANDING;
// } // }
HasActionsIF* receiver = objectManager->get<HasActionsIF>(commandTo); HasActionsIF *receiver = objectManager->get<HasActionsIF>(commandTo);
if (receiver == NULL) { if (receiver == NULL) {
return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS; return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS;
} }
@ -71,13 +72,13 @@ ReturnValue_t CommandActionHelper::initialize() {
} }
queueToUse = owner->getCommandQueuePtr(); queueToUse = owner->getCommandQueuePtr();
if(queueToUse == NULL){ if (queueToUse == NULL) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) { ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) {
if (reply->getSender() != lastTarget) { if (reply->getSender() != lastTarget) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -88,7 +89,8 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::COMPLETION_FAILED: case ActionMessage::COMPLETION_FAILED:
commandCount--; commandCount--;
owner->completionFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getReturnCode(reply)); owner->completionFailedReceived(ActionMessage::getActionId(reply),
ActionMessage::getReturnCode(reply));
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::STEP_SUCCESS: case ActionMessage::STEP_SUCCESS:
owner->stepSuccessfulReceived(ActionMessage::getActionId(reply), owner->stepSuccessfulReceived(ActionMessage::getActionId(reply),
@ -96,11 +98,13 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::STEP_FAILED: case ActionMessage::STEP_FAILED:
commandCount--; commandCount--;
owner->stepFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getStep(reply), owner->stepFailedReceived(ActionMessage::getActionId(reply),
ActionMessage::getStep(reply),
ActionMessage::getReturnCode(reply)); ActionMessage::getReturnCode(reply));
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
case ActionMessage::DATA_REPLY: case ActionMessage::DATA_REPLY:
extractDataForOwner(ActionMessage::getActionId(reply), ActionMessage::getStoreId(reply)); extractDataForOwner(ActionMessage::getActionId(reply),
ActionMessage::getStoreId(reply));
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;

View File

@ -148,47 +148,47 @@ public:
return theMap.maxSize(); return theMap.maxSize();
} }
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = SerializeAdapter<uint32_t>::serialize(&this->_size, ReturnValue_t result = SerializeAdapter::serialize(&this->_size,
buffer, size, max_size, bigEndian); buffer, size, maxSize, streamEndianness);
uint32_t i = 0; uint32_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
result = SerializeAdapter<key_t>::serialize(&theMap[i].first, buffer, result = SerializeAdapter::serialize(&theMap[i].first, buffer,
size, max_size, bigEndian); size, maxSize, streamEndianness);
result = SerializeAdapter<T>::serialize(&theMap[i].second, buffer, size, result = SerializeAdapter::serialize(&theMap[i].second, buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
++i; ++i;
} }
return result; return result;
} }
virtual uint32_t getSerializedSize() const { virtual size_t getSerializedSize() const {
uint32_t printSize = sizeof(_size); uint32_t printSize = sizeof(_size);
uint32_t i = 0; uint32_t i = 0;
for (i = 0; i < _size; ++i) { for (i = 0; i < _size; ++i) {
printSize += SerializeAdapter<key_t>::getSerializedSize( printSize += SerializeAdapter::getSerializedSize(
&theMap[i].first); &theMap[i].first);
printSize += SerializeAdapter<T>::getSerializedSize(&theMap[i].second); printSize += SerializeAdapter::getSerializedSize(&theMap[i].second);
} }
return printSize; return printSize;
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter<uint32_t>::deSerialize(&this->_size, ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size,
buffer, size, bigEndian); buffer, size, streamEndianness);
if (this->_size > theMap.maxSize()) { if (this->_size > theMap.maxSize()) {
return SerializeIF::TOO_MANY_ELEMENTS; return SerializeIF::TOO_MANY_ELEMENTS;
} }
uint32_t i = 0; uint32_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) {
result = SerializeAdapter<key_t>::deSerialize(&theMap[i].first, buffer, result = SerializeAdapter::deSerialize(&theMap[i].first, buffer,
size, bigEndian); size, streamEndianness);
result = SerializeAdapter<T>::deSerialize(&theMap[i].second, buffer, size, result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size,
bigEndian); streamEndianness);
++i; ++i;
} }
return result; return result;

View File

@ -1,5 +1,5 @@
#ifndef HYBRIDITERATOR_H_ #ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
#define HYBRIDITERATOR_H_ #define FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_
#include <framework/container/ArrayList.h> #include <framework/container/ArrayList.h>
#include <framework/container/SinglyLinkedList.h> #include <framework/container/SinglyLinkedList.h>
@ -8,34 +8,32 @@ template<typename T, typename count_t = uint8_t>
class HybridIterator: public LinkedElement<T>::Iterator, class HybridIterator: public LinkedElement<T>::Iterator,
public ArrayList<T, count_t>::Iterator { public ArrayList<T, count_t>::Iterator {
public: public:
HybridIterator() : HybridIterator() {}
value(NULL), linked(NULL), end(NULL) {
}
HybridIterator(typename LinkedElement<T>::Iterator *iter) : HybridIterator(typename LinkedElement<T>::Iterator *iter) :
LinkedElement<T>::Iterator(*iter), value( LinkedElement<T>::Iterator(*iter), value(iter->value),
iter->value), linked(true), end(NULL) { linked(true) {
} }
HybridIterator(LinkedElement<T> *start) : HybridIterator(LinkedElement<T> *start) :
LinkedElement<T>::Iterator(start), value( LinkedElement<T>::Iterator(start), value(start->value),
start->value), linked(true), end(NULL) { linked(true) {
} }
HybridIterator(typename ArrayList<T, count_t>::Iterator start, HybridIterator(typename ArrayList<T, count_t>::Iterator start,
typename ArrayList<T, count_t>::Iterator end) : typename ArrayList<T, count_t>::Iterator end) :
ArrayList<T, count_t>::Iterator(start), value(start.value), linked( ArrayList<T, count_t>::Iterator(start), value(start.value),
false), end(end.value) { linked(false), end(end.value) {
if (value == this->end) { if (value == this->end) {
value = NULL; value = NULL;
} }
} }
HybridIterator(T *firstElement, T *lastElement) : HybridIterator(T *firstElement, T *lastElement) :
ArrayList<T, count_t>::Iterator(firstElement), value(firstElement), linked( ArrayList<T, count_t>::Iterator(firstElement), value(firstElement),
false), end(++lastElement) { linked(false), end(++lastElement) {
if (value == end) { if (value == end) {
value = NULL; value = NULL;
} }
@ -44,17 +42,17 @@ public:
HybridIterator& operator++() { HybridIterator& operator++() {
if (linked) { if (linked) {
LinkedElement<T>::Iterator::operator++(); LinkedElement<T>::Iterator::operator++();
if (LinkedElement<T>::Iterator::value != NULL) { if (LinkedElement<T>::Iterator::value != nullptr) {
value = LinkedElement<T>::Iterator::value->value; value = LinkedElement<T>::Iterator::value->value;
} else { } else {
value = NULL; value = nullptr;
} }
} else { } else {
ArrayList<T, count_t>::Iterator::operator++(); ArrayList<T, count_t>::Iterator::operator++();
value = ArrayList<T, count_t>::Iterator::value; value = ArrayList<T, count_t>::Iterator::value;
if (value == end) { if (value == end) {
value = NULL; value = nullptr;
} }
} }
return *this; return *this;
@ -66,11 +64,11 @@ public:
return tmp; return tmp;
} }
bool operator==(HybridIterator other) { bool operator==(const HybridIterator& other) const {
return value == other->value; return value == other.value;
} }
bool operator!=(HybridIterator other) { bool operator!=(const HybridIterator& other) const {
return !(*this == other); return !(*this == other);
} }
@ -82,11 +80,11 @@ public:
return value; return value;
} }
T* value; T* value = nullptr;
private: private:
bool linked; bool linked = false;
T *end; T *end = nullptr;
}; };
#endif /* HYBRIDITERATOR_H_ */ #endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */

View File

@ -68,50 +68,50 @@ public:
return this->storedPackets; return this->storedPackets;
} }
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = AutoSerializeAdapter::serialize(&blockStartAddress,buffer,size,max_size,bigEndian); ReturnValue_t result = SerializeAdapter::serialize(&blockStartAddress,buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = indexType.serialize(buffer,size,max_size,bigEndian); result = indexType.serialize(buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); result = SerializeAdapter::serialize(&this->size,buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::serialize(&this->storedPackets,buffer,size,max_size,bigEndian); result = SerializeAdapter::serialize(&this->storedPackets,buffer,size,maxSize,streamEndianness);
return result; return result;
} }
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian){ Endianness streamEndianness){
ReturnValue_t result = AutoSerializeAdapter::deSerialize(&blockStartAddress,buffer,size,bigEndian); ReturnValue_t result = SerializeAdapter::deSerialize(&blockStartAddress,buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = indexType.deSerialize(buffer,size,bigEndian); result = indexType.deSerialize(buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::deSerialize(&this->size,buffer,size,bigEndian); result = SerializeAdapter::deSerialize(&this->size,buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::deSerialize(&this->storedPackets,buffer,size,bigEndian); result = SerializeAdapter::deSerialize(&this->storedPackets,buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
return result; return result;
} }
uint32_t getSerializedSize() const { size_t getSerializedSize() const {
uint32_t size = AutoSerializeAdapter::getSerializedSize(&blockStartAddress); uint32_t size = SerializeAdapter::getSerializedSize(&blockStartAddress);
size += indexType.getSerializedSize(); size += indexType.getSerializedSize();
size += AutoSerializeAdapter::getSerializedSize(&this->size); size += SerializeAdapter::getSerializedSize(&this->size);
size += AutoSerializeAdapter::getSerializedSize(&this->storedPackets); size += SerializeAdapter::getSerializedSize(&this->storedPackets);
return size; return size;
} }
@ -485,37 +485,37 @@ public:
* Parameters according to HasSerializeIF * Parameters according to HasSerializeIF
* @param buffer * @param buffer
* @param size * @param size
* @param max_size * @param maxSize
* @param bigEndian * @param streamEndianness
* @return * @return
*/ */
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const{ size_t maxSize, Endianness streamEndianness) const{
uint8_t* crcBuffer = *buffer; uint8_t* crcBuffer = *buffer;
uint32_t oldSize = *size; uint32_t oldSize = *size;
if(additionalInfo!=NULL){ if(additionalInfo!=NULL){
additionalInfo->serialize(buffer,size,max_size,bigEndian); additionalInfo->serialize(buffer,size,maxSize,streamEndianness);
} }
ReturnValue_t result = currentWriteBlock->serialize(buffer,size,max_size,bigEndian); ReturnValue_t result = currentWriteBlock->serialize(buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); result = SerializeAdapter::serialize(&this->size,buffer,size,maxSize,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
uint32_t i = 0; uint32_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) {
result = SerializeAdapter<Index<T> >::serialize(&this->entries[i], buffer, size, result = SerializeAdapter::serialize(&this->entries[i], buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
++i; ++i;
} }
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
uint16_t crc = Calculate_CRC(crcBuffer,(*size-oldSize)); uint16_t crc = Calculate_CRC(crcBuffer,(*size-oldSize));
result = AutoSerializeAdapter::serialize(&crc,buffer,size,max_size,bigEndian); result = SerializeAdapter::serialize(&crc,buffer,size,maxSize,streamEndianness);
return result; return result;
} }
@ -524,17 +524,17 @@ public:
* Get the serialized Size of the index * Get the serialized Size of the index
* @return The serialized size of the index * @return The serialized size of the index
*/ */
uint32_t getSerializedSize() const { size_t getSerializedSize() const {
uint32_t size = 0; uint32_t size = 0;
if(additionalInfo!=NULL){ if(additionalInfo!=NULL){
size += additionalInfo->getSerializedSize(); size += additionalInfo->getSerializedSize();
} }
size += currentWriteBlock->getSerializedSize(); size += currentWriteBlock->getSerializedSize();
size += AutoSerializeAdapter::getSerializedSize(&this->size); size += SerializeAdapter::getSerializedSize(&this->size);
size += (this->entries[0].getSerializedSize()) * this->size; size += (this->entries[0].getSerializedSize()) * this->size;
uint16_t crc = 0; uint16_t crc = 0;
size += AutoSerializeAdapter::getSerializedSize(&crc); size += SerializeAdapter::getSerializedSize(&crc);
return size; return size;
} }
/** /**
@ -542,28 +542,28 @@ public:
* CRC Has to be checked before! * CRC Has to be checked before!
* @param buffer * @param buffer
* @param size * @param size
* @param bigEndian * @param streamEndianness
* @return * @return
*/ */
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian){ Endianness streamEndianness){
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if(additionalInfo!=NULL){ if(additionalInfo!=NULL){
result = additionalInfo->deSerialize(buffer,size,bigEndian); result = additionalInfo->deSerialize(buffer,size,streamEndianness);
} }
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
Index<T> tempIndex; Index<T> tempIndex;
result = tempIndex.deSerialize(buffer,size,bigEndian); result = tempIndex.deSerialize(buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
uint32_t tempSize = 0; uint32_t tempSize = 0;
result = AutoSerializeAdapter::deSerialize(&tempSize,buffer,size,bigEndian); result = SerializeAdapter::deSerialize(&tempSize,buffer,size,streamEndianness);
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
@ -572,9 +572,9 @@ public:
} }
uint32_t i = 0; uint32_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) {
result = SerializeAdapter<Index<T> >::deSerialize( result = SerializeAdapter::deSerialize(
&this->entries[i], buffer, size, &this->entries[i], buffer, size,
bigEndian); streamEndianness);
++i; ++i;
} }
if(result != HasReturnvaluesIF::RETURN_OK){ if(result != HasReturnvaluesIF::RETURN_OK){

View File

@ -39,10 +39,10 @@ PoolEntryIF* DataPool::getRawData( uint32_t data_pool_id ) {
} }
} }
//uint8_t DataPool::getRawData( uint32_t data_pool_id, uint8_t* address, uint16_t* size, uint32_t max_size ) { //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 ); // std::map<uint32_t, PoolEntryIF*>::iterator it = this->data_pool.find( data_pool_id );
// if ( it != this->data_pool.end() ) { // if ( it != this->data_pool.end() ) {
// if ( it->second->getByteSize() <= max_size ) { // if ( it->second->getByteSize() <= maxSize ) {
// *size = it->second->getByteSize(); // *size = it->second->getByteSize();
// memcpy( address, it->second->getRawData(), *size ); // memcpy( address, it->second->getRawData(), *size );
// return DP_SUCCESSFUL; // return DP_SUCCESSFUL;

View File

@ -26,7 +26,7 @@ MessageQueueId_t DataPoolAdmin::getCommandQueue() const {
} }
ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId, ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) { MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
if (actionId != SET_VALIDITY) { if (actionId != SET_VALIDITY) {
return INVALID_ACTION_ID; return INVALID_ACTION_ID;
} }
@ -91,7 +91,7 @@ void DataPoolAdmin::handleCommand() {
} }
ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
const uint8_t* data, uint32_t size, uint8_t** dataPointer) { const uint8_t* data, size_t size, uint8_t** dataPointer) {
uint32_t poolId = ::dataPool.PIDToDataPoolId(address); uint32_t poolId = ::dataPool.PIDToDataPoolId(address);
uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address);
DataSet testSet; DataSet testSet;
@ -129,7 +129,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address,
return ACTIVITY_COMPLETED; return ACTIVITY_COMPLETED;
} }
ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size, ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, size_t size,
uint8_t** dataPointer, uint8_t* copyHere) { uint8_t** dataPointer, uint8_t* copyHere) {
uint32_t poolId = ::dataPool.PIDToDataPoolId(address); uint32_t poolId = ::dataPool.PIDToDataPoolId(address);
uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address); uint8_t arrayIndex = ::dataPool.PIDToArrayIndex(address);
@ -151,7 +151,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size,
PoolVariableIF::VAR_READ); PoolVariableIF::VAR_READ);
status = rawSet.read(); status = rawSet.read();
if (status == RETURN_OK) { if (status == RETURN_OK) {
uint32_t temp = 0; size_t temp = 0;
status = variable.getEntryEndianSafe(ptrToCopy, &temp, size); status = variable.getEntryEndianSafe(ptrToCopy, &temp, size);
if (status != RETURN_OK) { if (status != RETURN_OK) {
return RETURN_FAILED; return RETURN_FAILED;
@ -261,7 +261,7 @@ ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) {
//identical to ParameterHelper::sendParameter() //identical to ParameterHelper::sendParameter()
ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id,
const DataPoolParameterWrapper* wrapper) { const DataPoolParameterWrapper* wrapper) {
uint32_t serializedSize = wrapper->getSerializedSize(); size_t serializedSize = wrapper->getSerializedSize();
uint8_t *storeElement; uint8_t *storeElement;
store_address_t address; store_address_t address;
@ -272,10 +272,10 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id,
return result; return result;
} }
uint32_t storeElementSize = 0; size_t storeElementSize = 0;
result = wrapper->serialize(&storeElement, &storeElementSize, result = wrapper->serialize(&storeElement, &storeElementSize,
serializedSize, true); serializedSize, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
storage->deleteData(address); storage->deleteData(address);

View File

@ -29,12 +29,12 @@ public:
MessageQueueId_t getCommandQueue() const; MessageQueueId_t getCommandQueue() const;
ReturnValue_t handleMemoryLoad(uint32_t address, const uint8_t* data, ReturnValue_t handleMemoryLoad(uint32_t address, const uint8_t* data,
uint32_t size, uint8_t** dataPointer); size_t size, uint8_t** dataPointer);
ReturnValue_t handleMemoryDump(uint32_t address, uint32_t size, ReturnValue_t handleMemoryDump(uint32_t address, size_t size,
uint8_t** dataPointer, uint8_t* copyHere); uint8_t** dataPointer, uint8_t* copyHere);
ReturnValue_t executeAction(ActionId_t actionId, ReturnValue_t executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size); MessageQueueId_t commandedBy, const uint8_t* data, size_t size);
//not implemented as ParameterHelper is no used //not implemented as ParameterHelper is no used
ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,

View File

@ -36,22 +36,22 @@ ReturnValue_t DataPoolParameterWrapper::set(uint8_t domainId,
} }
ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer,
uint32_t* size, const uint32_t max_size, bool bigEndian) const { size_t* size, size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result; ReturnValue_t result;
result = SerializeAdapter<Type>::serialize(&type, buffer, size, max_size, result = SerializeAdapter::serialize(&type, buffer, size, maxSize,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&columns, buffer, size, result = SerializeAdapter::serialize(&columns, buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&rows, buffer, size, max_size, result = SerializeAdapter::serialize(&rows, buffer, size, maxSize,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
@ -60,7 +60,7 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer,
DataSet mySet; DataSet mySet;
PoolRawAccess raw(poolId, index, &mySet,PoolVariableIF::VAR_READ); PoolRawAccess raw(poolId, index, &mySet,PoolVariableIF::VAR_READ);
mySet.read(); mySet.read();
result = raw.serialize(buffer,size,max_size,bigEndian); result = raw.serialize(buffer,size,maxSize,streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK){ if (result != HasReturnvaluesIF::RETURN_OK){
return result; return result;
} }
@ -69,8 +69,8 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer,
} }
//same as ParameterWrapper //same as ParameterWrapper
uint32_t DataPoolParameterWrapper::getSerializedSize() const { size_t DataPoolParameterWrapper::getSerializedSize() const {
uint32_t serializedSize = 0; size_t serializedSize = 0;
serializedSize += type.getSerializedSize(); serializedSize += type.getSerializedSize();
serializedSize += sizeof(rows); serializedSize += sizeof(rows);
serializedSize += sizeof(columns); serializedSize += sizeof(columns);
@ -80,7 +80,7 @@ uint32_t DataPoolParameterWrapper::getSerializedSize() const {
} }
ReturnValue_t DataPoolParameterWrapper::deSerialize(const uint8_t** buffer, ReturnValue_t DataPoolParameterWrapper::deSerialize(const uint8_t** buffer,
int32_t* size, bool bigEndian) { size_t* size, Endianness streamEndianness) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }

View File

@ -11,13 +11,13 @@ public:
ReturnValue_t set(uint8_t domainId, uint16_t parameterId); ReturnValue_t set(uint8_t domainId, uint16_t parameterId);
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
virtual uint32_t getSerializedSize() const; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian); Endianness streamEndianness) override;
ReturnValue_t copyFrom(const ParameterWrapper *from, ReturnValue_t copyFrom(const ParameterWrapper *from,
uint16_t startWritingAtIndex); uint16_t startWritingAtIndex);

View File

@ -106,12 +106,12 @@ uint8_t DataSet::lockDataPool() {
return ::dataPool.lockDataPool(); return ::dataPool.lockDataPool();
} }
ReturnValue_t DataSet::serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t DataSet::serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = RETURN_FAILED; ReturnValue_t result = RETURN_FAILED;
for (uint16_t count = 0; count < fill_count; count++) { for (uint16_t count = 0; count < fill_count; count++) {
result = registeredVariables[count]->serialize(buffer, size, max_size, result = registeredVariables[count]->serialize(buffer, size, maxSize,
bigEndian); streamEndianness);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
@ -119,8 +119,8 @@ ReturnValue_t DataSet::serialize(uint8_t** buffer, uint32_t* size,
return result; return result;
} }
uint32_t DataSet::getSerializedSize() const { size_t DataSet::getSerializedSize() const {
uint32_t size = 0; size_t size = 0;
for (uint16_t count = 0; count < fill_count; count++) { for (uint16_t count = 0; count < fill_count; count++) {
size += registeredVariables[count]->getSerializedSize(); size += registeredVariables[count]->getSerializedSize();
} }
@ -136,12 +136,12 @@ void DataSet::setValid(uint8_t valid) {
} }
} }
ReturnValue_t DataSet::deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t DataSet::deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
ReturnValue_t result = RETURN_FAILED; ReturnValue_t result = RETURN_FAILED;
for (uint16_t count = 0; count < fill_count; count++) { for (uint16_t count = 0; count < fill_count; count++) {
result = registeredVariables[count]->deSerialize(buffer, size, result = registeredVariables[count]->deSerialize(buffer, size,
bigEndian); streamEndianness);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }

View File

@ -146,13 +146,13 @@ public:
*/ */
void setValid(uint8_t valid); void setValid(uint8_t valid);
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
uint32_t getSerializedSize() const; size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian); Endianness streamEndianness) override;
}; };

View File

@ -17,7 +17,7 @@ protected:
uint8_t valid; uint8_t valid;
ReturnValue_t read() { ReturnValue_t read() {
uint8_t arrayIndex = DataPool::PIDToArrayIndex(parameterId); uint8_t arrayIndex = DataPool::PIDToArrayIndex(parameterId);
PoolEntry<T>* read_out = ::dataPool.getData<T>( PoolEntry<T> *read_out = ::dataPool.getData<T>(
DataPool::PIDToDataPoolId(parameterId), arrayIndex); DataPool::PIDToDataPoolId(parameterId), arrayIndex);
if (read_out != NULL) { if (read_out != NULL) {
valid = read_out->valid; valid = read_out->valid;
@ -43,7 +43,8 @@ protected:
* Empty ctor for List initialization * Empty ctor for List initialization
*/ */
PIDReader() : PIDReader() :
parameterId(PoolVariableIF::NO_PARAMETER), valid(PoolVariableIF::INVALID), value(0) { parameterId(PoolVariableIF::NO_PARAMETER), valid(
PoolVariableIF::INVALID), value(0) {
} }
public: public:
@ -63,9 +64,9 @@ public:
* \param setWritable If this flag is set to true, changes in the value attribute can be * \param setWritable If this flag is set to true, changes in the value attribute can be
* written back to the data pool, otherwise not. * written back to the data pool, otherwise not.
*/ */
PIDReader(uint32_t setParameterId, DataSetIF* dataSet) : PIDReader(uint32_t setParameterId, DataSetIF *dataSet) :
parameterId(setParameterId), valid( parameterId(setParameterId), valid(PoolVariableIF::INVALID), value(
PoolVariableIF::INVALID), value(0) { 0) {
if (dataSet != NULL) { if (dataSet != NULL) {
dataSet->registerVariable(this); dataSet->registerVariable(this);
} }
@ -74,7 +75,7 @@ public:
/** /**
* Copy ctor to copy classes containing Pool Variables. * Copy ctor to copy classes containing Pool Variables.
*/ */
PIDReader(const PIDReader& rhs) : PIDReader(const PIDReader &rhs) :
parameterId(rhs.parameterId), valid(rhs.valid), value(rhs.value) { parameterId(rhs.parameterId), valid(rhs.valid), value(rhs.value) {
} }
@ -121,24 +122,25 @@ public:
return value; return value;
} }
PIDReader<T> &operator=(T newValue) { PIDReader<T>& operator=(T newValue) {
value = newValue; value = newValue;
return *this; return *this;
} }
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const override {
return SerializeAdapter<T>::serialize(&value, buffer, size, max_size, return SerializeAdapter::serialize(&value, buffer, size, maxSize,
bigEndian); streamEndianness);
} }
virtual uint32_t getSerializedSize() const { virtual size_t getSerializedSize() const override {
return SerializeAdapter<T>::getSerializedSize(&value); return SerializeAdapter::getSerializedSize(&value);
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian) { Endianness streamEndianness) override {
return SerializeAdapter<T>::deSerialize(&value, buffer, size, bigEndian); return SerializeAdapter::deSerialize(&value, buffer, size,
streamEndianness);
} }
}; };

View File

@ -1,13 +1,34 @@
#include <framework/datapool/PoolEntry.h> #include <framework/datapool/PoolEntry.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/globalfunctions/arrayprinter.h>
#include <cstring>
template <typename T> template <typename T>
PoolEntry<T>::PoolEntry( T* initValue, uint8_t set_length, uint8_t set_valid ) : length(set_length), valid(set_valid) { PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, uint8_t setLength,
bool setValid ) : length(setLength), valid(setValid) {
this->address = new T[this->length]; this->address = new T[this->length];
if (initValue != NULL) { if(initValue.size() == 0) {
memcpy(this->address, initValue, this->getByteSize() ); std::memset(this->address, 0, this->getByteSize());
}
else if (initValue.size() != setLength){
sif::warning << "PoolEntry: setLength is not equal to initializer list"
"length! Performing zero initialization with given setLength"
<< std::endl;
std::memset(this->address, 0, this->getByteSize());
}
else {
std::copy(initValue.begin(), initValue.end(), this->address);
}
}
template <typename T>
PoolEntry<T>::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) :
length(setLength), valid(setValid) {
this->address = new T[this->length];
if (initValue != nullptr) {
std::memcpy(this->address, initValue, this->getByteSize() );
} else { } else {
memset(this->address, 0, this->getByteSize() ); std::memset(this->address, 0, this->getByteSize() );
} }
} }
@ -34,21 +55,20 @@ void* PoolEntry<T>::getRawData() {
} }
template <typename T> template <typename T>
void PoolEntry<T>::setValid( uint8_t isValid ) { void PoolEntry<T>::setValid(bool isValid) {
this->valid = isValid; this->valid = isValid;
} }
template <typename T> template <typename T>
uint8_t PoolEntry<T>::getValid() { bool PoolEntry<T>::getValid() {
return valid; return valid;
} }
template <typename T> template <typename T>
void PoolEntry<T>::print() { void PoolEntry<T>::print() {
for (uint8_t size = 0; size < this->length; size++ ) { sif::debug << "Pool Entry Validity: " <<
sif::debug << "| " << std::hex << (double)this->address[size] (this->valid? " (valid) " : " (invalid) ") << std::endl;
<< (this->valid? " (valid) " : " (invalid) "); arrayprinter::print(reinterpret_cast<uint8_t*>(address), length);
}
sif::debug << std::dec << std::endl; sif::debug << std::dec << std::endl;
} }

View File

@ -1,81 +1,126 @@
#ifndef POOLENTRY_H_ #ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_
#define POOLENTRY_H_ #define FRAMEWORK_DATAPOOL_POOLENTRY_H_
#include <framework/datapool/PoolEntryIF.h> #include <framework/datapool/PoolEntryIF.h>
#include <stddef.h>
#include <cstring> #include <initializer_list>
#include <type_traits>
#include <cstddef>
/** /**
* \brief This is a small helper class that defines a single data pool entry. * @brief This is a small helper class that defines a single data pool entry.
* @details
* The helper is used to store all information together with the data as a
* single data pool entry. The content's type is defined by the template
* argument.
* *
* \details The helper is used to store all information together with the data as a single data pool entry. * It is prepared for use with plain old data types, but may be
* The content's type is defined by the template argument. * extended to complex types if necessary. It can be initialized with a
* It is prepared for use with plain old data types, * certain value, size and validity flag.
* but may be extended to complex types if necessary.
* It can be initialized with a certain value, size and validity flag.
* It holds a pointer to the real data and offers methods to access this data and to acquire
* additional information (such as validity and array/byte size).
* It is NOT intended to be used outside the DataPool class.
* *
* \ingroup data_pool * It holds a pointer to the real data and offers methods to access this data
* and to acquire additional information (such as validity and array/byte size).
* It is NOT intended to be used outside DataPool implementations as it performs
* dynamic memory allocation.
* *
* @ingroup data_pool
*/ */
template <typename T> template <typename T>
class PoolEntry : public PoolEntryIF { class PoolEntry : public PoolEntryIF {
public: public:
static_assert(not std::is_same<T, bool>::value,
"Do not use boolean for the PoolEntry type, use uint8_t "
"instead! The ECSS standard defines a boolean as a one bit "
"field. Therefore it is preferred to store a boolean as an "
"uint8_t");
/** /**
* \brief In the classe's constructor, space is allocated on the heap and * @brief In the classe's constructor, space is allocated on the heap and
* potential init values are copied to that space. * potential init values are copied to that space.
* \param initValue A pointer to the single value or array that holds the init value. * @details
* With the default value (NULL), the entry is initalized with all 0. * Not passing any arguments will initialize an non-array pool entry
* \param set_length Defines the array length of this entry. * (setLength = 1) with an initial invalid state.
* \param set_valid Sets the initialization flag. It is invalid (0) by default. * Please note that if an initializer list is passed, the correct
* corresponding length should be passed too, otherwise a zero
* initialization will be performed with the given setLength.
* @param initValue
* Initializer list with values to initialize with, for example {0,0} to
* initialize the two entries to zero.
* @param setLength
* Defines the array length of this entry. Should be equal to the
* intializer list length.
* @param setValid
* Sets the initialization flag. It is invalid by default.
*/ */
PoolEntry( T* initValue = NULL, uint8_t set_length = 1, uint8_t set_valid = 0 ); PoolEntry(std::initializer_list<T> initValue = {}, uint8_t setLength = 1,
bool setValid = false);
/** /**
* \brief The allocated memory for the variable is freed in the destructor. * @brief In the classe's constructor, space is allocated on the heap and
* \details As the data pool is global, this dtor is only called on program exit. * potential init values are copied to that space.
* PoolEntries shall never be copied, as a copy might delete the variable on the heap. * @param initValue
* A pointer to the single value or array that holds the init value.
* With the default value (nullptr), the entry is initalized with all 0.
* @param setLength
* Defines the array length of this entry.
* @param setValid
* Sets the initialization flag. It is invalid by default.
*/
PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false);
//! Explicitely deleted copy ctor, copying is not allowed!
PoolEntry(const PoolEntry&) = delete;
//! Explicitely deleted copy assignment, copying is not allowed!
PoolEntry& operator=(const PoolEntry&) = delete;
/**
* @brief The allocated memory for the variable is freed
* in the destructor.
* @details
* As the data pool is global, this dtor is only called on program exit.
* PoolEntries shall never be copied, as a copy might delete the variable
* on the heap.
*/ */
~PoolEntry(); ~PoolEntry();
/** /**
* \brief This is the address pointing to the allocated memory. * @brief This is the address pointing to the allocated memory.
*/ */
T* address; T* address;
/** /**
* \brief This attribute stores the length information. * @brief This attribute stores the length information.
*/ */
uint8_t length; uint8_t length;
/** /**
* \brief Here, the validity information for a variable is stored. * @brief Here, the validity information for a variable is stored.
* Every entry (single variable or vector) has one valid flag. * Every entry (single variable or vector) has one valid flag.
*/ */
uint8_t valid; uint8_t valid;
/** /**
* \brief getSize returns the array size of the entry. * @brief getSize returns the array size of the entry.
* \details A single parameter has size 1. * @details A single parameter has size 1.
*/ */
uint8_t getSize(); uint8_t getSize();
/** /**
* \brief This operation returns the size in bytes. * @brief This operation returns the size in bytes.
* \details The size is calculated by sizeof(type) * array_size. * @details The size is calculated by sizeof(type) * array_size.
*/ */
uint16_t getByteSize(); uint16_t getByteSize();
/** /**
* \brief This operation returns a the address pointer casted to void*. * @brief This operation returns a the address pointer casted to void*.
*/ */
void* getRawData(); void* getRawData();
/** /**
* \brief This method allows to set the valid information of the pool entry. * @brief This method allows to set the valid information
* of the pool entry.
*/ */
void setValid( uint8_t isValid ); void setValid( bool isValid );
/** /**
* \brief This method allows to get the valid information of the pool entry. * @brief This method allows to get the valid information
* of the pool entry.
*/ */
uint8_t getValid(); bool getValid();
/** /**
* \brief This is a debug method that prints all values and the valid information to the screen. * @brief This is a debug method that prints all values and the valid
* It prints all array entries in a row. * information to the screen. It prints all array entries in a row.
*/ */
void print(); void print();

View File

@ -1,62 +1,57 @@
/** #ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
* \file PoolEntryIF.h #define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
*
* \brief This file holds the class that defines the Interface for Pool Entry elements.
*
* \date 10/18/2012
*
* \author Bastian Baetz
*/
#ifndef POOLENTRYIF_H_
#define POOLENTRYIF_H_
#include <framework/globalfunctions/Type.h> #include <framework/globalfunctions/Type.h>
#include <stdint.h> #include <cstdint>
/** /**
* \brief This interface defines the access possibilities to a single data pool entry. * @brief This interface defines the access possibilities to a
* single data pool entry.
* @details
* The interface provides methods to determine the size and the validity
* information of a value. It also defines a method to receive a pointer to the
* raw data content. It is mainly used by DataPool itself, but also as a
* return pointer.
* *
* \details The interface provides methods to determine the size and the validity information of a value. * @author Bastian Baetz
* It also defines a method to receive a pointer to the raw data content. * @ingroup data_pool
* It is mainly used by DataPool itself, but also as a return pointer.
*
* \ingroup data_pool
* *
*/ */
class PoolEntryIF { class PoolEntryIF {
public: public:
/** /**
* \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. * @brief This is an empty virtual destructor,
* as it is required for C++ interfaces.
*/ */
virtual ~PoolEntryIF() { virtual ~PoolEntryIF() {
} }
/** /**
* \brief getSize returns the array size of the entry. A single variable parameter has size 1. * @brief getSize returns the array size of the entry.
* A single variable parameter has size 1.
*/ */
virtual uint8_t getSize() = 0; virtual uint8_t getSize() = 0;
/** /**
* \brief This operation returns the size in bytes, which is calculated by * @brief This operation returns the size in bytes, which is calculated by
* sizeof(type) * array_size. * sizeof(type) * array_size.
*/ */
virtual uint16_t getByteSize() = 0; virtual uint16_t getByteSize() = 0;
/** /**
* \brief This operation returns a the address pointer casted to void*. * @brief This operation returns a the address pointer casted to void*.
*/ */
virtual void* getRawData() = 0; virtual void* getRawData() = 0;
/** /**
* \brief This method allows to set the valid information of the pool entry. * @brief This method allows to set the valid information of the pool entry.
*/ */
virtual void setValid(uint8_t isValid) = 0; virtual void setValid(bool isValid) = 0;
/** /**
* \brief This method allows to set the valid information of the pool entry. * @brief This method allows to set the valid information of the pool entry.
*/ */
virtual uint8_t getValid() = 0; virtual bool getValid() = 0;
/** /**
* \brief This is a debug method that prints all values and the valid information to the screen. * @brief This is a debug method that prints all values and the valid
* It prints all array entries in a row. * information to the screen. It prints all array entries in a row.
* @details
* Also displays whether the pool entry is valid or invalid.
*/ */
virtual void print() = 0; virtual void print() = 0;
/** /**

View File

@ -2,12 +2,15 @@
#include <framework/datapool/PoolEntryIF.h> #include <framework/datapool/PoolEntryIF.h>
#include <framework/datapool/PoolRawAccess.h> #include <framework/datapool/PoolRawAccess.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/osal/Endiness.h> #include <framework/serialize/EndianConverter.h>
#include <cstring>
PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry, PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry,
DataSetIF* data_set, ReadWriteMode_t setReadWriteMode) : DataSetIF *data_set, ReadWriteMode_t setReadWriteMode) :
dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type(Type::UNKNOWN_TYPE), typeSize( dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type(
0), arraySize(0), sizeTillEnd(0), readWriteMode(setReadWriteMode) { Type::UNKNOWN_TYPE), typeSize(0), arraySize(0), sizeTillEnd(0), readWriteMode(
setReadWriteMode) {
memset(value, 0, sizeof(value)); memset(value, 0, sizeof(value));
if (data_set != NULL) { if (data_set != NULL) {
data_set->registerVariable(this); data_set->registerVariable(this);
@ -19,7 +22,7 @@ PoolRawAccess::~PoolRawAccess() {
} }
ReturnValue_t PoolRawAccess::read() { ReturnValue_t PoolRawAccess::read() {
PoolEntryIF* read_out = ::dataPool.getRawData(dataPoolId); PoolEntryIF *read_out = ::dataPool.getRawData(dataPoolId);
if (read_out != NULL) { if (read_out != NULL) {
valid = read_out->getValid(); valid = read_out->getValid();
if (read_out->getSize() > arrayEntry) { if (read_out->getSize() > arrayEntry) {
@ -29,7 +32,7 @@ ReturnValue_t PoolRawAccess::read() {
if (typeSize <= sizeof(value)) { if (typeSize <= sizeof(value)) {
uint16_t arrayPosition = arrayEntry * typeSize; uint16_t arrayPosition = arrayEntry * typeSize;
sizeTillEnd = read_out->getByteSize() - arrayPosition; sizeTillEnd = read_out->getByteSize() - arrayPosition;
uint8_t* ptr = uint8_t *ptr =
&((uint8_t*) read_out->getRawData())[arrayPosition]; &((uint8_t*) read_out->getRawData())[arrayPosition];
memcpy(value, ptr, typeSize); memcpy(value, ptr, typeSize);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
@ -42,8 +45,8 @@ ReturnValue_t PoolRawAccess::read() {
} else { } else {
//Error entry does not exist. //Error entry does not exist.
} }
sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex << dataPoolId sif::error << "PoolRawAccess: read of DP Variable 0x" << std::hex
<< std::dec << " failed." << std::endl; << dataPoolId << std::dec << " failed." << std::endl;
valid = INVALID; valid = INVALID;
typeSize = 0; typeSize = 0;
sizeTillEnd = 0; sizeTillEnd = 0;
@ -52,11 +55,11 @@ ReturnValue_t PoolRawAccess::read() {
} }
ReturnValue_t PoolRawAccess::commit() { ReturnValue_t PoolRawAccess::commit() {
PoolEntryIF* write_back = ::dataPool.getRawData(dataPoolId); PoolEntryIF *write_back = ::dataPool.getRawData(dataPoolId);
if ((write_back != NULL) && (readWriteMode != VAR_READ)) { if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
write_back->setValid(valid); write_back->setValid(valid);
uint8_t array_position = arrayEntry * typeSize; uint8_t array_position = arrayEntry * typeSize;
uint8_t* ptr = &((uint8_t*) write_back->getRawData())[array_position]; uint8_t *ptr = &((uint8_t*) write_back->getRawData())[array_position];
memcpy(ptr, value, typeSize); memcpy(ptr, value, typeSize);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
@ -68,23 +71,17 @@ uint8_t* PoolRawAccess::getEntry() {
return value; return value;
} }
ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t *buffer,
uint32_t* writtenBytes, uint32_t max_size) { size_t *writtenBytes, size_t maxSize) {
uint8_t* data_ptr = getEntry(); 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; // 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) if (typeSize == 0) {
return DATA_POOL_ACCESS_FAILED; return DATA_POOL_ACCESS_FAILED;
if (typeSize > max_size)
return INCORRECT_SIZE;
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
for (uint8_t count = 0; count < typeSize; count++) {
buffer[count] = data_ptr[typeSize - count - 1];
} }
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN if (typeSize > maxSize) {
memcpy(buffer, data_ptr, typeSize); return INCORRECT_SIZE;
#endif }
EndianConverter::convertBigEndian(buffer, data_ptr, typeSize);
*writtenBytes = typeSize; *writtenBytes = typeSize;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -93,11 +90,11 @@ Type PoolRawAccess::getType() {
return type; return type;
} }
uint8_t PoolRawAccess::getSizeOfType() { size_t PoolRawAccess::getSizeOfType() {
return typeSize; return typeSize;
} }
uint8_t PoolRawAccess::getArraySize(){ size_t PoolRawAccess::getArraySize() {
return arraySize; return arraySize;
} }
@ -109,21 +106,14 @@ PoolVariableIF::ReadWriteMode_t PoolRawAccess::getReadWriteMode() const {
return readWriteMode; return readWriteMode;
} }
ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t* buffer, ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t *buffer,
uint32_t setSize) { size_t setSize) {
if (typeSize == setSize) { if (typeSize == setSize) {
#ifndef BYTE_ORDER_SYSTEM EndianConverter::convertBigEndian(value, buffer, typeSize);
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
for (uint8_t count = 0; count < typeSize; count++) {
value[count] = buffer[typeSize - count - 1];
}
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
memcpy(value, buffer, typeSize);
#endif
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {
sif::error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: Internal" sif::error
<< "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: Internal"
<< (uint32_t) typeSize << ", Requested: " << setSize << (uint32_t) typeSize << ", Requested: " << setSize
<< std::endl; << std::endl;
return INCORRECT_SIZE; return INCORRECT_SIZE;
@ -141,25 +131,24 @@ void PoolRawAccess::setValid(uint8_t valid) {
this->valid = valid; this->valid = valid;
} }
uint16_t PoolRawAccess::getSizeTillEnd() const { size_t PoolRawAccess::getSizeTillEnd() const {
return sizeTillEnd; return sizeTillEnd;
} }
ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t PoolRawAccess::serialize(uint8_t **buffer, size_t *size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
if (typeSize + *size <= max_size) { if (typeSize + *size <= maxSize) {
if (bigEndian) { switch (streamEndianness) {
#ifndef BYTE_ORDER_SYSTEM case (Endianness::BIG):
#error BYTE_ORDER_SYSTEM not defined EndianConverter::convertBigEndian(*buffer, value, typeSize);
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN break;
for (uint8_t count = 0; count < typeSize; count++) { case (Endianness::LITTLE):
(*buffer)[count] = value[typeSize - count - 1]; EndianConverter::convertLittleEndian(*buffer, value, typeSize);
} break;
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN default:
memcpy(*buffer, value, typeSize); case (Endianness::MACHINE):
#endif
} else {
memcpy(*buffer, value, typeSize); memcpy(*buffer, value, typeSize);
break;
} }
*size += typeSize; *size += typeSize;
(*buffer) += typeSize; (*buffer) += typeSize;
@ -169,28 +158,27 @@ ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, uint32_t* size,
} }
} }
uint32_t PoolRawAccess::getSerializedSize() const { size_t PoolRawAccess::getSerializedSize() const {
return typeSize; return typeSize;
} }
ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t PoolRawAccess::deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian) { Endianness streamEndianness) {
*size -= typeSize;
if (*size >= 0) {
if (bigEndian) { if (*size >= typeSize) {
#ifndef BYTE_ORDER_SYSTEM switch (streamEndianness) {
#error BYTE_ORDER_SYSTEM not defined case (Endianness::BIG):
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN EndianConverter::convertBigEndian(value, *buffer, typeSize);
for (uint8_t count = 0; count < typeSize; count++) { break;
value[count] = (*buffer)[typeSize - count - 1]; case (Endianness::LITTLE):
} EndianConverter::convertLittleEndian(value, *buffer, typeSize);
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN break;
memcpy(value, *buffer, typeSize); default:
#endif case (Endianness::MACHINE):
} else {
memcpy(value, *buffer, typeSize); memcpy(value, *buffer, typeSize);
break;
} }
*size -= typeSize;
*buffer += typeSize; *buffer += typeSize;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} else { } else {

View File

@ -32,15 +32,15 @@ private:
/** /**
* \brief This value contains the size of the data pool entry in bytes. * \brief This value contains the size of the data pool entry in bytes.
*/ */
uint8_t typeSize; size_t typeSize;
/** /**
* The size of the DP array (single values return 1) * The size of the DP array (single values return 1)
*/ */
uint8_t arraySize; size_t arraySize;
/** /**
* The size (in bytes) from the selected entry till the end of this DataPool variable. * The size (in bytes) from the selected entry till the end of this DataPool variable.
*/ */
uint16_t sizeTillEnd; size_t sizeTillEnd;
/** /**
* \brief The information whether the class is read-write or read-only is stored here. * \brief The information whether the class is read-write or read-only is stored here.
*/ */
@ -70,7 +70,7 @@ public:
static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02); static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02);
uint8_t value[RAW_MAX_SIZE]; uint8_t value[RAW_MAX_SIZE];
PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry, PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry,
DataSetIF* data_set, ReadWriteMode_t setReadWriteMode = DataSetIF *data_set, ReadWriteMode_t setReadWriteMode =
PoolVariableIF::VAR_READ); PoolVariableIF::VAR_READ);
/** /**
* \brief The classes destructor is empty. If commit() was not called, the local value is * \brief The classes destructor is empty. If commit() was not called, the local value is
@ -90,15 +90,15 @@ public:
* \details It makes use of the getEntry call of this function, but additionally flips the * \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- * 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 * keeping telemetry). To achieve this, the data is copied directly to the passed
* buffer, if it fits in the given max_size. * buffer, if it fits in the given maxSize.
* \param buffer A pointer to a buffer to write to * \param buffer A pointer to a buffer to write to
* \param writtenBytes The number of bytes written is returned with this value. * \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. * \param maxSize The maximum size that the function may write to buffer.
* \return - \c RETURN_OK if entry could be acquired * \return - \c RETURN_OK if entry could be acquired
* - \c RETURN_FAILED else. * - \c RETURN_FAILED else.
*/ */
ReturnValue_t getEntryEndianSafe(uint8_t* buffer, uint32_t* size, ReturnValue_t getEntryEndianSafe(uint8_t *buffer, size_t *size,
uint32_t max_size); size_t maxSize);
/** /**
* With this method, the content can be set from a big endian buffer safely. * With this method, the content can be set from a big endian buffer safely.
* @param buffer Pointer to the data to set * @param buffer Pointer to the data to set
@ -106,8 +106,8 @@ public:
* @return - \c RETURN_OK on success * @return - \c RETURN_OK on success
* - \c RETURN_FAILED on failure * - \c RETURN_FAILED on failure
*/ */
ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer, ReturnValue_t setEntryFromBigEndian(const uint8_t *buffer,
uint32_t setSize); size_t setSize);
/** /**
* \brief This operation returns the type of the entry currently stored. * \brief This operation returns the type of the entry currently stored.
*/ */
@ -115,12 +115,12 @@ public:
/** /**
* \brief This operation returns the size of the entry currently stored. * \brief This operation returns the size of the entry currently stored.
*/ */
uint8_t getSizeOfType(); size_t getSizeOfType();
/** /**
* *
* @return the size of the datapool array * @return the size of the datapool array
*/ */
uint8_t getArraySize(); size_t getArraySize();
/** /**
* \brief This operation returns the data pool id of the variable. * \brief This operation returns the data pool id of the variable.
*/ */
@ -138,15 +138,15 @@ public:
/** /**
* Getter for the remaining size. * Getter for the remaining size.
*/ */
uint16_t getSizeTillEnd() const; size_t getSizeTillEnd() const;
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
const uint32_t max_size, bool bigEndian) const; Endianness streamEndianness) const override;
uint32_t getSerializedSize() const; size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian); Endianness streamEndianness) override;
}; };
#endif /* POOLRAWACCESS_H_ */ #endif /* POOLRAWACCESS_H_ */

View File

@ -58,7 +58,7 @@ protected:
* The operation does NOT provide any mutual exclusive protection by itself. * The operation does NOT provide any mutual exclusive protection by itself.
*/ */
ReturnValue_t read() { ReturnValue_t read() {
PoolEntry<T>* read_out = ::dataPool.getData<T>(dataPoolId, 1); PoolEntry<T> *read_out = ::dataPool.getData < T > (dataPoolId, 1);
if (read_out != NULL) { if (read_out != NULL) {
valid = read_out->valid; valid = read_out->valid;
value = *(read_out->address); value = *(read_out->address);
@ -79,7 +79,7 @@ protected:
* *
*/ */
ReturnValue_t commit() { ReturnValue_t commit() {
PoolEntry<T>* write_back = ::dataPool.getData<T>(dataPoolId, 1); PoolEntry<T> *write_back = ::dataPool.getData < T > (dataPoolId, 1);
if ((write_back != NULL) && (readWriteMode != VAR_READ)) { if ((write_back != NULL) && (readWriteMode != VAR_READ)) {
write_back->valid = valid; write_back->valid = valid;
*(write_back->address) = value; *(write_back->address) = value;
@ -115,7 +115,7 @@ public:
* \param setWritable If this flag is set to true, changes in the value attribute can be * \param setWritable If this flag is set to true, changes in the value attribute can be
* written back to the data pool, otherwise not. * written back to the data pool, otherwise not.
*/ */
PoolVariable(uint32_t set_id, DataSetIF* dataSet, PoolVariable(uint32_t set_id, DataSetIF *dataSet,
ReadWriteMode_t setReadWriteMode) : ReadWriteMode_t setReadWriteMode) :
dataPoolId(set_id), valid(PoolVariableIF::INVALID), readWriteMode( dataPoolId(set_id), valid(PoolVariableIF::INVALID), readWriteMode(
setReadWriteMode), value(0) { setReadWriteMode), value(0) {
@ -126,7 +126,7 @@ public:
/** /**
* Copy ctor to copy classes containing Pool Variables. * Copy ctor to copy classes containing Pool Variables.
*/ */
PoolVariable(const PoolVariable& rhs) : PoolVariable(const PoolVariable &rhs) :
dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode( dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode(
rhs.readWriteMode), value(rhs.value) { rhs.readWriteMode), value(rhs.value) {
} }
@ -184,29 +184,29 @@ public:
return value; return value;
} }
PoolVariable<T> &operator=(T newValue) { PoolVariable<T>& operator=(T newValue) {
value = newValue; value = newValue;
return *this; return *this;
} }
PoolVariable<T> &operator=(PoolVariable<T> newPoolVariable) { PoolVariable<T>& operator=(PoolVariable<T> newPoolVariable) {
value = newPoolVariable.value; value = newPoolVariable.value;
return *this; return *this;
} }
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const override {
return SerializeAdapter<T>::serialize(&value, buffer, size, max_size, return SerializeAdapter::serialize<T>(&value, buffer, size, maxSize,
bigEndian); streamEndianness);
} }
virtual uint32_t getSerializedSize() const { virtual size_t getSerializedSize() const override {
return SerializeAdapter<T>::getSerializedSize(&value); return SerializeAdapter::getSerializedSize(&value);
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian) { Endianness streamEndianness) override {
return SerializeAdapter<T>::deSerialize(&value, buffer, size, bigEndian); return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness);
} }
}; };

View File

@ -197,13 +197,13 @@ public:
return *this; return *this;
} }
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
uint16_t i; uint16_t i;
ReturnValue_t result; ReturnValue_t result;
for (i = 0; i < vector_size; i++) { for (i = 0; i < vector_size; i++) {
result = SerializeAdapter<T>::serialize(&(value[i]), buffer, size, result = SerializeAdapter::serialize(&(value[i]), buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
@ -211,17 +211,17 @@ public:
return result; return result;
} }
virtual uint32_t getSerializedSize() const { virtual size_t getSerializedSize() const {
return vector_size * SerializeAdapter<T>::getSerializedSize(value); return vector_size * SerializeAdapter::getSerializedSize(value);
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
uint16_t i; uint16_t i;
ReturnValue_t result; ReturnValue_t result;
for (i = 0; i < vector_size; i++) { for (i = 0; i < vector_size; i++) {
result = SerializeAdapter<T>::deSerialize(&(value[i]), buffer, size, result = SerializeAdapter::deSerialize(&(value[i]), buffer, size,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }

View File

@ -2,15 +2,16 @@
#include <framework/devicehandlers/ChildHandlerBase.h> #include <framework/devicehandlers/ChildHandlerBase.h>
#include <framework/subsystem/SubsystemBase.h> #include <framework/subsystem/SubsystemBase.h>
ChildHandlerBase::ChildHandlerBase(uint32_t ioBoardAddress, ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId,
object_id_t setObjectId, object_id_t deviceCommunication, object_id_t deviceCommunication, CookieIF * comCookie,
uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch, uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, uint32_t thermalRequestPoolId, uint32_t parent,
uint32_t parent, FailureIsolationBase* customFdir, uint32_t cmdQueueSize) : FailureIsolationBase* customFdir, size_t cmdQueueSize) :
DeviceHandlerBase(ioBoardAddress, setObjectId, maxDeviceReplyLen, DeviceHandlerBase(setObjectId, deviceCommunication, comCookie,
setDeviceSwitch, deviceCommunication, thermalStatePoolId, setDeviceSwitch, thermalStatePoolId,thermalRequestPoolId,
thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir), cmdQueueSize), parentId( (customFdir == nullptr? &childHandlerFdir : customFdir),
parent), childHandlerFdir(setObjectId) { cmdQueueSize),
parentId(parent), childHandlerFdir(setObjectId) {
} }
ChildHandlerBase::~ChildHandlerBase() { ChildHandlerBase::~ChildHandlerBase() {
@ -34,7 +35,7 @@ ReturnValue_t ChildHandlerBase::initialize() {
parent->registerChild(getObjectId()); parent->registerChild(getObjectId());
} }
healthHelper.setParentQeueue(parentQueue); healthHelper.setParentQueue(parentQueue);
modeHelper.setParentQueue(parentQueue); modeHelper.setParentQueue(parentQueue);

View File

@ -6,12 +6,12 @@
class ChildHandlerBase: public DeviceHandlerBase { class ChildHandlerBase: public DeviceHandlerBase {
public: public:
ChildHandlerBase(uint32_t ioBoardAddress, object_id_t setObjectId, ChildHandlerBase(object_id_t setObjectId,
object_id_t deviceCommunication, uint32_t maxDeviceReplyLen, object_id_t deviceCommunication, CookieIF * comCookie,
uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
uint32_t thermalRequestPoolId, uint32_t parent, uint32_t thermalRequestPoolId, uint32_t parent,
FailureIsolationBase* customFdir = NULL, FailureIsolationBase* customFdir = nullptr,
uint32_t cmdQueueSize = 20); size_t cmdQueueSize = 20);
virtual ~ChildHandlerBase(); virtual ~ChildHandlerBase();
virtual ReturnValue_t initialize(); virtual ReturnValue_t initialize();

View File

@ -1,10 +0,0 @@
#ifndef COOKIE_H_
#define COOKIE_H_
class Cookie{
public:
virtual ~Cookie(){}
};
#endif /* COOKIE_H_ */

34
devicehandlers/CookieIF.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef COOKIE_H_
#define COOKIE_H_
#include <cstdint>
/**
* @brief Physical address type
*/
typedef std::uint32_t address_t;
/**
* @brief This datatype is used to identify different connection over a
* single interface (like RMAP or I2C)
* @details
* To use this class, implement a communication specific child cookie which
* inherits Cookie. Cookie instances are created in config/Factory.cpp by
* calling @code{.cpp} CookieIF* childCookie = new ChildCookie(...)
* @endcode .
*
* [not implemented yet]
* This cookie is then passed to the child device handlers, which stores the
* pointer and passes it to the communication interface functions.
*
* The cookie can be used to store all kinds of information
* about the communication, like slave addresses, communication status,
* communication parameters etc.
*
* @ingroup comm
*/
class CookieIF {
public:
virtual ~CookieIF() {};
};
#endif /* COOKIE_H_ */

View File

@ -1,63 +1,131 @@
#ifndef DEVICECOMMUNICATIONIF_H_ #ifndef DEVICECOMMUNICATIONIF_H_
#define DEVICECOMMUNICATIONIF_H_ #define DEVICECOMMUNICATIONIF_H_
#include <framework/devicehandlers/Cookie.h> #include <framework/devicehandlers/CookieIF.h>
#include <framework/returnvalues/HasReturnvaluesIF.h> #include <framework/returnvalues/HasReturnvaluesIF.h>
#include <cstddef>
/**
* @defgroup interfaces Interfaces
* @brief Interfaces for flight software objects
*/
/**
* @defgroup comm Communication
* @brief Communication software components.
*/
/**
* @brief This is an interface to decouple device communication from
* the device handler to allow reuse of these components.
* @details
* Documentation: Dissertation Baetz p.138.
* It works with the assumption that received data
* is polled by a component. There are four generic steps of device communication:
*
* 1. Send data to a device
* 2. Get acknowledgement for sending
* 3. Request reading data from a device
* 4. Read received data
*
* To identify different connection over a single interface can return
* so-called cookies to components.
* The CommunicationMessage message type can be used to extend the
* functionality of the ComIF if a separate polling task is required.
* @ingroup interfaces
* @ingroup comm
*/
class DeviceCommunicationIF: public HasReturnvaluesIF { class DeviceCommunicationIF: public HasReturnvaluesIF {
public: public:
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_COMMUNICATION_IF; static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_COMMUNICATION_IF;
static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x01); //! Standard Error Codes
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x02); //! General protocol error. Define more concrete errors in child handler
static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x03); static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x01);
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x04); //! If cookie is a null pointer
static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x05); static const ReturnValue_t NULLPOINTER = MAKE_RETURN_CODE(0x02);
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0x06); static const ReturnValue_t INVALID_COOKIE_TYPE = MAKE_RETURN_CODE(0x03);
static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x07); // is this needed if there is no open/close call?
static const ReturnValue_t NOT_ACTIVE = MAKE_RETURN_CODE(0x05);
static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0x06);
static const ReturnValue_t TOO_MUCH_DATA = MAKE_RETURN_CODE(0x07);
static const ReturnValue_t CANT_CHANGE_REPLY_LEN = MAKE_RETURN_CODE(0x08);
virtual ~DeviceCommunicationIF() { //! Can be used in readReceivedMessage() if no reply was received.
static const ReturnValue_t NO_REPLY_RECEIVED = MAKE_RETURN_CODE(0xA1);
} virtual ~DeviceCommunicationIF() {}
virtual ReturnValue_t open(Cookie **cookie, uint32_t address,
uint32_t maxReplyLen) = 0;
/** /**
* Use an existing cookie to open a connection to a new DeviceCommunication. * @brief Device specific initialization, using the cookie.
* The previous connection must not be closed. * @details
* If the returnvalue is not RETURN_OK, the cookie is unchanged and * The cookie is already prepared in the factory. If the communication
* can be used with the previous connection. * interface needs to be set up in some way and requires cookie information,
* this can be performed in this function, which is called on device handler
* initialization.
* @param cookie
* @return
* - @c RETURN_OK if initialization was successfull
* - Everything else triggers failure event with returnvalue as parameter 1
*/
virtual ReturnValue_t initializeInterface(CookieIF * cookie) = 0;
/**
* Called by DHB in the SEND_WRITE doSendWrite().
* This function is used to send data to the physical device
* by implementing and calling related drivers or wrapper functions.
* @param cookie
* @param data
* @param len
* @return
* - @c RETURN_OK for successfull send
* - Everything else triggers failure event with returnvalue as parameter 1
*/
virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData,
size_t sendLen) = 0;
/**
* Called by DHB in the GET_WRITE doGetWrite().
* Get send confirmation that the data in sendMessage() was sent successfully.
* @param cookie
* @return - @c RETURN_OK if data was sent successfull
* - Everything else triggers falure event with
* returnvalue as parameter 1
*/
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) = 0;
/**
* Called by DHB in the SEND_WRITE doSendRead().
* It is assumed that it is always possible to request a reply
* from a device. If a requestLen of 0 is supplied, no reply was enabled
* and communication specific action should be taken (e.g. read nothing
* or read everything).
* *
* @param cookie * @param cookie
* @param address * @param requestLen Size of data to read
* @param maxReplyLen * @return - @c RETURN_OK to confirm the request for data has been sent.
* @return * - Everything else triggers failure event with
* returnvalue as parameter 1
*/ */
virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address, virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie,
uint32_t maxReplyLen) = 0; size_t requestLen) = 0;
virtual void close(Cookie *cookie) = 0;
//SHOULDDO can data be const?
virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data,
uint32_t len) = 0;
virtual ReturnValue_t getSendSuccess(Cookie *cookie) = 0;
virtual ReturnValue_t requestReceiveMessage(Cookie *cookie) = 0;
virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer,
uint32_t *size) = 0;
virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address) = 0;
virtual uint32_t getAddress(Cookie *cookie) = 0;
virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter) = 0;
virtual uint32_t getParameter(Cookie *cookie) = 0;
/**
* Called by DHB in the GET_WRITE doGetRead().
* This function is used to receive data from the physical device
* by implementing and calling related drivers or wrapper functions.
* @param cookie
* @param buffer [out] Set reply here (by using *buffer = ...)
* @param size [out] size pointer to set (by using *size = ...).
* Set to 0 if no reply was received
* @return - @c RETURN_OK for successfull receive
* - @c NO_REPLY_RECEIVED if not reply was received. Setting size to
* 0 has the same effect
* - Everything else triggers failure event with
* returnvalue as parameter 1
*/
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
size_t *size) = 0;
}; };
#endif /* DEVICECOMMUNICATIONIF_H_ */ #endif /* DEVICECOMMUNICATIONIF_H_ */

View File

@ -1,52 +1,60 @@
#include <framework/datapool/DataSet.h>
#include <framework/datapool/PoolVariable.h>
#include <framework/datapool/PoolVector.h>
#include <framework/devicehandlers/AcceptsDeviceResponsesIF.h>
#include <framework/devicehandlers/DeviceHandlerBase.h> #include <framework/devicehandlers/DeviceHandlerBase.h>
#include <framework/devicehandlers/DeviceTmReportingWrapper.h>
#include <framework/globalfunctions/CRC.h>
#include <framework/objectmanager/ObjectManager.h> #include <framework/objectmanager/ObjectManager.h>
#include <framework/storagemanager/StorageManagerIF.h> #include <framework/storagemanager/StorageManagerIF.h>
#include <framework/subsystem/SubsystemBase.h>
#include <framework/thermal/ThermalComponentIF.h> #include <framework/thermal/ThermalComponentIF.h>
#include <framework/devicehandlers/AcceptsDeviceResponsesIF.h>
#include <framework/datapool/DataSet.h>
#include <framework/datapool/PoolVariable.h>
#include <framework/devicehandlers/DeviceTmReportingWrapper.h>
#include <framework/globalfunctions/CRC.h>
#include <framework/subsystem/SubsystemBase.h>
#include <framework/ipc/QueueFactory.h> #include <framework/ipc/QueueFactory.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <iomanip>
object_id_t DeviceHandlerBase::powerSwitcherId = 0; object_id_t DeviceHandlerBase::powerSwitcherId = 0;
object_id_t DeviceHandlerBase::rawDataReceiverId = 0; object_id_t DeviceHandlerBase::rawDataReceiverId = 0;
object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; object_id_t DeviceHandlerBase::defaultFDIRParentId = 0;
DeviceHandlerBase::DeviceHandlerBase(uint32_t ioBoardAddress, DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
object_id_t setObjectId, uint32_t maxDeviceReplyLen, object_id_t deviceCommunication, CookieIF * comCookie,
uint8_t setDeviceSwitch, object_id_t deviceCommunication, uint8_t setDeviceSwitch, uint32_t thermalStatePoolId,
uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, uint32_t thermalRequestPoolId, FailureIsolationBase* fdirInstance,
FailureIsolationBase* fdirInstance, uint32_t cmdQueueSize) : size_t cmdQueueSize) :
SystemObject(setObjectId), rawPacket(0), rawPacketLen(0), mode( SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE),
MODE_OFF), submode(SUBMODE_NONE), pstStep(0), maxDeviceReplyLen( wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS),
maxDeviceReplyLen), wiretappingMode(OFF), defaultRawReceiver(0), storedRawData( deviceCommunicationId(deviceCommunication), comCookie(comCookie),
StorageManagerIF::INVALID_ADDRESS), requestedRawTraffic(0), powerSwitcher( deviceThermalStatePoolId(thermalStatePoolId),
NULL), IPCStore(NULL), deviceCommunicationId(deviceCommunication), communicationInterface( deviceThermalRequestPoolId(thermalRequestPoolId),
NULL), cookie( healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
NULL), commandQueue(NULL), deviceThermalStatePoolId(thermalStatePoolId), deviceThermalRequestPoolId( childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
thermalRequestPoolId), healthHelper(this, setObjectId), modeHelper( hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
this), parameterHelper(this), childTransitionFailure(RETURN_OK), ignoreMissedRepliesCount( switchOffWasReported(false), actionHelper(this, nullptr),
0), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed( childTransitionDelay(5000),
fdirInstance == NULL), switchOffWasReported(false),executingTask(NULL), actionHelper(this, NULL), cookieInfo(), ioBoardAddress( transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode(
ioBoardAddress), timeoutStart(0), childTransitionDelay(5000), transitionSourceMode( SUBMODE_NONE), deviceSwitch(setDeviceSwitch) {
_MODE_POWER_DOWN), transitionSourceSubMode(SUBMODE_NONE), deviceSwitch(
setDeviceSwitch) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
CommandMessage::MAX_MESSAGE_SIZE); CommandMessage::MAX_MESSAGE_SIZE);
cookieInfo.state = COOKIE_UNUSED;
insertInCommandMap(RAW_COMMAND_ID); insertInCommandMap(RAW_COMMAND_ID);
if (this->fdirInstance == NULL) { cookieInfo.state = COOKIE_UNUSED;
cookieInfo.pendingCommand = deviceCommandMap.end();
if (comCookie == nullptr) {
sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex <<
std::setw(8) << std::setfill('0') << this->getObjectId() <<
std::dec << ": Do not pass nullptr as a cookie, consider "
<< std::setfill(' ') << "passing a dummy cookie instead!" <<
std::endl;
}
if (this->fdirInstance == nullptr) {
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
defaultFDIRParentId); defaultFDIRParentId);
} }
} }
DeviceHandlerBase::~DeviceHandlerBase() { DeviceHandlerBase::~DeviceHandlerBase() {
communicationInterface->close(cookie); delete comCookie;
if (defaultFDIRUsed) { if (defaultFDIRUsed) {
delete fdirInstance; delete fdirInstance;
} }
@ -56,7 +64,7 @@ DeviceHandlerBase::~DeviceHandlerBase() {
ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) { ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
this->pstStep = counter; this->pstStep = counter;
if (counter == 0) { if (getComAction() == SEND_WRITE) {
cookieInfo.state = COOKIE_UNUSED; cookieInfo.state = COOKIE_UNUSED;
readCommandQueue(); readCommandQueue();
doStateMachine(); doStateMachine();
@ -64,11 +72,12 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
decrementDeviceReplyMap(); decrementDeviceReplyMap();
fdirInstance->checkForFailures(); fdirInstance->checkForFailures();
hkSwitcher.performOperation(); hkSwitcher.performOperation();
performOperationHook();
} }
if (mode == MODE_OFF) { if (mode == MODE_OFF) {
return RETURN_OK; return RETURN_OK;
} }
switch (getRmapAction()) { switch (getComAction()) {
case SEND_WRITE: case SEND_WRITE:
if ((cookieInfo.state == COOKIE_UNUSED)) { if ((cookieInfo.state == COOKIE_UNUSED)) {
buildInternalCommand(); buildInternalCommand();
@ -91,13 +100,91 @@ ReturnValue_t DeviceHandlerBase::performOperation(uint8_t counter) {
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t DeviceHandlerBase::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return result;
}
communicationInterface = objectManager->get<DeviceCommunicationIF>(
deviceCommunicationId);
if (communicationInterface == NULL) {
return RETURN_FAILED;
}
result = communicationInterface->initializeInterface(comCookie);
if (result != RETURN_OK) {
return result;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == NULL) {
return RETURN_FAILED;
}
AcceptsDeviceResponsesIF *rawReceiver = objectManager->get<
AcceptsDeviceResponsesIF>(rawDataReceiverId);
if (rawReceiver == NULL) {
return RETURN_FAILED;
}
defaultRawReceiver = rawReceiver->getDeviceQueue();
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
if (powerSwitcher == NULL) {
return RETURN_FAILED;
}
result = healthHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = modeHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return result;
}
result = fdirInstance->initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = parameterHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = hkSwitcher.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
fillCommandAndReplyMap();
//Set temperature target state to NON_OP.
DataSet mySet;
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_WRITE);
mySet.read();
thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
mySet.commit(PoolVariableIF::VALID);
return RETURN_OK;
}
void DeviceHandlerBase::decrementDeviceReplyMap() { void DeviceHandlerBase::decrementDeviceReplyMap() {
for (std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter = for (std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
deviceReplyMap.begin(); iter != deviceReplyMap.end(); iter++) { deviceReplyMap.begin(); iter != deviceReplyMap.end(); iter++) {
if (iter->second.delayCycles != 0) { if (iter->second.delayCycles != 0) {
iter->second.delayCycles--; iter->second.delayCycles--;
if (iter->second.delayCycles == 0) { if (iter->second.delayCycles == 0) {
if (iter->second.periodic != 0) { if (iter->second.periodic) {
iter->second.delayCycles = iter->second.maxDelayCycles; iter->second.delayCycles = iter->second.maxDelayCycles;
} }
replyToReply(iter, TIMEOUT); replyToReply(iter, TIMEOUT);
@ -256,55 +343,49 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode,
} }
} }
ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand,
DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, uint16_t maxDelayCycles, size_t replyLen, bool periodic,
uint8_t periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) { bool hasDifferentReplyId, DeviceCommandId_t replyId) {
//No need to check, as we may try to insert multiple times. //No need to check, as we may try to insert multiple times.
insertInCommandMap(deviceCommand); insertInCommandMap(deviceCommand);
if (hasDifferentReplyId) { if (hasDifferentReplyId) {
return insertInReplyMap(replyId, maxDelayCycles, periodic); return insertInReplyMap(replyId, maxDelayCycles, replyLen, periodic);
} else { } else {
return insertInReplyMap(deviceCommand, maxDelayCycles, periodic); return insertInReplyMap(deviceCommand, maxDelayCycles, replyLen, periodic);
} }
} }
ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId,
uint16_t maxDelayCycles, uint8_t periodic) { uint16_t maxDelayCycles, size_t replyLen, bool periodic) {
DeviceReplyInfo info; DeviceReplyInfo info;
info.maxDelayCycles = maxDelayCycles; info.maxDelayCycles = maxDelayCycles;
info.periodic = periodic; info.periodic = periodic;
info.delayCycles = 0; info.delayCycles = 0;
info.replyLen = replyLen;
info.command = deviceCommandMap.end(); info.command = deviceCommandMap.end();
std::pair<std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator, bool> returnValue; auto resultPair = deviceReplyMap.emplace(replyId, info);
returnValue = deviceReplyMap.insert( if (resultPair.second) {
std::pair<DeviceCommandId_t, DeviceReplyInfo>(replyId, info));
if (returnValue.second) {
return RETURN_OK; return RETURN_OK;
} else { } else {
return RETURN_FAILED; return RETURN_FAILED;
} }
} }
ReturnValue_t DeviceHandlerBase::insertInCommandMap( ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) {
DeviceCommandId_t deviceCommand) {
DeviceCommandInfo info; DeviceCommandInfo info;
info.expectedReplies = 0; info.expectedReplies = 0;
info.isExecuting = false; info.isExecuting = false;
info.sendReplyTo = NO_COMMANDER; info.sendReplyTo = NO_COMMANDER;
std::pair<std::map<DeviceCommandId_t, DeviceCommandInfo>::iterator, bool> returnValue; auto resultPair = deviceCommandMap.emplace(deviceCommand, info);
returnValue = deviceCommandMap.insert( if (resultPair.second) {
std::pair<DeviceCommandId_t, DeviceCommandInfo>(deviceCommand,
info));
if (returnValue.second) {
return RETURN_OK; return RETURN_OK;
} else { } else {
return RETURN_FAILED; return RETURN_FAILED;
} }
} }
ReturnValue_t DeviceHandlerBase::updateReplyMapEntry( ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply,
DeviceCommandId_t deviceReply, uint16_t delayCycles, uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) {
uint16_t maxDelayCycles, uint8_t periodic) {
std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter = std::map<DeviceCommandId_t, DeviceReplyInfo>::iterator iter =
deviceReplyMap.find(deviceReply); deviceReplyMap.find(deviceReply);
if (iter == deviceReplyMap.end()) { if (iter == deviceReplyMap.end()) {
@ -429,7 +510,7 @@ void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter,
void DeviceHandlerBase::doSendWrite() { void DeviceHandlerBase::doSendWrite() {
if (cookieInfo.state == COOKIE_WRITE_READY) { if (cookieInfo.state == COOKIE_WRITE_READY) {
ReturnValue_t result = communicationInterface->sendMessage(cookie, ReturnValue_t result = communicationInterface->sendMessage(comCookie,
rawPacket, rawPacketLen); rawPacket, rawPacketLen);
if (result == RETURN_OK) { if (result == RETURN_OK) {
@ -450,12 +531,14 @@ void DeviceHandlerBase::doGetWrite() {
return; return;
} }
cookieInfo.state = COOKIE_UNUSED; cookieInfo.state = COOKIE_UNUSED;
ReturnValue_t result = communicationInterface->getSendSuccess(cookie); ReturnValue_t result = communicationInterface->getSendSuccess(comCookie);
if (result == RETURN_OK) { if (result == RETURN_OK) {
if (wiretappingMode == RAW) { if (wiretappingMode == RAW) {
replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true); replyRawData(rawPacket, rawPacketLen, requestedRawTraffic, true);
} }
//We need to distinguish here, because a raw command never expects a reply. (Could be done in eRIRM, but then child implementations need to be careful.
//We need to distinguish here, because a raw command never expects a reply.
//(Could be done in eRIRM, but then child implementations need to be careful.
result = enableReplyInReplyMap(cookieInfo.pendingCommand); result = enableReplyInReplyMap(cookieInfo.pendingCommand);
} else { } else {
//always generate a failure event, so that FDIR knows what's up //always generate a failure event, so that FDIR knows what's up
@ -471,7 +554,17 @@ void DeviceHandlerBase::doGetWrite() {
void DeviceHandlerBase::doSendRead() { void DeviceHandlerBase::doSendRead() {
ReturnValue_t result; ReturnValue_t result;
result = communicationInterface->requestReceiveMessage(cookie); size_t requestLen = 0;
if(cookieInfo.pendingCommand != deviceCommandMap.end()) {
DeviceReplyIter iter = deviceReplyMap.find(
cookieInfo.pendingCommand->first);
if(iter != deviceReplyMap.end()) {
requestLen = iter->second.replyLen;
}
}
result = communicationInterface->requestReceiveMessage(comCookie, requestLen);
if (result == RETURN_OK) { if (result == RETURN_OK) {
cookieInfo.state = COOKIE_READ_SENT; cookieInfo.state = COOKIE_READ_SENT;
} else { } else {
@ -485,10 +578,10 @@ void DeviceHandlerBase::doSendRead() {
} }
void DeviceHandlerBase::doGetRead() { void DeviceHandlerBase::doGetRead() {
uint32_t receivedDataLen; size_t receivedDataLen;
uint8_t *receivedData; uint8_t *receivedData;
DeviceCommandId_t foundId = 0xFFFFFFFF; DeviceCommandId_t foundId = 0xFFFFFFFF;
uint32_t foundLen = 0; size_t foundLen = 0;
ReturnValue_t result; ReturnValue_t result;
if (cookieInfo.state != COOKIE_READ_SENT) { if (cookieInfo.state != COOKIE_READ_SENT) {
@ -498,8 +591,8 @@ void DeviceHandlerBase::doGetRead() {
cookieInfo.state = COOKIE_UNUSED; cookieInfo.state = COOKIE_UNUSED;
result = communicationInterface->readReceivedMessage(cookie, &receivedData, result = communicationInterface->readReceivedMessage(comCookie,
&receivedDataLen); &receivedData, &receivedDataLen);
if (result != RETURN_OK) { if (result != RETURN_OK) {
triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result); triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result);
@ -508,7 +601,7 @@ void DeviceHandlerBase::doGetRead() {
return; return;
} }
if (receivedDataLen == 0) if (receivedDataLen == 0 or result == DeviceCommunicationIF::NO_REPLY_RECEIVED)
return; return;
if (wiretappingMode == RAW) { if (wiretappingMode == RAW) {
@ -539,6 +632,8 @@ void DeviceHandlerBase::doGetRead() {
break; break;
case IGNORE_REPLY_DATA: case IGNORE_REPLY_DATA:
break; break;
case IGNORE_FULL_PACKET:
return;
default: default:
//We need to wait for timeout.. don't know what command failed and who sent it. //We need to wait for timeout.. don't know what command failed and who sent it.
replyRawReplyIfnotWiretapped(receivedData, foundLen); replyRawReplyIfnotWiretapped(receivedData, foundLen);
@ -560,8 +655,8 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
uint8_t * *data, uint32_t * len) { uint8_t * *data, uint32_t * len) {
size_t lenTmp; size_t lenTmp;
if (IPCStore == NULL) { if (IPCStore == nullptr) {
*data = NULL; *data = nullptr;
*len = 0; *len = 0;
return RETURN_FAILED; return RETURN_FAILED;
} }
@ -572,90 +667,10 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress,
} else { } else {
triggerEvent(StorageManagerIF::GET_DATA_FAILED, result, triggerEvent(StorageManagerIF::GET_DATA_FAILED, result,
storageAddress.raw); storageAddress.raw);
*data = NULL; *data = nullptr;
*len = 0; *len = 0;
return result; return result;
} }
}
ReturnValue_t DeviceHandlerBase::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return result;
}
communicationInterface = objectManager->get<DeviceCommunicationIF>(
deviceCommunicationId);
if (communicationInterface == NULL) {
return RETURN_FAILED;
}
result = communicationInterface->open(&cookie, ioBoardAddress,
maxDeviceReplyLen);
if (result != RETURN_OK) {
return result;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == NULL) {
return RETURN_FAILED;
}
AcceptsDeviceResponsesIF *rawReceiver = objectManager->get<
AcceptsDeviceResponsesIF>(rawDataReceiverId);
if (rawReceiver == NULL) {
return RETURN_FAILED;
}
defaultRawReceiver = rawReceiver->getDeviceQueue();
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
if (powerSwitcher == NULL) {
return RETURN_FAILED;
}
result = healthHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = modeHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return result;
}
result = fdirInstance->initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = parameterHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = hkSwitcher.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
fillCommandAndReplyMap();
//Set temperature target state to NON_OP.
DataSet mySet;
PoolVariable<int8_t> thermalRequest(deviceThermalRequestPoolId, &mySet,
PoolVariableIF::VAR_WRITE);
mySet.read();
thermalRequest = ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL;
mySet.commit(PoolVariableIF::VALID);
return RETURN_OK;
} }
void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
@ -687,8 +702,7 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len,
} }
//Default child implementations //Default child implementations
DeviceHandlerIF::CommunicationAction_t DeviceHandlerBase::getComAction() {
DeviceHandlerBase::RmapAction_t DeviceHandlerBase::getRmapAction() {
switch (pstStep) { switch (pstStep) {
case 0: case 0:
return SEND_WRITE; return SEND_WRITE;
@ -727,7 +741,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
if (info->delayCycles != 0) { if (info->delayCycles != 0) {
if (info->periodic != 0) { if (info->periodic) {
info->delayCycles = info->maxDelayCycles; info->delayCycles = info->maxDelayCycles;
} else { } else {
info->delayCycles = 0; info->delayCycles = 0;
@ -748,20 +762,20 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData,
} }
} }
ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) { //ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) {
DeviceCommunicationIF *newCommunication = objectManager->get< // DeviceCommunicationIF *newCommunication = objectManager->get<
DeviceCommunicationIF>(newChannelId); // DeviceCommunicationIF>(newChannelId);
//
if (newCommunication != NULL) { // if (newCommunication != NULL) {
ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress, // ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress,
maxDeviceReplyLen); // maxDeviceReplyLen);
if (result != RETURN_OK) { // if (result != RETURN_OK) {
return result; // return result;
} // }
return RETURN_OK; // return RETURN_OK;
} // }
return RETURN_FAILED; // return RETURN_FAILED;
} //}
void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) { void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) {
storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage); storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage);
@ -1022,7 +1036,6 @@ void DeviceHandlerBase::replyRawReplyIfnotWiretapped(const uint8_t* data,
ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage( ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
CommandMessage * message) { CommandMessage * message) {
ReturnValue_t result;
switch (message->getCommand()) { switch (message->getCommand()) {
case DeviceHandlerMessage::CMD_WIRETAPPING: case DeviceHandlerMessage::CMD_WIRETAPPING:
switch (DeviceHandlerMessage::getWiretappingMode(message)) { switch (DeviceHandlerMessage::getWiretappingMode(message)) {
@ -1044,19 +1057,19 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
} }
replyReturnvalueToCommand(RETURN_OK); replyReturnvalueToCommand(RETURN_OK);
return RETURN_OK; return RETURN_OK;
case DeviceHandlerMessage::CMD_SWITCH_IOBOARD: // case DeviceHandlerMessage::CMD_SWITCH_IOBOARD:
if (mode != MODE_OFF) { // if (mode != MODE_OFF) {
replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND); // replyReturnvalueToCommand(WRONG_MODE_FOR_COMMAND);
} else { // } else {
result = switchCookieChannel( // result = switchCookieChannel(
DeviceHandlerMessage::getIoBoardObjectId(message)); // DeviceHandlerMessage::getIoBoardObjectId(message));
if (result == RETURN_OK) { // if (result == RETURN_OK) {
replyReturnvalueToCommand(RETURN_OK); // replyReturnvalueToCommand(RETURN_OK);
} else { // } else {
replyReturnvalueToCommand(CANT_SWITCH_IOBOARD); // replyReturnvalueToCommand(CANT_SWITCH_IO_ADDRESS);
} // }
} // }
return RETURN_OK; // return RETURN_OK;
case DeviceHandlerMessage::CMD_RAW: case DeviceHandlerMessage::CMD_RAW:
if ((mode != MODE_RAW)) { if ((mode != MODE_RAW)) {
DeviceHandlerMessage::clear(message); DeviceHandlerMessage::clear(message);
@ -1072,7 +1085,7 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage(
void DeviceHandlerBase::setParentQueue(MessageQueueId_t parentQueueId) { void DeviceHandlerBase::setParentQueue(MessageQueueId_t parentQueueId) {
modeHelper.setParentQueue(parentQueueId); modeHelper.setParentQueue(parentQueueId);
healthHelper.setParentQeueue(parentQueueId); healthHelper.setParentQueue(parentQueueId);
} }
bool DeviceHandlerBase::isAwaitingReply() { bool DeviceHandlerBase::isAwaitingReply() {
@ -1270,3 +1283,9 @@ void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){
executingTask = task_; executingTask = task_;
} }
// Default implementations empty.
void DeviceHandlerBase::debugInterface(uint8_t positionTracker,
object_id_t objectId, uint32_t parameter) {}
void DeviceHandlerBase::performOperationHook() {}

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,8 @@
#include <framework/ipc/MessageQueueSenderIF.h> #include <framework/ipc/MessageQueueSenderIF.h>
/** /**
* This is the Interface used to communicate with a device handler. * @brief This is the Interface used to communicate with a device handler.
* @details Includes all expected return values, events and modes.
* *
*/ */
class DeviceHandlerIF { class DeviceHandlerIF {
@ -22,93 +23,127 @@ public:
* *
* @details The mode of the device handler must not be confused with the mode the device is in. * @details The mode of the device handler must not be confused with the mode the device is in.
* The mode of the device itself is transparent to the user but related to the mode of the handler. * The mode of the device itself is transparent to the user but related to the mode of the handler.
* MODE_ON and MODE_OFF are included in hasModesIF.h
*/ */
// MODE_ON = 0, //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted
// MODE_OFF = 1, //!< The device is powered off. The only command accepted in this mode is a mode change to on.
static const Mode_t MODE_NORMAL = 2; //!< The device is powered on and the device handler periodically sends commands. The commands to be sent are selected by the handler according to the submode.
static const Mode_t MODE_RAW = 3; //!< The device is powered on and ready to perform operations. In this mode, raw commands can be sent. The device handler will send all replies received from the command back to the commanding object.
static const Mode_t MODE_ERROR_ON = 4; //!4< The device is shut down but the switch could not be turned off, so the device still is powered. In this mode, only a mode change to @c MODE_OFF can be commanded, which tries to switch off the device again.
static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5; //!< This is a transitional state which can not be commanded. The device handler performs all commands to get the device in a state ready to perform commands. When this is completed, the mode changes to @c MODE_ON.
static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6; //!< This is a transitional state which can not be commanded. The device handler performs all actions and commands to get the device shut down. When the device is off, the mode changes to @c MODE_OFF.
static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON;
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW;
static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL;
static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1; //!< This is a transitional state which can not be commanded. The device is shut down and ready to be switched off. After the command to set the switch off has been sent, the mode changes to @c MODE_WAIT_OFF
static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2; //!< This is a transitional state which can not be commanded. The device will be switched on in this state. After the command to set the switch on has been sent, the mode changes to @c MODE_WAIT_ON
static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3; //!< This is a transitional state which can not be commanded. The switch has been commanded off and the handler waits for it to be off. When the switch is off, the mode changes to @c MODE_OFF.
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4; //!< This is a transitional state which can not be commanded. The switch has been commanded on and the handler waits for it to be on. When the switch is on, the mode changes to @c MODE_TO_ON.
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5; //!< This is a transitional state which can not be commanded. The switch has been commanded off and is off now. This state is only to do an RMAP cycle once more where the doSendRead() function will set the mode to MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH; // MODE_ON = 0, //!< The device is powered and ready to perform operations. In this mode, no commands are sent by the device handler itself, but direct commands van be commanded and will be interpreted
static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, SEVERITY::LOW); // MODE_OFF = 1, //!< The device is powered off. The only command accepted in this mode is a mode change to on.
static const Event DEVICE_SENDING_COMMAND_FAILED = MAKE_EVENT(1, SEVERITY::LOW); //! The device is powered on and the device handler periodically sends
static const Event DEVICE_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, SEVERITY::LOW); //! commands. The commands to be sent are selected by the handler
static const Event DEVICE_READING_REPLY_FAILED = MAKE_EVENT(3, SEVERITY::LOW); //! according to the submode.
static const Event DEVICE_INTERPRETING_REPLY_FAILED = MAKE_EVENT(4, SEVERITY::LOW); static const Mode_t MODE_NORMAL = 2;
static const Event DEVICE_MISSED_REPLY = MAKE_EVENT(5, SEVERITY::LOW); //! The device is powered on and ready to perform operations. In this mode,
static const Event DEVICE_UNKNOWN_REPLY = MAKE_EVENT(6, SEVERITY::LOW); //! raw commands can be sent. The device handler will send all replies
static const Event DEVICE_UNREQUESTED_REPLY = MAKE_EVENT(7, SEVERITY::LOW); //! received from the command back to the commanding object.
static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, SEVERITY::LOW); //!< Indicates a SW bug in child class. static const Mode_t MODE_RAW = 3;
static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, SEVERITY::LOW); //! The device is shut down but the switch could not be turned off, so the
static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH); //! device still is powered. In this mode, only a mode change to @c MODE_OFF
//! can be commanded, which tries to switch off the device again.
static const Mode_t MODE_ERROR_ON = 4;
//! This is a transitional state which can not be commanded. The device
//! handler performs all commands to get the device in a state ready to
//! perform commands. When this is completed, the mode changes to @c MODE_ON.
static const Mode_t _MODE_START_UP = TRANSITION_MODE_CHILD_ACTION_MASK | 5;
//! This is a transitional state which can not be commanded.
//! The device handler performs all actions and commands to get the device
//! shut down. When the device is off, the mode changes to @c MODE_OFF.
static const Mode_t _MODE_SHUT_DOWN = TRANSITION_MODE_CHILD_ACTION_MASK | 6;
//! It is possible to set the mode to _MODE_TO_ON to use the to on
//! transition if available.
static const Mode_t _MODE_TO_ON = TRANSITION_MODE_CHILD_ACTION_MASK | HasModesIF::MODE_ON;
//! It is possible to set the mode to _MODE_TO_RAW to use the to raw
//! transition if available.
static const Mode_t _MODE_TO_RAW = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_RAW;
//! It is possible to set the mode to _MODE_TO_NORMAL to use the to normal
//! transition if available.
static const Mode_t _MODE_TO_NORMAL = TRANSITION_MODE_CHILD_ACTION_MASK | MODE_NORMAL;
//! This is a transitional state which can not be commanded.
//! The device is shut down and ready to be switched off.
//! After the command to set the switch off has been sent,
//! the mode changes to @c MODE_WAIT_OFF
static const Mode_t _MODE_POWER_DOWN = TRANSITION_MODE_BASE_ACTION_MASK | 1;
//! This is a transitional state which can not be commanded. The device
//! will be switched on in this state. After the command to set the switch
//! on has been sent, the mode changes to @c MODE_WAIT_ON.
static const Mode_t _MODE_POWER_ON = TRANSITION_MODE_BASE_ACTION_MASK | 2;
//! This is a transitional state which can not be commanded. The switch has
//! been commanded off and the handler waits for it to be off.
//! When the switch is off, the mode changes to @c MODE_OFF.
static const Mode_t _MODE_WAIT_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 3;
//! This is a transitional state which can not be commanded. The switch
//! has been commanded on and the handler waits for it to be on.
//! When the switch is on, the mode changes to @c MODE_TO_ON.
static const Mode_t _MODE_WAIT_ON = TRANSITION_MODE_BASE_ACTION_MASK | 4;
//! This is a transitional state which can not be commanded. The switch has
//! been commanded off and is off now. This state is only to do an RMAP
//! cycle once more where the doSendRead() function will set the mode to
//! MODE_OFF. The reason to do this is to get rid of stuck packets in the IO Board.
static const Mode_t _MODE_SWITCH_IS_OFF = TRANSITION_MODE_BASE_ACTION_MASK | 5;
static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CDH;
static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); static const Event DEVICE_BUILDING_COMMAND_FAILED = MAKE_EVENT(0, SEVERITY::LOW);
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); static const Event DEVICE_SENDING_COMMAND_FAILED = MAKE_EVENT(1, SEVERITY::LOW);
static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2); static const Event DEVICE_REQUESTING_REPLY_FAILED = MAKE_EVENT(2, SEVERITY::LOW);
static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3); static const Event DEVICE_READING_REPLY_FAILED = MAKE_EVENT(3, SEVERITY::LOW);
static const ReturnValue_t CANT_SWITCH_IOBOARD = MAKE_RETURN_CODE(0xA4); static const Event DEVICE_INTERPRETING_REPLY_FAILED = MAKE_EVENT(4, SEVERITY::LOW);
static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5); static const Event DEVICE_MISSED_REPLY = MAKE_EVENT(5, SEVERITY::LOW);
static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6); static const Event DEVICE_UNKNOWN_REPLY = MAKE_EVENT(6, SEVERITY::LOW);
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7); static const Event DEVICE_UNREQUESTED_REPLY = MAKE_EVENT(7, SEVERITY::LOW);
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command. static const Event INVALID_DEVICE_COMMAND = MAKE_EVENT(8, SEVERITY::LOW); //!< Indicates a SW bug in child class.
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9); static const Event MONITORING_LIMIT_EXCEEDED = MAKE_EVENT(9, SEVERITY::LOW);
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA); static const Event MONITORING_AMBIGUOUS = MAKE_EVENT(10, SEVERITY::HIGH);
//standard codes used in scan for reply static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF;
// static const ReturnValue_t TOO_SHORT = MAKE_RETURN_CODE(0xB1);
static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB2);
static const ReturnValue_t LENGTH_MISSMATCH = MAKE_RETURN_CODE(0xB3);
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(0xB4);
static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0xB5);
//standard codes used in interpret device reply // Standard codes used when building commands.
static const ReturnValue_t DEVICE_DID_NOT_EXECUTE = MAKE_RETURN_CODE(0xC1); //the device reported, that it did not execute the command static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); //!< If the command size is 0. Checked in DHB
static const ReturnValue_t DEVICE_REPORTED_ERROR = MAKE_RETURN_CODE(0xC2); static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); //!< Command ID not in commandMap. Checked in DHB
static const ReturnValue_t UNKNOW_DEVICE_REPLY = MAKE_RETURN_CODE(0xC3); //the deviceCommandId reported by scanforReply is unknown static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2); //!< Command was already executed. Checked in DHB
static const ReturnValue_t DEVICE_REPLY_INVALID = MAKE_RETURN_CODE(0xC4); //syntax etc is correct but still not ok, eg parameters where none are expected static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3);
static const ReturnValue_t CANT_SWITCH_ADDRESS = MAKE_RETURN_CODE(0xA4);
static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5);
static const ReturnValue_t TIMEOUT = MAKE_RETURN_CODE(0xA6);
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(0xA7);
static const ReturnValue_t NO_REPLY_EXPECTED = MAKE_RETURN_CODE(0xA8); //!< Used to indicate that this is a command-only command.
static const ReturnValue_t NON_OP_TEMPERATURE = MAKE_RETURN_CODE(0xA9);
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xAA);
//Standard codes used in buildCommandFromCommand // Standard codes used in scanForReply
static const ReturnValue_t INVALID_COMMAND_PARAMETER = MAKE_RETURN_CODE( static const ReturnValue_t CHECKSUM_ERROR = MAKE_RETURN_CODE(0xB0);
0xD0); static const ReturnValue_t LENGTH_MISSMATCH = MAKE_RETURN_CODE(0xB1);
static const ReturnValue_t INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS = static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(0xB2);
MAKE_RETURN_CODE(0xD1); static const ReturnValue_t PROTOCOL_ERROR = MAKE_RETURN_CODE(0xB3);
// Standard codes used in interpretDeviceReply
static const ReturnValue_t DEVICE_DID_NOT_EXECUTE = MAKE_RETURN_CODE(0xC0); //the device reported, that it did not execute the command
static const ReturnValue_t DEVICE_REPORTED_ERROR = MAKE_RETURN_CODE(0xC1);
static const ReturnValue_t UNKNOW_DEVICE_REPLY = MAKE_RETURN_CODE(0xC2); //the deviceCommandId reported by scanforReply is unknown
static const ReturnValue_t DEVICE_REPLY_INVALID = MAKE_RETURN_CODE(0xC3); //syntax etc is correct but still not ok, eg parameters where none are expected
// Standard codes used in buildCommandFromCommand
static const ReturnValue_t INVALID_COMMAND_PARAMETER = MAKE_RETURN_CODE(0xD0);
static const ReturnValue_t INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS = MAKE_RETURN_CODE(0xD1);
/**
* Communication action that will be executed.
*
* This is used by the child class to tell the base class what to do.
*/
enum CommunicationAction_t: uint8_t {
SEND_WRITE,//!< Send write
GET_WRITE, //!< Get write
SEND_READ, //!< Send read
GET_READ, //!< Get read
NOTHING //!< Do nothing.
};
/**
* RMAP Action that will be executed.
*
* This is used by the child class to tell the base class what to do.
*/
enum RmapAction_t {
SEND_WRITE,//!< RMAP send write
GET_WRITE, //!< RMAP get write
SEND_READ, //!< RMAP send read
GET_READ, //!< RMAP get read
NOTHING //!< Do nothing.
};
/** /**
* Default Destructor * Default Destructor
*/ */
virtual ~DeviceHandlerIF() { virtual ~DeviceHandlerIF() {}
}
/** /**
* This MessageQueue is used to command the device handler. * This MessageQueue is used to command the device handler.
*
* To command a device handler, a DeviceHandlerCommandMessage can be sent to this Queue.
* The handler replies with a DeviceHandlerCommandMessage containing the DeviceHandlerCommand_t reply.
*
* @return the id of the MessageQueue * @return the id of the MessageQueue
*/ */
virtual MessageQueueId_t getCommandQueue() const = 0; virtual MessageQueueId_t getCommandQueue() const = 0;

View File

@ -12,35 +12,35 @@ DeviceTmReportingWrapper::~DeviceTmReportingWrapper() {
} }
ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer, ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer,
uint32_t* size, const uint32_t max_size, bool bigEndian) const { size_t* size, size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = SerializeAdapter<object_id_t>::serialize(&objectId, ReturnValue_t result = SerializeAdapter::serialize(&objectId,
buffer, size, max_size, bigEndian); buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<ActionId_t>::serialize(&actionId, buffer, result = SerializeAdapter::serialize(&actionId, buffer,
size, max_size, bigEndian); size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return data->serialize(buffer, size, max_size, bigEndian); return data->serialize(buffer, size, maxSize, streamEndianness);
} }
uint32_t DeviceTmReportingWrapper::getSerializedSize() const { size_t DeviceTmReportingWrapper::getSerializedSize() const {
return sizeof(objectId) + sizeof(ActionId_t) + data->getSerializedSize(); return sizeof(objectId) + sizeof(ActionId_t) + data->getSerializedSize();
} }
ReturnValue_t DeviceTmReportingWrapper::deSerialize(const uint8_t** buffer, ReturnValue_t DeviceTmReportingWrapper::deSerialize(const uint8_t** buffer,
int32_t* size, bool bigEndian) { size_t* size, Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter<object_id_t>::deSerialize(&objectId, ReturnValue_t result = SerializeAdapter::deSerialize(&objectId,
buffer, size, bigEndian); buffer, size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<ActionId_t>::deSerialize(&actionId, buffer, result = SerializeAdapter::deSerialize(&actionId, buffer,
size, bigEndian); size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return data->deSerialize(buffer, size, bigEndian); return data->deSerialize(buffer, size, streamEndianness);
} }

View File

@ -11,13 +11,13 @@ public:
SerializeIF *data); SerializeIF *data);
virtual ~DeviceTmReportingWrapper(); virtual ~DeviceTmReportingWrapper();
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
virtual uint32_t getSerializedSize() const; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian); Endianness streamEndianness) override;
private: private:
object_id_t objectId; object_id_t objectId;
ActionId_t actionId; ActionId_t actionId;

View File

@ -16,6 +16,5 @@ FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime,
handler->setTaskIF(executingTask); handler->setTaskIF(executingTask);
} }
FixedSequenceSlot::~FixedSequenceSlot() { FixedSequenceSlot::~FixedSequenceSlot() {}
}

View File

@ -13,35 +13,47 @@
class PeriodicTaskIF; class PeriodicTaskIF;
/** /**
* \brief This class is the representation of a single polling sequence table entry. * @brief This class is the representation of a single polling sequence table entry.
* *
* \details The PollingSlot class is the representation of a single polling sequence table entry. * @details The PollingSlot class is the representation of a single polling
* sequence table entry.
*/ */
class FixedSequenceSlot { class FixedSequenceSlot {
public: public:
FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs, int8_t setSequenceId, PeriodicTaskIF* executingTask ); FixedSequenceSlot( object_id_t handlerId, uint32_t setTimeMs,
int8_t setSequenceId, PeriodicTaskIF* executingTask );
virtual ~FixedSequenceSlot(); virtual ~FixedSequenceSlot();
/** /**
* \brief \c handler identifies which device handler object is executed in this slot. * @brief Handler identifies which device handler object is executed in this slot.
*/ */
ExecutableObjectIF* handler; ExecutableObjectIF* handler;
/** /**
* \brief This attribute defines when a device handler object is executed. * @brief This attribute defines when a device handler object is executed.
* *
* \details The pollingTime attribute identifies the time the handler is executed in ms. It must be * @details The pollingTime attribute identifies the time the handler is executed in ms.
* smaller than the period length of the polling sequence, what is ensured by automated calculation * It must be smaller than the period length of the polling sequence.
* from a database.
*/ */
uint32_t pollingTimeMs; uint32_t pollingTimeMs;
/** /**
* \brief This value defines the type of device communication. * @brief This value defines the type of device communication.
* *
* \details The state of this value decides what communication routine is called in the PST executable or the device handler object. * @details The state of this value decides what communication routine is
* called in the PST executable or the device handler object.
*/ */
uint8_t opcode; uint8_t opcode;
/**
* @brief Operator overload for the comparison operator to
* allow sorting by polling time.
* @param fixedSequenceSlot
* @return
*/
bool operator <(const FixedSequenceSlot & fixedSequenceSlot) const {
return pollingTimeMs < fixedSequenceSlot.pollingTimeMs;
}
}; };

View File

@ -7,17 +7,12 @@ FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) :
} }
FixedSlotSequence::~FixedSlotSequence() { FixedSlotSequence::~FixedSlotSequence() {
std::list<FixedSequenceSlot*>::iterator slotIt; // Call the destructor on each list entry.
//Iterate through slotList and delete all entries. slotList.clear();
slotIt = this->slotList.begin();
while (slotIt != this->slotList.end()) {
delete (*slotIt);
slotIt++;
}
} }
void FixedSlotSequence::executeAndAdvance() { void FixedSlotSequence::executeAndAdvance() {
(*this->current)->handler->performOperation((*this->current)->opcode); current->handler->performOperation(current->opcode);
// if (returnValue != RETURN_OK) { // if (returnValue != RETURN_OK) {
// this->sendErrorMessage( returnValue ); // this->sendErrorMessage( returnValue );
// } // }
@ -31,53 +26,50 @@ void FixedSlotSequence::executeAndAdvance() {
uint32_t FixedSlotSequence::getIntervalToNextSlotMs() { uint32_t FixedSlotSequence::getIntervalToNextSlotMs() {
uint32_t oldTime; uint32_t oldTime;
std::list<FixedSequenceSlot*>::iterator it; SlotListIter slotListIter = current;
it = current;
// Get the pollingTimeMs of the current slot object. // Get the pollingTimeMs of the current slot object.
oldTime = (*it)->pollingTimeMs; oldTime = slotListIter->pollingTimeMs;
// Advance to the next object. // Advance to the next object.
it++; slotListIter++;
// Find the next interval which is not 0. // Find the next interval which is not 0.
while (it != slotList.end()) { while (slotListIter != slotList.end()) {
if (oldTime != (*it)->pollingTimeMs) { if (oldTime != slotListIter->pollingTimeMs) {
return (*it)->pollingTimeMs - oldTime; return slotListIter->pollingTimeMs - oldTime;
} else { } else {
it++; slotListIter++;
} }
} }
// If the list end is reached (this is definitely an interval != 0), // If the list end is reached (this is definitely an interval != 0),
// the interval is calculated by subtracting the remaining time of the PST // the interval is calculated by subtracting the remaining time of the PST
// and adding the start time of the first handler in the list. // and adding the start time of the first handler in the list.
it = slotList.begin(); slotListIter = slotList.begin();
return lengthMs - oldTime + (*it)->pollingTimeMs; return lengthMs - oldTime + slotListIter->pollingTimeMs;
} }
uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() { uint32_t FixedSlotSequence::getIntervalToPreviousSlotMs() {
uint32_t currentTime; uint32_t currentTime;
std::list<FixedSequenceSlot*>::iterator it; SlotListIter slotListIter = current;
it = current;
// Get the pollingTimeMs of the current slot object. // Get the pollingTimeMs of the current slot object.
currentTime = (*it)->pollingTimeMs; currentTime = slotListIter->pollingTimeMs;
//if it is the first slot, calculate difference to last slot //if it is the first slot, calculate difference to last slot
if (it == slotList.begin()){ if (slotListIter == slotList.begin()){
return lengthMs - (*(--slotList.end()))->pollingTimeMs + currentTime; return lengthMs - (--slotList.end())->pollingTimeMs + currentTime;
} }
// get previous slot // get previous slot
it--; slotListIter--;
return currentTime - (*it)->pollingTimeMs; return currentTime - slotListIter->pollingTimeMs;
} }
bool FixedSlotSequence::slotFollowsImmediately() { bool FixedSlotSequence::slotFollowsImmediately() {
uint32_t currentTime = (*current)->pollingTimeMs; uint32_t currentTime = current->pollingTimeMs;
std::list<FixedSequenceSlot*>::iterator it; SlotListIter fixedSequenceIter = this->current;
it = this->current;
// Get the pollingTimeMs of the current slot object. // Get the pollingTimeMs of the current slot object.
if (it == slotList.begin()) if (fixedSequenceIter == slotList.begin())
return false; return false;
it--; fixedSequenceIter--;
if ((*it)->pollingTimeMs == currentTime) { if (fixedSequenceIter->pollingTimeMs == currentTime) {
return true; return true;
} else { } else {
return false; return false;
@ -93,26 +85,30 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl; sif::error << "Fixed Slot Sequence: Slot list is empty!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
auto slotIt = slotList.begin(); auto slotIt = slotList.begin();
uint32_t count = 0; uint32_t count = 0;
uint32_t time = 0; uint32_t time = 0;
while (slotIt != slotList.end()) { while (slotIt != slotList.end()) {
if ((*slotIt)->handler == NULL) { if (slotIt->handler == nullptr) {
sif::error << "FixedSlotSequene::initialize: ObjectId does not exist!" sif::error << "FixedSlotSequene::initialize: ObjectId does not exist!"
<< std::endl; << std::endl;
count++; count++;
} else if ((*slotIt)->pollingTimeMs < time) { } else if (slotIt->pollingTimeMs < time) {
sif::error << "FixedSlotSequence::initialize: Time: " sif::error << "FixedSlotSequence::initialize: Time: "
<< (*slotIt)->pollingTimeMs << slotIt->pollingTimeMs
<< " is smaller than previous with " << time << std::endl; << " is smaller than previous with " << time << std::endl;
count++; count++;
} else { } else {
//All ok, print slot. // All ok, print slot.
// (*slotIt)->print(); //info << "Current slot polling time: " << std::endl;
//info << std::dec << slotIt->pollingTimeMs << std::endl;
} }
time = (*slotIt)->pollingTimeMs; time = slotIt->pollingTimeMs;
slotIt++; slotIt++;
} }
//info << "Number of elements in slot list: "
// << slotList.size() << std::endl;
if (count > 0) { if (count > 0) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
@ -121,8 +117,7 @@ ReturnValue_t FixedSlotSequence::checkSequence() const {
void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs, void FixedSlotSequence::addSlot(object_id_t componentId, uint32_t slotTimeMs,
int8_t executionStep, PeriodicTaskIF* executingTask) { int8_t executionStep, PeriodicTaskIF* executingTask) {
this->slotList.push_back( this->slotList.insert(FixedSequenceSlot(componentId, slotTimeMs, executionStep,
new FixedSequenceSlot(componentId, slotTimeMs, executionStep, executingTask));
executingTask));
this->current = slotList.begin(); this->current = slotList.begin();
} }

View File

@ -1,9 +1,9 @@
#ifndef FIXEDSLOTSEQUENCE_H_ #ifndef FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_
#define FIXEDSLOTSEQUENCE_H_ #define FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_
#include <framework/devicehandlers/FixedSequenceSlot.h> #include <framework/devicehandlers/FixedSequenceSlot.h>
#include <framework/objectmanager/SystemObject.h> #include <framework/objectmanager/SystemObject.h>
#include <list> #include <set>
/** /**
* @brief This class is the representation of a Polling Sequence Table in software. * @brief This class is the representation of a Polling Sequence Table in software.
@ -24,30 +24,39 @@
*/ */
class FixedSlotSequence { class FixedSlotSequence {
public: public:
using SlotList = std::multiset<FixedSequenceSlot>;
using SlotListIter = std::multiset<FixedSequenceSlot>::iterator;
/** /**
* \brief The constructor of the FixedSlotSequence object. * @brief The constructor of the FixedSlotSequence object.
* *
* \details The constructor takes two arguments, the period length and the init function. * @details The constructor takes two arguments, the period length and the init function.
* *
* \param setLength The period length, expressed in ms. * @param setLength The period length, expressed in ms.
*/ */
FixedSlotSequence(uint32_t setLengthMs); FixedSlotSequence(uint32_t setLengthMs);
/** /**
* \brief The destructor of the FixedSlotSequence object. * @brief The destructor of the FixedSlotSequence object.
* *
* \details The destructor frees all allocated memory by iterating through the slotList * @details The destructor frees all allocated memory by iterating through the slotList
* and deleting all allocated resources. * and deleting all allocated resources.
*/ */
virtual ~FixedSlotSequence(); virtual ~FixedSlotSequence();
/** /**
* \brief This is a method to add an PollingSlot object to slotList. * @brief This is a method to add an PollingSlot object to slotList.
* *
* \details Here, a polling slot object is added to the slot list. It is appended * @details Here, a polling slot object is added to the slot list. It is appended
* to the end of the list. The list is currently NOT reordered. * to the end of the list. The list is currently NOT reordered.
* Afterwards, the iterator current is set to the beginning of the list. * Afterwards, the iterator current is set to the beginning of the list.
* @param Object ID of the object to add
* @param setTime Value between (0 to 1) * slotLengthMs, when a FixedTimeslotTask
* will be called inside the slot period.
* @param setSequenceId ID which can be used to distinguish
* different task operations
* @param
* @param
*/ */
void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId, void addSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId,
PeriodicTaskIF* executingTask); PeriodicTaskIF* executingTask);
@ -61,47 +70,59 @@ public:
bool slotFollowsImmediately(); bool slotFollowsImmediately();
/** /**
* \brief This method returns the time until the next software component is invoked. * @brief This method returns the time until the next software
* component is invoked.
* *
* \details This method is vitally important for the operation of the PST. By fetching the polling time * @details
* of the current slot and that of the next one (or the first one, if the list end is reached) * This method is vitally important for the operation of the PST.
* it calculates and returns the interval in milliseconds within which the handler execution * By fetching the polling time of the current slot and that of the
* shall take place. If the next slot has the same time as the current one, it is ignored until * next one (or the first one, if the list end is reached)
* a slot with different time or the end of the PST is found. * it calculates and returns the interval in milliseconds within
* which the handler execution shall take place.
* If the next slot has the same time as the current one, it is ignored
* until a slot with different time or the end of the PST is found.
*/ */
uint32_t getIntervalToNextSlotMs(); uint32_t getIntervalToNextSlotMs();
/** /**
* \brief This method returns the time difference between the current slot and the previous slot * @brief This method returns the time difference between the current
* slot and the previous slot
* *
* \details This method is vitally important for the operation of the PST. By fetching the polling time * @details
* of the current slot and that of the prevous one (or the last one, if the slot is the first one) * This method is vitally important for the operation of the PST.
* it calculates and returns the interval in milliseconds that the handler execution shall be delayed. * By fetching the polling time of the current slot and that of the previous
* one (or the last one, if the slot is the first one) it calculates and
* returns the interval in milliseconds that the handler execution shall
* be delayed.
*/ */
uint32_t getIntervalToPreviousSlotMs(); uint32_t getIntervalToPreviousSlotMs();
/** /**
* \brief This method returns the length of this FixedSlotSequence instance. * @brief This method returns the length of this FixedSlotSequence instance.
*/ */
uint32_t getLengthMs() const; uint32_t getLengthMs() const;
/** /**
* \brief The method to execute the device handler entered in the current OPUSPollingSlot object. * @brief The method to execute the device handler entered in the current
* PollingSlot object.
* *
* \details Within this method the device handler object to be executed is chosen by looking up the * @details
* handler address of the current slot in the handlerMap. Either the device handler's * Within this method the device handler object to be executed is chosen by
* talkToInterface or its listenToInterface method is invoked, depending on the isTalking flag * looking up the handler address of the current slot in the handlerMap.
* of the polling slot. After execution the iterator current is increased or, by reaching the * Either the device handler's talkToInterface or its listenToInterface
* end of slotList, reset to the beginning. * method is invoked, depending on the isTalking flag of the polling slot.
* After execution the iterator current is increased or, by reaching the
* end of slotList, reset to the beginning.
*/ */
void executeAndAdvance(); void executeAndAdvance();
/** /**
* \brief An iterator that indicates the current polling slot to execute. * @brief An iterator that indicates the current polling slot to execute.
* *
* \details This is an iterator for slotList and always points to the polling slot which is executed next. * @details This is an iterator for slotList and always points to the
* polling slot which is executed next.
*/ */
std::list<FixedSequenceSlot*>::iterator current; SlotListIter current;
/** /**
* Iterate through slotList and check successful creation. * Iterate through slotList and check successful creation.
@ -109,18 +130,21 @@ public:
* @return * @return
*/ */
ReturnValue_t checkSequence() const; ReturnValue_t checkSequence() const;
protected: protected:
/** /**
* \brief This list contains all OPUSPollingSlot objects, defining order and execution time of the * @brief This list contains all PollingSlot objects, defining order and
* device handler objects. * execution time of the device handler objects.
* *
* \details The slot list is a std:list object that contains all created OPUSPollingSlot instances. * @details
* They are NOT ordered automatically, so by adding entries, the correct order needs to be ensured. * The slot list is a std:list object that contains all created
* By iterating through this list the polling sequence is executed. Two entries with identical * PollingSlot instances. They are NOT ordered automatically, so by
* polling times are executed immediately one after another. * adding entries, the correct order needs to be ensured. By iterating
* through this list the polling sequence is executed. Two entries with
* identical polling times are executed immediately one after another.
*/ */
std::list<FixedSequenceSlot*> slotList; SlotList slotList;
uint32_t lengthMs; uint32_t lengthMs;
}; };

View File

@ -38,7 +38,7 @@ MessageQueueId_t HealthDevice::getCommandQueue() const {
} }
void HealthDevice::setParentQueue(MessageQueueId_t parentQueue) { void HealthDevice::setParentQueue(MessageQueueId_t parentQueue) {
healthHelper.setParentQeueue(parentQueue); healthHelper.setParentQueue(parentQueue);
} }
bool HealthDevice::hasHealthChanged() { bool HealthDevice::hasHealthChanged() {

View File

@ -11,16 +11,16 @@ class EventRangeMatcherBase: public SerializeableMatcherIF<EventMessage*> {
public: public:
EventRangeMatcherBase(T from, T till, bool inverted) : rangeMatcher(from, till, inverted) { } EventRangeMatcherBase(T from, T till, bool inverted) : rangeMatcher(from, till, inverted) { }
virtual ~EventRangeMatcherBase() { } virtual ~EventRangeMatcherBase() { }
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
return rangeMatcher.serialize(buffer, size, max_size, bigEndian); return rangeMatcher.serialize(buffer, size, maxSize, streamEndianness);
} }
uint32_t getSerializedSize() const { size_t getSerializedSize() const {
return rangeMatcher.getSerializedSize(); return rangeMatcher.getSerializedSize();
} }
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
return rangeMatcher.deSerialize(buffer, size, bigEndian); return rangeMatcher.deSerialize(buffer, size, streamEndianness);
} }
protected: protected:
RangeMatcher<T> rangeMatcher; RangeMatcher<T> rangeMatcher;

View File

@ -59,8 +59,8 @@ uint8_t Type::getSize() const {
} }
} }
ReturnValue_t Type::serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t Type::serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
uint8_t ptc; uint8_t ptc;
uint8_t pfc; uint8_t pfc;
ReturnValue_t result = getPtcPfc(&ptc, &pfc); ReturnValue_t result = getPtcPfc(&ptc, &pfc);
@ -68,36 +68,36 @@ ReturnValue_t Type::serialize(uint8_t** buffer, uint32_t* size,
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&ptc, buffer, size, max_size, result = SerializeAdapter::serialize(&ptc, buffer, size, maxSize,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&pfc, buffer, size, max_size, result = SerializeAdapter::serialize(&pfc, buffer, size, maxSize,
bigEndian); streamEndianness);
return result; return result;
} }
uint32_t Type::getSerializedSize() const { size_t Type::getSerializedSize() const {
uint8_t dontcare = 0; uint8_t dontcare = 0;
return 2 * SerializeAdapter<uint8_t>::getSerializedSize(&dontcare); return 2 * SerializeAdapter::getSerializedSize(&dontcare);
} }
ReturnValue_t Type::deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t Type::deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
uint8_t ptc; uint8_t ptc;
uint8_t pfc; uint8_t pfc;
ReturnValue_t result = SerializeAdapter<uint8_t>::deSerialize(&ptc, buffer, ReturnValue_t result = SerializeAdapter::deSerialize(&ptc, buffer,
size, bigEndian); size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::deSerialize(&pfc, buffer, size, result = SerializeAdapter::deSerialize(&pfc, buffer, size,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }

View File

@ -22,7 +22,7 @@ public:
Type(ActualType_t actualType); Type(ActualType_t actualType);
Type(const Type& type); Type(const Type &type);
Type& operator=(Type rhs); Type& operator=(Type rhs);
@ -30,8 +30,8 @@ public:
operator ActualType_t() const; operator ActualType_t() const;
bool operator==(const Type& rhs); bool operator==(const Type &rhs);
bool operator!=(const Type& rhs); bool operator!=(const Type &rhs);
uint8_t getSize() const; uint8_t getSize() const;
@ -39,13 +39,13 @@ public:
static ActualType_t getActualType(uint8_t ptc, uint8_t pfc); static ActualType_t getActualType(uint8_t ptc, uint8_t pfc);
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
virtual uint32_t getSerializedSize() const; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian); Endianness streamEndianness) override;
private: private:
ActualType_t actualType; ActualType_t actualType;

View File

@ -1,104 +0,0 @@
#include <framework/globalfunctions/conversion.h>
#include <framework/osal/Endiness.h>
#include <cstring>
//SHOULDDO: This shall be optimized (later)!
void convertToByteStream( uint16_t value, uint8_t* buffer, uint32_t* size ) {
buffer[0] = (value & 0xFF00) >> 8;
buffer[1] = (value & 0x00FF);
*size += 2;
}
void convertToByteStream( uint32_t value, uint8_t* buffer, uint32_t* size ) {
buffer[0] = (value & 0xFF000000) >> 24;
buffer[1] = (value & 0x00FF0000) >> 16;
buffer[2] = (value & 0x0000FF00) >> 8;
buffer[3] = (value & 0x000000FF);
*size +=4;
}
void convertToByteStream( int16_t value, uint8_t* buffer, uint32_t* size ) {
buffer[0] = (value & 0xFF00) >> 8;
buffer[1] = (value & 0x00FF);
*size += 2;
}
void convertToByteStream( int32_t value, uint8_t* buffer, uint32_t* size ) {
buffer[0] = (value & 0xFF000000) >> 24;
buffer[1] = (value & 0x00FF0000) >> 16;
buffer[2] = (value & 0x0000FF00) >> 8;
buffer[3] = (value & 0x000000FF);
*size += 4;
}
//void convertToByteStream( uint64_t value, uint8_t* buffer, uint32_t* size ) {
// buffer[0] = (value & 0xFF00000000000000) >> 56;
// buffer[1] = (value & 0x00FF000000000000) >> 48;
// buffer[2] = (value & 0x0000FF0000000000) >> 40;
// buffer[3] = (value & 0x000000FF00000000) >> 32;
// buffer[4] = (value & 0x00000000FF000000) >> 24;
// buffer[5] = (value & 0x0000000000FF0000) >> 16;
// buffer[6] = (value & 0x000000000000FF00) >> 8;
// buffer[7] = (value & 0x00000000000000FF);
// *size+=8;
//}
//
//void convertToByteStream( int64_t value, uint8_t* buffer, uint32_t* size ) {
// buffer[0] = (value & 0xFF00000000000000) >> 56;
// buffer[1] = (value & 0x00FF000000000000) >> 48;
// buffer[2] = (value & 0x0000FF0000000000) >> 40;
// buffer[3] = (value & 0x000000FF00000000) >> 32;
// buffer[4] = (value & 0x00000000FF000000) >> 24;
// buffer[5] = (value & 0x0000000000FF0000) >> 16;
// buffer[6] = (value & 0x000000000000FF00) >> 8;
// buffer[7] = (value & 0x00000000000000FF);
// *size+=8;
//}
void convertToByteStream( float in_value, uint8_t* buffer, uint32_t* size ) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
union float_union {
float value;
uint8_t chars[4];
};
float_union temp;
temp.value = in_value;
buffer[0] = temp.chars[3];
buffer[1] = temp.chars[2];
buffer[2] = temp.chars[1];
buffer[3] = temp.chars[0];
*size += 4;
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
memcpy(buffer, &in_value, sizeof(in_value));
*size += sizeof(in_value);
#endif
}
void convertToByteStream( double in_value, uint8_t* buffer, uint32_t* size ) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
union double_union {
double value;
uint8_t chars[8];
};
double_union temp;
temp.value = in_value;
buffer[0] = temp.chars[7];
buffer[1] = temp.chars[6];
buffer[2] = temp.chars[5];
buffer[3] = temp.chars[4];
buffer[4] = temp.chars[3];
buffer[5] = temp.chars[2];
buffer[6] = temp.chars[1];
buffer[7] = temp.chars[0];
*size += 8;
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
memcpy(buffer, &in_value, sizeof(in_value));
*size += sizeof(in_value);
#endif
}

View File

@ -1,24 +0,0 @@
#ifndef CONVERSION_H_
#define CONVERSION_H_
#include <stdint.h>
void convertToByteStream( uint16_t value, uint8_t* buffer, uint32_t* size );
void convertToByteStream( uint32_t value, uint8_t* buffer, uint32_t* size );
void convertToByteStream( int16_t value, uint8_t* buffer, uint32_t* size );
void convertToByteStream( int32_t value, uint8_t* buffer, uint32_t* size );
//void convertToByteStream( uint64_t value, uint8_t* buffer, uint32_t* size );
//
//void convertToByteStream( int64_t value, uint8_t* buffer, uint32_t* size );
void convertToByteStream( float value, uint8_t* buffer, uint32_t* size );
void convertToByteStream( double value, uint8_t* buffer, uint32_t* size );
#endif /* CONVERSION_H_ */

View File

@ -45,38 +45,38 @@ public:
return matchSubtree(iter, number); return matchSubtree(iter, number);
} }
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, SerializeIF::Endianness streamEndianness) const override {
iterator iter = this->begin(); iterator iter = this->begin();
uint8_t count = this->countRight(iter); uint8_t count = this->countRight(iter);
ReturnValue_t result = SerializeAdapter<uint8_t>::serialize(&count, ReturnValue_t result = SerializeAdapter::serialize(&count,
buffer, size, max_size, bigEndian); buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
if (iter == this->end()) { if (iter == this->end()) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
result = iter->serialize(buffer, size, max_size, bigEndian); result = iter->serialize(buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
if (maxDepth > 0) { if (maxDepth > 0) {
MatchTree<T> temp(iter.left(), maxDepth - 1); MatchTree<T> temp(iter.left(), maxDepth - 1);
result = temp.serialize(buffer, size, max_size, bigEndian); result = temp.serialize(buffer, size, maxSize, streamEndianness);
} }
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
iter = iter.right(); iter = iter.right();
while (iter != this->end()) { while (iter != this->end()) {
result = iter->serialize(buffer, size, max_size, bigEndian); result = iter->serialize(buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
if (maxDepth > 0) { if (maxDepth > 0) {
MatchTree<T> temp(iter.left(), maxDepth - 1); MatchTree<T> temp(iter.left(), maxDepth - 1);
result = temp.serialize(buffer, size, max_size, bigEndian); result = temp.serialize(buffer, size, maxSize, streamEndianness);
} }
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
@ -86,7 +86,7 @@ public:
return result; return result;
} }
uint32_t getSerializedSize() const { size_t getSerializedSize() const override {
//Analogous to serialize! //Analogous to serialize!
uint32_t size = 1; //One for count uint32_t size = 1; //One for count
iterator iter = this->begin(); iterator iter = this->begin();
@ -115,8 +115,8 @@ public:
return size; return size;
} }
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { SerializeIF::Endianness streamEndianness) override {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -4,7 +4,6 @@
#include <framework/globalfunctions/matching/SerializeableMatcherIF.h> #include <framework/globalfunctions/matching/SerializeableMatcherIF.h>
#include <framework/serialize/SerializeAdapter.h> #include <framework/serialize/SerializeAdapter.h>
template<typename T> template<typename T>
class RangeMatcher: public SerializeableMatcherIF<T> { class RangeMatcher: public SerializeableMatcherIF<T> {
public: public:
@ -27,34 +26,40 @@ public:
} }
} }
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
const uint32_t max_size, bool bigEndian) const { SerializeIF::Endianness streamEndianness) const override {
ReturnValue_t result = SerializeAdapter<T>::serialize(&lowerBound, buffer, size, max_size, bigEndian); ReturnValue_t result = SerializeAdapter::serialize(&lowerBound, buffer,
size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<T>::serialize(&upperBound, buffer, size, max_size, bigEndian); result = SerializeAdapter::serialize(&upperBound, buffer, size,
maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return SerializeAdapter<bool>::serialize(&inverted, buffer, size, max_size, bigEndian); return SerializeAdapter::serialize(&inverted, buffer, size, maxSize,
streamEndianness);
} }
uint32_t getSerializedSize() const { size_t getSerializedSize() const override {
return sizeof(lowerBound) + sizeof(upperBound) + sizeof(bool); return sizeof(lowerBound) + sizeof(upperBound) + sizeof(bool);
} }
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian) { SerializeIF::Endianness streamEndianness) override {
ReturnValue_t result = SerializeAdapter<T>::deSerialize(&lowerBound, buffer, size, bigEndian); ReturnValue_t result = SerializeAdapter::deSerialize(&lowerBound,
buffer, size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<T>::deSerialize(&upperBound, buffer, size, bigEndian); result = SerializeAdapter::deSerialize(&upperBound, buffer, size,
streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return SerializeAdapter<bool>::deSerialize(&inverted, buffer, size, bigEndian); return SerializeAdapter::deSerialize(&inverted, buffer, size,
streamEndianness);
} }
protected: protected:
bool doMatch(T input) { bool doMatch(T input) {

View File

@ -29,11 +29,11 @@ HasHealthIF::HealthState HealthHelper::getHealth() {
} }
ReturnValue_t HealthHelper::initialize(MessageQueueId_t parentQueue) { ReturnValue_t HealthHelper::initialize(MessageQueueId_t parentQueue) {
setParentQeueue(parentQueue); setParentQueue(parentQueue);
return initialize(); return initialize();
} }
void HealthHelper::setParentQeueue(MessageQueueId_t parentQueue) { void HealthHelper::setParentQueue(MessageQueueId_t parentQueue) {
this->parentQueue = parentQueue; this->parentQueue = parentQueue;
} }

View File

@ -78,7 +78,7 @@ public:
/** /**
* @param parentQueue the Queue id of the parent object. Set to 0 if no parent present * @param parentQueue the Queue id of the parent object. Set to 0 if no parent present
*/ */
void setParentQeueue(MessageQueueId_t parentQueue); void setParentQueue(MessageQueueId_t parentQueue);
/** /**
* *

View File

@ -63,21 +63,21 @@ bool HealthTable::hasHealth(object_id_t object) {
return exits; return exits;
} }
void HealthTable::printAll(uint8_t* pointer, uint32_t maxSize) { void HealthTable::printAll(uint8_t* pointer, size_t maxSize) {
mutex->lockMutex(MutexIF::NO_TIMEOUT); mutex->lockMutex(MutexIF::NO_TIMEOUT);
uint32_t size = 0; size_t size = 0;
uint16_t count = healthMap.size(); uint16_t count = healthMap.size();
ReturnValue_t result = SerializeAdapter<uint16_t>::serialize(&count, ReturnValue_t result = SerializeAdapter::serialize(&count,
&pointer, &size, maxSize, true); &pointer, &size, maxSize, SerializeIF::Endianness::BIG);
HealthMap::iterator iter; HealthMap::iterator iter;
for (iter = healthMap.begin(); for (iter = healthMap.begin();
iter != healthMap.end() && result == HasReturnvaluesIF::RETURN_OK; iter != healthMap.end() && result == HasReturnvaluesIF::RETURN_OK;
++iter) { ++iter) {
result = SerializeAdapter<object_id_t>::serialize(&iter->first, result = SerializeAdapter::serialize(&iter->first,
&pointer, &size, maxSize, true); &pointer, &size, maxSize, SerializeIF::Endianness::BIG);
uint8_t health = iter->second; uint8_t health = iter->second;
result = SerializeAdapter<uint8_t>::serialize(&health, &pointer, &size, result = SerializeAdapter::serialize(&health, &pointer, &size,
maxSize, true); maxSize, SerializeIF::Endianness::BIG);
} }
mutex->unlockMutex(); mutex->unlockMutex();
} }

View File

@ -21,7 +21,7 @@ public:
virtual HasHealthIF::HealthState getHealth(object_id_t); virtual HasHealthIF::HealthState getHealth(object_id_t);
virtual uint32_t getPrintSize(); virtual uint32_t getPrintSize();
virtual void printAll(uint8_t *pointer, uint32_t maxSize); virtual void printAll(uint8_t *pointer, size_t maxSize);
protected: protected:
MutexIF* mutex; MutexIF* mutex;

View File

@ -17,7 +17,7 @@ public:
HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0; HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0;
virtual uint32_t getPrintSize() = 0; virtual uint32_t getPrintSize() = 0;
virtual void printAll(uint8_t *pointer, uint32_t maxSize) = 0; virtual void printAll(uint8_t *pointer, size_t maxSize) = 0;
protected: protected:
virtual ReturnValue_t iterate(std::pair<object_id_t,HasHealthIF::HealthState> *value, bool reset = false) = 0; virtual ReturnValue_t iterate(std::pair<object_id_t,HasHealthIF::HealthState> *value, bool reset = false) = 0;

View File

@ -18,8 +18,8 @@ public:
*/ */
static QueueFactory* instance(); static QueueFactory* instance();
MessageQueueIF* createMessageQueue(uint32_t message_depth = 3, MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3,
uint32_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE); size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE);
void deleteMessageQueue(MessageQueueIF* queue); void deleteMessageQueue(MessageQueueIF* queue);
private: private:

View File

@ -2,7 +2,7 @@
#include <framework/memory/MemoryHelper.h> #include <framework/memory/MemoryHelper.h>
#include <framework/memory/MemoryMessage.h> #include <framework/memory/MemoryMessage.h>
#include <framework/objectmanager/ObjectManagerIF.h> #include <framework/objectmanager/ObjectManagerIF.h>
#include <framework/serialize/EndianSwapper.h> #include <framework/serialize/EndianConverter.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
MemoryHelper::MemoryHelper(HasMemoryIF* workOnThis, MessageQueueIF* useThisQueue) : MemoryHelper::MemoryHelper(HasMemoryIF* workOnThis, MessageQueueIF* useThisQueue) :
@ -53,7 +53,7 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode,
memcpy(copyHere, dataToCopy, size); memcpy(copyHere, dataToCopy, size);
break; break;
case HasMemoryIF::POINTS_TO_VARIABLE: case HasMemoryIF::POINTS_TO_VARIABLE:
EndianSwapper::swap(copyHere, dataToCopy, size); EndianConverter::convertBigEndian(copyHere, dataToCopy, size);
break; break;
case HasMemoryIF::ACTIVITY_COMPLETED: case HasMemoryIF::ACTIVITY_COMPLETED:
case RETURN_OK: case RETURN_OK:
@ -86,7 +86,7 @@ void MemoryHelper::completeDump(ReturnValue_t errorCode,
case HasMemoryIF::POINTS_TO_VARIABLE: case HasMemoryIF::POINTS_TO_VARIABLE:
//"data" must be valid pointer! //"data" must be valid pointer!
if (errorCode == HasMemoryIF::POINTS_TO_VARIABLE) { if (errorCode == HasMemoryIF::POINTS_TO_VARIABLE) {
EndianSwapper::swap(reservedSpaceInIPC, dataToCopy, size); EndianConverter::convertBigEndian(reservedSpaceInIPC, dataToCopy, size);
} else { } else {
memcpy(reservedSpaceInIPC, dataToCopy, size); memcpy(reservedSpaceInIPC, dataToCopy, size);
} }
@ -136,7 +136,7 @@ void MemoryHelper::swapMatrixCopy(uint8_t* out, const uint8_t *in,
} }
while (totalSize > 0){ while (totalSize > 0){
EndianSwapper::swap(out,in,datatypeSize); EndianConverter::convertBigEndian(out,in,datatypeSize);
out += datatypeSize; out += datatypeSize;
in += datatypeSize; in += datatypeSize;
totalSize -= datatypeSize; totalSize -= datatypeSize;

View File

@ -17,7 +17,7 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF
} }
store_address_t storeId; store_address_t storeId;
uint8_t* dataTarget = NULL; uint8_t* dataTarget = NULL;
uint32_t maxSize = data->getSerializedSize(); size_t maxSize = data->getSerializedSize();
if (maxSize > MonitoringIF::VIOLATION_REPORT_MAX_SIZE) { if (maxSize > MonitoringIF::VIOLATION_REPORT_MAX_SIZE) {
return MonitoringIF::INVALID_SIZE; return MonitoringIF::INVALID_SIZE;
} }
@ -26,8 +26,8 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
uint32_t size = 0; size_t size = 0;
result = data->serialize(&dataTarget, &size, maxSize, true); result = data->serialize(&dataTarget, &size, maxSize, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }

View File

@ -1,5 +1,6 @@
#include <framework/objectmanager/ObjectManager.h> #include <framework/objectmanager/ObjectManager.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <iomanip>
#include <cstdlib> #include <cstdlib>
ObjectManager::ObjectManager( void (*setProducer)() ): ObjectManager::ObjectManager( void (*setProducer)() ):

View File

@ -1,16 +1,18 @@
#include <framework/timemanager/Clock.h> #include <framework/timemanager/Clock.h>
#include <framework/globalfunctions/timevalOperations.h> #include <framework/globalfunctions/timevalOperations.h>
#include <stdlib.h> #include <framework/osal/FreeRTOS/Timekeeper.h>
#include "Timekeeper.h"
#include <FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <task.h> #include <freertos/task.h>
#include <stdlib.h>
#include <time.h>
//TODO sanitize input? //TODO sanitize input?
//TODO much of this code can be reused for tick-only systems //TODO much of this code can be reused for tick-only systems
uint16_t Clock::leapSeconds = 0; uint16_t Clock::leapSeconds = 0;
MutexIF* Clock::timeMutex = NULL; MutexIF* Clock::timeMutex = nullptr;
uint32_t Clock::getTicksPerSecond(void) { uint32_t Clock::getTicksPerSecond(void) {
return 1000; return 1000;
@ -56,7 +58,6 @@ ReturnValue_t Clock::getUptime(timeval* uptime) {
timeval Clock::getUptime() { timeval Clock::getUptime() {
TickType_t ticksSinceStart = xTaskGetTickCount(); TickType_t ticksSinceStart = xTaskGetTickCount();
return Timekeeper::ticksToTimeval(ticksSinceStart); return Timekeeper::ticksToTimeval(ticksSinceStart);
} }
@ -128,7 +129,7 @@ ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) {
ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) {
//SHOULDDO: works not for dates in the past (might have less leap seconds) //SHOULDDO: works not for dates in the past (might have less leap seconds)
if (timeMutex == NULL) { if (timeMutex == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }

View File

@ -1,6 +1,7 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h>
#include "FixedTimeslotTask.h" #include "FixedTimeslotTask.h"
#include <framework/serviceinterface/ServiceInterfaceStream.h>
uint32_t FixedTimeslotTask::deadlineMissedCount = 0; uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE;
@ -18,16 +19,19 @@ FixedTimeslotTask::~FixedTimeslotTask() {
void FixedTimeslotTask::taskEntryPoint(void* argument) { void FixedTimeslotTask::taskEntryPoint(void* argument) {
//The argument is re-interpreted as FixedTimeslotTask. The Task object is global, so it is found from any place. // The argument is re-interpreted as FixedTimeslotTask. The Task object is
// global, so it is found from any place.
FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(argument)); FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(argument));
// Task should not start until explicitly requested /* Task should not start until explicitly requested,
// in FreeRTOS, tasks start as soon as they are created if the scheduler is running * but in FreeRTOS, tasks start as soon as they are created if the scheduler
// but not if the scheduler is not running. * is running but not if the scheduler is not running.
// to be able to accommodate both cases we check a member which is set in #startTask() * To be able to accommodate both cases we check a member which is set in
// if it is not set and we get here, the scheduler was started before #startTask() was called and we need to suspend * #startTask(). If it is not set and we get here, the scheduler was started
// if it is set, the scheduler was not running before #startTask() was called and we can continue * before #startTask() was called and we need to suspend if it is set,
* the scheduler was not running before #startTask() was called and we
* can continue */
if (!originalTask->started) { if (not originalTask->started) {
vTaskSuspend(NULL); vTaskSuspend(NULL);
} }
@ -58,11 +62,6 @@ ReturnValue_t FixedTimeslotTask::startTask() {
ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId,
uint32_t slotTimeMs, int8_t executionStep) { uint32_t slotTimeMs, int8_t executionStep) {
if (objectManager->get<ExecutableObjectIF>(componentId) != nullptr) { if (objectManager->get<ExecutableObjectIF>(componentId) != nullptr) {
if(slotTimeMs == 0) {
// FreeRTOS throws a sanity error for zero values, so we set
// the time to one millisecond.
slotTimeMs = 1;
}
pst.addSlot(componentId, slotTimeMs, executionStep, this); pst.addSlot(componentId, slotTimeMs, executionStep, this);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -81,43 +80,79 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const {
} }
void FixedTimeslotTask::taskFunctionality() { void FixedTimeslotTask::taskFunctionality() {
// A local iterator for the Polling Sequence Table is created to find the start time for the first entry. // A local iterator for the Polling Sequence Table is created to find the
std::list<FixedSequenceSlot*>::iterator it = pst.current; // start time for the first entry.
FixedSlotSequence::SlotListIter slotListIter = pst.current;
//The start time for the first entry is read. //The start time for the first entry is read.
uint32_t intervalMs = (*it)->pollingTimeMs; uint32_t intervalMs = slotListIter->pollingTimeMs;
TickType_t interval = pdMS_TO_TICKS(intervalMs); TickType_t interval = pdMS_TO_TICKS(intervalMs);
TickType_t xLastWakeTime; TickType_t xLastWakeTime;
/* The xLastWakeTime variable needs to be initialized with the current tick /* The xLastWakeTime variable needs to be initialized with the current tick
count. Note that this is the only time the variable is written to explicitly. count. Note that this is the only time the variable is written to
After this assignment, xLastWakeTime is updated automatically internally within explicitly. After this assignment, xLastWakeTime is updated automatically
vTaskDelayUntil(). */ internally within vTaskDelayUntil(). */
xLastWakeTime = xTaskGetTickCount(); xLastWakeTime = xTaskGetTickCount();
// wait for first entry's start time // wait for first entry's start time
vTaskDelayUntil(&xLastWakeTime, interval); if(interval > 0) {
vTaskDelayUntil(&xLastWakeTime, interval);
}
/* Enter the loop that defines the task behavior. */ /* Enter the loop that defines the task behavior. */
for (;;) { for (;;) {
//The component for this slot is executed and the next one is chosen. //The component for this slot is executed and the next one is chosen.
this->pst.executeAndAdvance(); this->pst.executeAndAdvance();
if (pst.slotFollowsImmediately()) { if (not pst.slotFollowsImmediately()) {
//Do nothing // Get the interval till execution of the next slot.
} else { intervalMs = this->pst.getIntervalToPreviousSlotMs();
// we need to wait before executing the current slot interval = pdMS_TO_TICKS(intervalMs);
//this gives us the time to wait:
intervalMs = this->pst.getIntervalToPreviousSlotMs();
interval = pdMS_TO_TICKS(intervalMs);
vTaskDelayUntil(&xLastWakeTime, interval);
//TODO deadline missed check
}
checkMissedDeadline(xLastWakeTime, interval);
// Wait for the interval. This exits immediately if a deadline was
// missed while also updating the last wake time.
vTaskDelayUntil(&xLastWakeTime, interval);
}
} }
} }
void FixedTimeslotTask::checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval) {
/* Check whether deadline was missed while also taking overflows
* into account. Drawing this on paper with a timeline helps to understand
* it. */
TickType_t currentTickCount = xTaskGetTickCount();
TickType_t timeToWake = xLastWakeTime + interval;
// Tick count has overflown
if(currentTickCount < xLastWakeTime) {
// Time to wake has overflown as well. If the tick count
// is larger than the time to wake, a deadline was missed.
if(timeToWake < xLastWakeTime and
currentTickCount > timeToWake) {
handleMissedDeadline();
}
}
// No tick count overflow. If the timeToWake has not overflown
// and the current tick count is larger than the time to wake,
// a deadline was missed.
else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) {
handleMissedDeadline();
}
}
void FixedTimeslotTask::handleMissedDeadline() {
#ifdef DEBUG
sif::warning << "FixedTimeslotTask: " << pcTaskGetName(NULL) <<
" missed deadline!\n" << std::flush;
#endif
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
}
ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) {
vTaskDelay(pdMS_TO_TICKS(ms)); vTaskDelay(pdMS_TO_TICKS(ms));
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -1,24 +1,27 @@
#ifndef POLLINGTASK_H_ #ifndef FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_
#define POLLINGTASK_H_ #define FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_
#include <framework/devicehandlers/FixedSlotSequence.h> #include <framework/devicehandlers/FixedSlotSequence.h>
#include <framework/tasks/FixedTimeslotTaskIF.h> #include <framework/tasks/FixedTimeslotTaskIF.h>
#include <framework/tasks/Typedef.h> #include <framework/tasks/Typedef.h>
#include <FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include "task.h" #include <freertos/task.h>
class FixedTimeslotTask: public FixedTimeslotTaskIF { class FixedTimeslotTask: public FixedTimeslotTaskIF {
public: public:
/** /**
* @brief The standard constructor of the class. * Keep in mind that you need to call before vTaskStartScheduler()!
* * A lot of task parameters are set in "FreeRTOSConfig.h".
* @details This is the general constructor of the class. In addition to the TaskBase parameters, * @param name Name of the task, lenght limited by configMAX_TASK_NAME_LEN
* the following variables are passed: * @param setPriority Number of priorities specified by
* * configMAX_PRIORITIES. High taskPriority_ number means high priority.
* @param (*setDeadlineMissedFunc)() The function pointer to the deadline missed function that shall be assigned. * @param setStack Stack size in words (not bytes!).
* * Lower limit specified by configMINIMAL_STACK_SIZE
* @param getPst The object id of the completely initialized polling sequence. * @param overallPeriod Period in seconds.
* @param setDeadlineMissedFunc Callback if a deadline was missed.
* @return Pointer to the newly created task.
*/ */
FixedTimeslotTask(const char *name, TaskPriority setPriority, FixedTimeslotTask(const char *name, TaskPriority setPriority,
TaskStackSize setStack, TaskPeriod overallPeriod, TaskStackSize setStack, TaskPeriod overallPeriod,
@ -26,16 +29,18 @@ public:
/** /**
* @brief The destructor of the class. * @brief The destructor of the class.
* * @details
* @details The destructor frees all heap memory that was allocated on thread initialization for the PST and * The destructor frees all heap memory that was allocated on thread
* the device handlers. This is done by calling the PST's destructor. * initialization for the PST and the device handlers. This is done by
* calling the PST's destructor.
*/ */
virtual ~FixedTimeslotTask(void); virtual ~FixedTimeslotTask(void);
ReturnValue_t startTask(void); ReturnValue_t startTask(void);
/** /**
* This static function can be used as #deadlineMissedFunc. * This static function can be used as #deadlineMissedFunc.
* It counts missedDeadlines and prints the number of missed deadlines every 10th time. * It counts missedDeadlines and prints the number of missed deadlines
* every 10th time.
*/ */
static void missedDeadlineCounter(); static void missedDeadlineCounter();
/** /**
@ -44,13 +49,14 @@ public:
static uint32_t deadlineMissedCount; static uint32_t deadlineMissedCount;
ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs,
int8_t executionStep); int8_t executionStep) override;
uint32_t getPeriodMs() const; uint32_t getPeriodMs() const override;
ReturnValue_t checkSequence() const; ReturnValue_t checkSequence() const override;
ReturnValue_t sleepFor(uint32_t ms) override;
ReturnValue_t sleepFor(uint32_t ms);
protected: protected:
bool started; bool started;
TaskHandle_t handle; TaskHandle_t handle;
@ -58,32 +64,35 @@ protected:
FixedSlotSequence pst; FixedSlotSequence pst;
/** /**
* @brief This attribute holds a function pointer that is executed when a deadline was missed. * @brief This attribute holds a function pointer that is executed when
* * a deadline was missed.
* @details Another function may be announced to determine the actions to perform when a deadline was missed. * @details
* Currently, only one function for missing any deadline is allowed. * Another function may be announced to determine the actions to perform
* If not used, it shall be declared NULL. * when a deadline was missed. Currently, only one function for missing
* any deadline is allowed. If not used, it shall be declared NULL.
*/ */
void (*deadlineMissedFunc)(void); void (*deadlineMissedFunc)(void);
/** /**
* @brief This is the entry point in a new polling thread. * @brief This is the entry point for a new task.
* * @details
* @details This method, that is the generalOSAL::checkAndRestartPeriod( this->periodId, interval ); entry point in the new thread, is here set to generate * This method starts the task by calling taskFunctionality(), as soon as
* and link the Polling Sequence Table to the thread object and start taskFunctionality() * all requirements (task scheduler has started and startTask()
* on success. If operation of the task is ended for some reason, * has been called) are met.
* the destructor is called to free allocated memory.
*/ */
static void taskEntryPoint(void* argument); static void taskEntryPoint(void* argument);
/** /**
* @brief This function holds the main functionality of the thread. * @brief This function holds the main functionality of the thread.
* * @details
* * Core function holding the main functionality of the task
* @details Holding the main functionality of the task, this method is most important. * It links the functionalities provided by FixedSlotSequence with the
* It links the functionalities provided by FixedSlotSequence with the OS's System Calls * OS's System Calls to keep the timing of the periods.
* to keep the timing of the periods.
*/ */
void taskFunctionality(void); void taskFunctionality(void);
void checkMissedDeadline(const TickType_t xLastWakeTime,
const TickType_t interval);
void handleMissedDeadline();
}; };
#endif /* POLLINGTASK_H_ */ #endif /* FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ */

View File

@ -25,8 +25,8 @@ QueueFactory::~QueueFactory() {
} }
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth,
uint32_t max_message_size) { size_t maxMessageSize) {
return new MessageQueue(message_depth, max_message_size); return new MessageQueue(message_depth, maxMessageSize);
} }
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {

View File

@ -1,20 +1,19 @@
#include "Timekeeper.h" #include <framework/osal/FreeRTOS/Timekeeper.h>
#include <FreeRTOSConfig.h>
Timekeeper::Timekeeper() : #include "FreeRTOSConfig.h"
offset( { 0, 0 }) {
// TODO Auto-generated constructor stub
} Timekeeper * Timekeeper::myinstance = nullptr;
Timekeeper * Timekeeper::myinstance = NULL; Timekeeper::Timekeeper() : offset( { 0, 0 } ) {}
Timekeeper::~Timekeeper() {}
const timeval& Timekeeper::getOffset() const { const timeval& Timekeeper::getOffset() const {
return offset; return offset;
} }
Timekeeper* Timekeeper::instance() { Timekeeper* Timekeeper::instance() {
if (myinstance == NULL) { if (myinstance == nullptr) {
myinstance = new Timekeeper(); myinstance = new Timekeeper();
} }
return myinstance; return myinstance;
@ -24,10 +23,6 @@ void Timekeeper::setOffset(const timeval& offset) {
this->offset = offset; this->offset = offset;
} }
Timekeeper::~Timekeeper() {
// TODO Auto-generated destructor stub
}
timeval Timekeeper::ticksToTimeval(TickType_t ticks) { timeval Timekeeper::ticksToTimeval(TickType_t ticks) {
timeval uptime; timeval uptime;
uptime.tv_sec = ticks / configTICK_RATE_HZ; uptime.tv_sec = ticks / configTICK_RATE_HZ;
@ -40,3 +35,7 @@ timeval Timekeeper::ticksToTimeval(TickType_t ticks) {
return uptime; return uptime;
} }
TickType_t Timekeeper::getTicks() {
return xTaskGetTickCount();
}

View File

@ -3,7 +3,9 @@
#include <framework/timemanager/Clock.h> #include <framework/timemanager/Clock.h>
#include <FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/task.h>
/** /**
* A Class to basically store the time difference between uptime and UTC * A Class to basically store the time difference between uptime and UTC
@ -25,6 +27,11 @@ public:
virtual ~Timekeeper(); virtual ~Timekeeper();
static timeval ticksToTimeval(TickType_t ticks); static timeval ticksToTimeval(TickType_t ticks);
/**
* Get elapsed time in system ticks.
* @return
*/
static TickType_t getTicks();
const timeval& getOffset() const; const timeval& getOffset() const;
void setOffset(const timeval& offset); void setOffset(const timeval& offset);

View File

@ -1,10 +1,10 @@
#include <sys/time.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <time.h>
#include <framework/timemanager/Clock.h> #include <framework/timemanager/Clock.h>
#include <sys/time.h>
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <linux/sysinfo.h> #include <linux/sysinfo.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
//#include <fstream> //#include <fstream>
@ -65,6 +65,15 @@ ReturnValue_t Clock::getClock_usecs(uint64_t* time) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
timeval Clock::getUptime() {
timeval uptime;
auto result = getUptime(&uptime);
if(result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Clock::getUptime: Error getting uptime" << std::endl;
}
return uptime;
}
ReturnValue_t Clock::getUptime(timeval* uptime) { ReturnValue_t Clock::getUptime(timeval* uptime) {
//TODO This is not posix compatible and delivers only seconds precision //TODO This is not posix compatible and delivers only seconds precision
struct sysinfo sysInfo; struct sysinfo sysInfo;

View File

@ -1,10 +1,7 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <unistd.h>
#include <limits.h>
#include <signal.h>
#include <errno.h>
#include <framework/osal/linux/FixedTimeslotTask.h> #include <framework/osal/linux/FixedTimeslotTask.h>
#include <limits.h>
uint32_t FixedTimeslotTask::deadlineMissedCount = 0; uint32_t FixedTimeslotTask::deadlineMissedCount = 0;
const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN;
@ -23,7 +20,7 @@ void* FixedTimeslotTask::taskEntryPoint(void* arg) {
FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(arg)); FixedTimeslotTask *originalTask(reinterpret_cast<FixedTimeslotTask*>(arg));
//The task's functionality is called. //The task's functionality is called.
originalTask->taskFunctionality(); originalTask->taskFunctionality();
return NULL; return nullptr;
} }
ReturnValue_t FixedTimeslotTask::startTask() { ReturnValue_t FixedTimeslotTask::startTask() {

View File

@ -8,7 +8,20 @@
class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread { class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread {
public: public:
FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_); /**
* Create a generic periodic task.
* @param name_
* Name, maximum allowed size of linux is 16 chars, everything else will
* be truncated.
* @param priority_
* Real-time priority, ranges from 1 to 99 for Linux.
* See: https://man7.org/linux/man-pages/man7/sched.7.html
* @param stackSize_
* @param period_
* @param deadlineMissedFunc_
*/
FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_,
uint32_t periodMs_);
virtual ~FixedTimeslotTask(); virtual ~FixedTimeslotTask();
virtual ReturnValue_t startTask(); virtual ReturnValue_t startTask();
@ -17,7 +30,9 @@ public:
virtual uint32_t getPeriodMs() const; virtual uint32_t getPeriodMs() const;
virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs,
int8_t executionStep);
virtual ReturnValue_t checkSequence() const; virtual ReturnValue_t checkSequence() const;
/** /**
@ -34,11 +49,10 @@ public:
protected: protected:
/** /**
* @brief This function holds the main functionality of the thread. * @brief This function holds the main functionality of the thread.
* * @details
* * Holding the main functionality of the task, this method is most important.
* @details Holding the main functionality of the task, this method is most important. * It links the functionalities provided by FixedSlotSequence with the
* It links the functionalities provided by FixedSlotSequence with the OS's System Calls * OS's System Calls to keep the timing of the periods.
* to keep the timing of the periods.
*/ */
virtual void taskFunctionality(); virtual void taskFunctionality();
@ -46,8 +60,13 @@ private:
/** /**
* @brief This is the entry point in a new thread. * @brief This is the entry point in a new thread.
* *
* @details This method, that is the entry point in the new thread and calls taskFunctionality of the child class. * @details
* Needs a valid pointer to the derived class. * This method, that is the entry point in the new thread and calls
* taskFunctionality of the child class. Needs a valid pointer to the
* derived class.
*
* The void* returnvalue is not used yet but could be used to return
* arbitrary data.
*/ */
static void* taskEntryPoint(void* arg); static void* taskEntryPoint(void* arg);
FixedSlotSequence pst; FixedSlotSequence pst;

View File

@ -1,56 +1,37 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <mqueue.h>
#include <cstring>
#include <errno.h>
#include <framework/osal/linux/MessageQueue.h> #include <framework/osal/linux/MessageQueue.h>
#include <fstream>
MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : #include <fcntl.h> /* For O_* constants */
id(0), lastPartner(0), defaultDestination(NO_QUEUE) { #include <sys/stat.h> /* For mode constants */
#include <cstring>
#include <errno.h>
MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize):
id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE),
defaultDestination(MessageQueueIF::NO_QUEUE) {
//debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl;
mq_attr attributes; mq_attr attributes;
this->id = 0; this->id = 0;
//Set attributes //Set attributes
attributes.mq_curmsgs = 0; attributes.mq_curmsgs = 0;
attributes.mq_maxmsg = message_depth; attributes.mq_maxmsg = messageDepth;
attributes.mq_msgsize = max_message_size; attributes.mq_msgsize = maxMessageSize;
attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open
//Set the name of the queue //Set the name of the queue. The slash is mandatory!
sprintf(name, "/Q%u\n", queueCounter++); sprintf(name, "/FSFW_MQ%u\n", queueCounter++);
//Create a nonblocking queue if the name is available (the queue is Read and // Create a nonblocking queue if the name is available (the queue is read
// writable for the owner as well as the group) // and writable for the owner as well as the group)
mqd_t tempId = mq_open(name, O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, int oflag = O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL;
S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH, &attributes); mode_t mode = S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH;
mqd_t tempId = mq_open(name, oflag, mode, &attributes);
if (tempId == -1) { if (tempId == -1) {
//An error occured during open handleError(&attributes, messageDepth);
//We need to distinguish if it is caused by an already created queue }
if (errno == EEXIST) { else {
//There's another queue with the same name
//We unlink the other queue
int status = mq_unlink(name);
if (status != 0) {
sif::error << "mq_unlink Failed with status: " << strerror(errno)
<< std::endl;
} else {
//Successful unlinking, try to open again
mqd_t tempId = mq_open(name,
O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL,
S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, &attributes);
if (tempId != -1) {
//Successful mq_open
this->id = tempId;
return;
}
}
}
//Failed either the first time or the second time
sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex
<< name << std::dec << " failed with status: "
<< strerror(errno) << std::endl;
} else {
//Successful mq_open call //Successful mq_open call
this->id = tempId; this->id = tempId;
} }
@ -69,6 +50,73 @@ MessageQueue::~MessageQueue() {
} }
} }
ReturnValue_t MessageQueue::handleError(mq_attr* attributes,
uint32_t messageDepth) {
switch(errno) {
case(EINVAL): {
sif::error << "MessageQueue::MessageQueue: Invalid name or attributes"
" for message size" << std::endl;
size_t defaultMqMaxMsg = 0;
// Not POSIX conformant, but should work for all UNIX systems.
// Just an additional helpful printout :-)
if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >>
defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) {
// See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html
// This happens if the msg_max value is not large enough
// It is ignored if the executable is run in privileged mode.
// Run the unlockRealtime script or grant the mode manually by using:
// sudo setcap 'CAP_SYS_RESOURCE=+ep' <pathToBinary>
// Persistent solution for session:
// echo <newMsgMax> | sudo tee /proc/sys/fs/mqueue/msg_max
// Permanent solution:
// sudo nano /etc/sysctl.conf
// Append at end: fs/mqueue/msg_max = <newMsgMaxLen>
// Apply changes with: sudo sysctl -p
sif::error << "MessageQueue::MessageQueue: Default MQ size "
<< defaultMqMaxMsg << " is too small for requested size "
<< messageDepth << std::endl;
}
break;
}
case(EEXIST): {
// An error occured during open
// We need to distinguish if it is caused by an already created queue
//There's another queue with the same name
//We unlink the other queue
int status = mq_unlink(name);
if (status != 0) {
sif::error << "mq_unlink Failed with status: " << strerror(errno)
<< std::endl;
}
else {
// Successful unlinking, try to open again
mqd_t tempId = mq_open(name,
O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL,
S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes);
if (tempId != -1) {
//Successful mq_open
this->id = tempId;
return HasReturnvaluesIF::RETURN_OK;
}
}
break;
}
default:
// Failed either the first time or the second time
sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex
<< name << std::dec << " failed with status: "
<< strerror(errno) << std::endl;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo,
MessageQueueMessage* message, bool ignoreFault) { MessageQueueMessage* message, bool ignoreFault) {
return sendMessageFrom(sendTo, message, this->getId(), false); return sendMessageFrom(sendTo, message, this->getId(), false);
@ -108,12 +156,13 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
//Success but no message received //Success but no message received
return MessageQueueIF::EMPTY; return MessageQueueIF::EMPTY;
} else { } else {
//No message was received. Keep lastPartner anyway, I might send something later. //No message was received. Keep lastPartner anyway, I might send
//But still, delete packet content. //something later. But still, delete packet content.
memset(message->getData(), 0, message->MAX_DATA_SIZE); memset(message->getData(), 0, message->MAX_DATA_SIZE);
switch(errno){ switch(errno){
case EAGAIN: case EAGAIN:
//O_NONBLOCK or MQ_NONBLOCK was set and there are no messages currently on the specified queue. //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages
//currently on the specified queue.
return MessageQueueIF::EMPTY; return MessageQueueIF::EMPTY;
case EBADF: case EBADF:
//mqdes doesn't represent a valid queue open for reading. //mqdes doesn't represent a valid queue open for reading.
@ -123,9 +172,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
case EINVAL: case EINVAL:
/* /*
* This value indicates one of the following: * This value indicates one of the following:
* * The pointer to the buffer for storing the received message, msg_ptr, is NULL. * - The pointer to the buffer for storing the received message,
* * The number of bytes requested, msg_len is less than zero. * msg_ptr, is NULL.
* * msg_len is anything other than the mq_msgsize of the specified queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't been set in the queue's mq_flags. * - The number of bytes requested, msg_len is less than zero.
* - msg_len is anything other than the mq_msgsize of the specified
* queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't
* been set in the queue's mq_flags.
*/ */
sif::error << "MessageQueue::receive: configuration error " sif::error << "MessageQueue::receive: configuration error "
<< strerror(errno) << std::endl; << strerror(errno) << std::endl;
@ -133,8 +185,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) {
case EMSGSIZE: case EMSGSIZE:
/* /*
* This value indicates one of the following: * This value indicates one of the following:
* * the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, and the given msg_len is shorter than the mq_msgsize for the given queue. * - the QNX extended option MQ_READBUF_DYNAMIC hasn't been set,
* * the extended option MQ_READBUF_DYNAMIC has been set, but the given msg_len is too short for the message that would have been received. * and the given msg_len is shorter than the mq_msgsize for
* the given queue.
* - the extended option MQ_READBUF_DYNAMIC has been set, but the
* given msg_len is too short for the message that would have
* been received.
*/ */
sif::error << "MessageQueue::receive: configuration error " sif::error << "MessageQueue::receive: configuration error "
<< strerror(errno) << std::endl; << strerror(errno) << std::endl;
@ -182,9 +238,10 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) {
case EINVAL: case EINVAL:
/* /*
* This value indicates one of the following: * This value indicates one of the following:
* * mq_attr is NULL. * - mq_attr is NULL.
* * MQ_MULT_NOTIFY had been set for this queue, and the given mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once MQ_MULT_NOTIFY has been turned on, it may never be turned off. * - MQ_MULT_NOTIFY had been set for this queue, and the given
* * mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once
* MQ_MULT_NOTIFY has been turned on, it may never be turned off.
*/ */
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
@ -233,7 +290,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
//TODO: Check if we're in ISR. //TODO: Check if we're in ISR.
if (result != 0) { if (result != 0) {
if(!ignoreFault){ if(!ignoreFault){
InternalErrorReporterIF* internalErrorReporter = objectManager->get<InternalErrorReporterIF>( InternalErrorReporterIF* internalErrorReporter =
objectManager->get<InternalErrorReporterIF>(
objects::INTERNAL_ERROR_REPORTER); objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != NULL) { if (internalErrorReporter != NULL) {
internalErrorReporter->queueMessageNotSent(); internalErrorReporter->queueMessageNotSent();
@ -241,10 +299,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
} }
switch(errno){ switch(errno){
case EAGAIN: case EAGAIN:
//The O_NONBLOCK flag was set when opening the queue, or the MQ_NONBLOCK flag was set in its attributes, and the specified queue is full. //The O_NONBLOCK flag was set when opening the queue, or the
//MQ_NONBLOCK flag was set in its attributes, and the
//specified queue is full.
return MessageQueueIF::FULL; return MessageQueueIF::FULL;
case EBADF: case EBADF:
//mq_des doesn't represent a valid message queue descriptor, or mq_des wasn't opened for writing. //mq_des doesn't represent a valid message queue descriptor,
//or mq_des wasn't opened for writing.
sif::error << "MessageQueue::sendMessage: Configuration error " sif::error << "MessageQueue::sendMessage: Configuration error "
<< strerror(errno) << " in mq_send mqSendTo: " << sendTo << strerror(errno) << " in mq_send mqSendTo: " << sendTo
<< " sent from " << sentFrom << std::endl; << " sent from " << sentFrom << std::endl;
@ -254,18 +315,22 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
case EINVAL: case EINVAL:
/* /*
* This value indicates one of the following: * This value indicates one of the following:
* * msg_ptr is NULL. * - msg_ptr is NULL.
* * msg_len is negative. * - msg_len is negative.
* * msg_prio is greater than MQ_PRIO_MAX. * - msg_prio is greater than MQ_PRIO_MAX.
* * msg_prio is less than 0. * - msg_prio is less than 0.
* * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, * - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and
* and msg_prio is greater than the priority of the calling process. * msg_prio is greater than the priority of the calling process.
* */ */
sif::error << "MessageQueue::sendMessage: Configuration error " sif::error << "MessageQueue::sendMessage: Configuration error "
<< strerror(errno) << " in mq_send" << std::endl; << strerror(errno) << " in mq_send" << std::endl;
/*NO BREAK*/ /*NO BREAK*/
case EMSGSIZE: case EMSGSIZE:
//The msg_len is greater than the msgsize associated with the specified queue. // The msg_len is greater than the msgsize associated with
//the specified queue.
sif::error << "MessageQueue::sendMessage: Size error [" <<
strerror(errno) << "] in mq_send" << std::endl;
/*NO BREAK*/
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }

View File

@ -4,21 +4,26 @@
#include <framework/internalError/InternalErrorReporterIF.h> #include <framework/internalError/InternalErrorReporterIF.h>
#include <framework/ipc/MessageQueueIF.h> #include <framework/ipc/MessageQueueIF.h>
#include <framework/ipc/MessageQueueMessage.h> #include <framework/ipc/MessageQueueMessage.h>
#include <mqueue.h>
/** /**
* @brief This class manages sending and receiving of message queue messages. * @brief This class manages sending and receiving of message queue messages.
* *
* @details Message queues are used to pass asynchronous messages between processes. * @details
* They work like post boxes, where all incoming messages are stored in FIFO * Message queues are used to pass asynchronous messages between processes.
* order. This class creates a new receiving queue and provides methods to fetch * They work like post boxes, where all incoming messages are stored in FIFO
* received messages. Being a child of MessageQueueSender, this class also provides * order. This class creates a new receiving queue and provides methods to fetch
* methods to send a message to a user-defined or a default destination. In addition * received messages. Being a child of MessageQueueSender, this class also
* it also provides a reply method to answer to the queue it received its last message * provides methods to send a message to a user-defined or a default destination.
* from. * In addition it also provides a reply method to answer to the queue it
* The MessageQueue should be used as "post box" for a single owning object. So all * received its last message from.
* message queue communication is "n-to-one". *
* For creating the queue, as well as sending and receiving messages, the class makes * The MessageQueue should be used as "post box" for a single owning object.
* use of the operating system calls provided. * So all message queue communication is "n-to-one".
* \ingroup message_queue *
* The creation of message queues, as well as sending and receiving messages,
* makes use of the operating system calls provided.
* @ingroup message_queue
*/ */
class MessageQueue : public MessageQueueIF { class MessageQueue : public MessageQueueIF {
friend class MessageQueueSenderIF; friend class MessageQueueSenderIF;
@ -35,7 +40,8 @@ public:
* @param max_message_size With this parameter, the maximum message size can be adjusted. * @param max_message_size With this parameter, the maximum message size can be adjusted.
* This should be left default. * This should be left default.
*/ */
MessageQueue( size_t message_depth = 3, size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE ); MessageQueue(uint32_t messageDepth = 3,
size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE );
/** /**
* @brief The destructor deletes the formerly created message queue. * @brief The destructor deletes the formerly created message queue.
* @details This is accomplished by using the delete call provided by the operating system. * @details This is accomplished by using the delete call provided by the operating system.
@ -168,6 +174,8 @@ private:
char name[5]; char name[5];
static uint16_t queueCounter; static uint16_t queueCounter;
ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth);
}; };
#endif /* MESSAGEQUEUE_H_ */ #endif /* MESSAGEQUEUE_H_ */

View File

@ -3,9 +3,10 @@
#include <errno.h> #include <errno.h>
#include <framework/osal/linux/PeriodicPosixTask.h> #include <framework/osal/linux/PeriodicPosixTask.h>
PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()):PosixThread(name_,priority_,stackSize_),objectList(),started(false),periodMs(period_),deadlineMissedFunc( PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_,
deadlineMissedFunc_) { size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()):
PosixThread(name_,priority_,stackSize_),objectList(),started(false),
periodMs(period_),deadlineMissedFunc(deadlineMissedFunc_) {
} }
PeriodicPosixTask::~PeriodicPosixTask() { PeriodicPosixTask::~PeriodicPosixTask() {
@ -37,7 +38,8 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) {
ReturnValue_t PeriodicPosixTask::startTask(void){ ReturnValue_t PeriodicPosixTask::startTask(void){
started = true; started = true;
createTask(&taskEntryPoint,this); //sif::info << stackSize << std::endl;
PosixThread::createTask(&taskEntryPoint,this);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -56,9 +58,11 @@ void PeriodicPosixTask::taskFunctionality(void){
char name[20] = {0}; char name[20] = {0};
int status = pthread_getname_np(pthread_self(),name,sizeof(name)); int status = pthread_getname_np(pthread_self(),name,sizeof(name));
if(status==0){ if(status==0){
sif::error << "ObjectTask: " << name << " Deadline missed." << std::endl; sif::error << "PeriodicPosixTask " << name << ": Deadline "
"missed." << std::endl;
}else{ }else{
sif::error << "ObjectTask: X Deadline missed. " << status << std::endl; sif::error << "PeriodicPosixTask X: Deadline missed. " <<
status << std::endl;
} }
if (this->deadlineMissedFunc != NULL) { if (this->deadlineMissedFunc != NULL) {
this->deadlineMissedFunc(); this->deadlineMissedFunc();

View File

@ -9,9 +9,22 @@
class PeriodicPosixTask: public PosixThread, public PeriodicTaskIF { class PeriodicPosixTask: public PosixThread, public PeriodicTaskIF {
public: public:
/**
* Create a generic periodic task.
* @param name_
* Name, maximum allowed size of linux is 16 chars, everything else will
* be truncated.
* @param priority_
* Real-time priority, ranges from 1 to 99 for Linux.
* See: https://man7.org/linux/man-pages/man7/sched.7.html
* @param stackSize_
* @param period_
* @param deadlineMissedFunc_
*/
PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_,
uint32_t period_, void(*deadlineMissedFunc_)()); uint32_t period_, void(*deadlineMissedFunc_)());
virtual ~PeriodicPosixTask(); virtual ~PeriodicPosixTask();
/** /**
* @brief The method to start the task. * @brief The method to start the task.
* @details The method starts the task with the respective system call. * @details The method starts the task with the respective system call.

View File

@ -1,8 +1,13 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/osal/linux/PosixThread.h>
#include <cstring> #include <cstring>
#include <errno.h> #include <errno.h>
#include <framework/osal/linux/PosixThread.h>
PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_):
thread(0),priority(priority_),stackSize(stackSize_) {
name[0] = '\0';
std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1);
}
PosixThread::~PosixThread() { PosixThread::~PosixThread() {
//No deletion and no free of Stack Pointer //No deletion and no free of Stack Pointer
@ -55,10 +60,6 @@ void PosixThread::resume(){
pthread_kill(thread,SIGUSR1); pthread_kill(thread,SIGUSR1);
} }
bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms, bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms,
const uint64_t delayTime_ms) { const uint64_t delayTime_ms) {
uint64_t nextTimeToWake_ms; uint64_t nextTimeToWake_ms;
@ -113,12 +114,6 @@ uint64_t PosixThread::getCurrentMonotonicTimeMs(){
return currentTime_ms; return currentTime_ms;
} }
PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_):
thread(0),priority(priority_),stackSize(stackSize_) {
strcpy(name,name_);
}
void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
//sif::debug << "PosixThread::createTask" << std::endl; //sif::debug << "PosixThread::createTask" << std::endl;
@ -135,14 +130,24 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
sif::error << "Posix Thread attribute init failed with: " << sif::error << "Posix Thread attribute init failed with: " <<
strerror(status) << std::endl; strerror(status) << std::endl;
} }
void* sp; void* stackPointer;
status = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stackSize); status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize);
if(status != 0){ if(status != 0){
sif::error << "Posix Thread stack init failed with: " << sif::error << "PosixThread::createTask: Stack init failed with: " <<
strerror(status) << std::endl; strerror(status) << std::endl;
if(errno == ENOMEM) {
uint64_t stackMb = stackSize/10e6;
sif::error << "PosixThread::createTask: Insufficient memory for"
" the requested " << stackMb << " MB" << std::endl;
}
else if(errno == EINVAL) {
sif::error << "PosixThread::createTask: Wrong alignment argument!"
<< std::endl;
}
return;
} }
status = pthread_attr_setstack(&attributes, sp, stackSize); status = pthread_attr_setstack(&attributes, stackPointer, stackSize);
if(status != 0){ if(status != 0){
sif::error << "Posix Thread attribute setStack failed with: " << sif::error << "Posix Thread attribute setStack failed with: " <<
strerror(status) << std::endl; strerror(status) << std::endl;
@ -154,7 +159,7 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
strerror(status) << std::endl; strerror(status) << std::endl;
} }
//TODO FIFO -> This needs root privileges for the process // TODO FIFO -> This needs root privileges for the process
status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO); status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO);
if(status != 0){ if(status != 0){
sif::error << "Posix Thread attribute schedule policy failed with: " << sif::error << "Posix Thread attribute schedule policy failed with: " <<
@ -188,8 +193,18 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) {
status = pthread_setname_np(thread,name); status = pthread_setname_np(thread,name);
if(status != 0){ if(status != 0){
sif::error << "Posix Thread setname failed with: " << sif::error << "PosixThread::createTask: setname failed with: " <<
strerror(status) << std::endl; strerror(status) << std::endl;
if(status == ERANGE) {
sif::error << "PosixThread::createTask: Task name length longer"
" than 16 chars. Truncating.." << std::endl;
name[15] = '\0';
status = pthread_setname_np(thread,name);
if(status != 0){
sif::error << "PosixThread::createTask: Setting name"
" did not work.." << std::endl;
}
}
} }
status = pthread_attr_destroy(&attributes); status = pthread_attr_destroy(&attributes);

View File

@ -1,15 +1,15 @@
#ifndef FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ #ifndef FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_
#define FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ #define FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <framework/returnvalues/HasReturnvaluesIF.h> #include <framework/returnvalues/HasReturnvaluesIF.h>
#include <pthread.h>
#include <signal.h>
#include <cstdlib>
#include <unistd.h>
class PosixThread { class PosixThread {
public: public:
static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16;
PosixThread(const char* name_, int priority_, size_t stackSize_); PosixThread(const char* name_, int priority_, size_t stackSize_);
virtual ~PosixThread(); virtual ~PosixThread();
/** /**
@ -54,21 +54,24 @@ protected:
pthread_t thread; pthread_t thread;
/** /**
* @brief Function that has to be called by derived class because the derived class pointer has to be valid as argument * @brief Function that has to be called by derived class because the
* @details This function creates a pthread with the given parameters. As the function requires a pointer to the derived object * derived class pointer has to be valid as argument.
* it has to be called after the this pointer of the derived object is valid. Sets the taskEntryPoint as * @details
* function to be called by new a thread. * This function creates a pthread with the given parameters. As the
* @param name_ Name of the task * function requires a pointer to the derived object it has to be called
* @param priority_ Priority of the task according to POSIX * after the this pointer of the derived object is valid.
* @param stackSize_ Size of the stack attached to that task * Sets the taskEntryPoint as function to be called by new a thread.
* @param arg_ argument of the taskEntryPoint function, needs to be this pointer of derived class * @param fnc_ Function which will be executed by the thread.
* @param arg_
* argument of the taskEntryPoint function, needs to be this pointer
* of derived class
*/ */
void createTask(void* (*fnc_)(void*),void* arg_); void createTask(void* (*fnc_)(void*),void* arg_);
private: private:
char name[10]; char name[PTHREAD_MAX_NAMELEN];
int priority; int priority;
size_t stackSize; size_t stackSize = 0;
}; };
#endif /* FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ */ #endif /* FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ */

View File

@ -5,16 +5,18 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <cstring> #include <cstring>
QueueFactory* QueueFactory::factoryInstance = NULL; QueueFactory* QueueFactory::factoryInstance = nullptr;
ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo,
MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) { MessageQueueMessage* message, MessageQueueId_t sentFrom,
return MessageQueue::sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault); bool ignoreFault) {
return MessageQueue::sendMessageFromMessageQueue(sendTo,message,
sentFrom,ignoreFault);
} }
QueueFactory* QueueFactory::instance() { QueueFactory* QueueFactory::instance() {
if (factoryInstance == NULL) { if (factoryInstance == nullptr) {
factoryInstance = new QueueFactory; factoryInstance = new QueueFactory;
} }
return factoryInstance; return factoryInstance;
@ -26,9 +28,9 @@ QueueFactory::QueueFactory() {
QueueFactory::~QueueFactory() { QueueFactory::~QueueFactory() {
} }
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth,
uint32_t max_message_size) { size_t maxMessageSize) {
return new MessageQueue(message_depth, max_message_size); return new MessageQueue(messageDepth, maxMessageSize);
} }
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {

View File

@ -13,12 +13,20 @@ TaskFactory* TaskFactory::instance() {
return TaskFactory::factoryInstance; return TaskFactory::factoryInstance;
} }
PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) { PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,
return static_cast<PeriodicTaskIF*>(new PeriodicPosixTask(name_, taskPriority_,stackSize_,periodInSeconds_ * 1000,deadLineMissedFunction_)); TaskPriority taskPriority_,TaskStackSize stackSize_,
TaskPeriod periodInSeconds_,
TaskDeadlineMissedFunction deadLineMissedFunction_) {
return new PeriodicPosixTask(name_, taskPriority_,stackSize_,
periodInSeconds_ * 1000, deadLineMissedFunction_);
} }
FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) { FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_,
return static_cast<FixedTimeslotTaskIF*>(new FixedTimeslotTask(name_, taskPriority_,stackSize_,periodInSeconds_*1000)); TaskPriority taskPriority_,TaskStackSize stackSize_,
TaskPeriod periodInSeconds_,
TaskDeadlineMissedFunction deadLineMissedFunction_) {
return new FixedTimeslotTask(name_, taskPriority_,stackSize_,
periodInSeconds_*1000);
} }
ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) {

View File

@ -89,15 +89,15 @@ void CpuUsage::clear() {
threadData.clear(); threadData.clear();
} }
ReturnValue_t CpuUsage::serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t CpuUsage::serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = SerializeAdapter<float>::serialize( ReturnValue_t result = SerializeAdapter::serialize(
&timeSinceLastReset, buffer, size, max_size, bigEndian); &timeSinceLastReset, buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return SerialArrayListAdapter<ThreadData>::serialize(&threadData, buffer, return SerialArrayListAdapter<ThreadData>::serialize(&threadData, buffer,
size, max_size, bigEndian); size, maxSize, streamEndianness);
} }
uint32_t CpuUsage::getSerializedSize() const { uint32_t CpuUsage::getSerializedSize() const {
@ -109,37 +109,37 @@ uint32_t CpuUsage::getSerializedSize() const {
return size; return size;
} }
ReturnValue_t CpuUsage::deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t CpuUsage::deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter<float>::deSerialize( ReturnValue_t result = SerializeAdapter::deSerialize(
&timeSinceLastReset, buffer, size, bigEndian); &timeSinceLastReset, buffer, size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return SerialArrayListAdapter<ThreadData>::deSerialize(&threadData, buffer, return SerialArrayListAdapter<ThreadData>::deSerialize(&threadData, buffer,
size, bigEndian); size, streamEndianness);
} }
ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = SerializeAdapter<uint32_t>::serialize(&id, buffer, ReturnValue_t result = SerializeAdapter::serialize(&id, buffer,
size, max_size, bigEndian); size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
if (*size + MAX_LENGTH_OF_THREAD_NAME > max_size) { if (*size + MAX_LENGTH_OF_THREAD_NAME > maxSize) {
return BUFFER_TOO_SHORT; return BUFFER_TOO_SHORT;
} }
memcpy(*buffer, name, MAX_LENGTH_OF_THREAD_NAME); memcpy(*buffer, name, MAX_LENGTH_OF_THREAD_NAME);
*size += MAX_LENGTH_OF_THREAD_NAME; *size += MAX_LENGTH_OF_THREAD_NAME;
*buffer += MAX_LENGTH_OF_THREAD_NAME; *buffer += MAX_LENGTH_OF_THREAD_NAME;
result = SerializeAdapter<float>::serialize(&timeRunning, result = SerializeAdapter::serialize(&timeRunning,
buffer, size, max_size, bigEndian); buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<float>::serialize(&percentUsage, result = SerializeAdapter::serialize(&percentUsage,
buffer, size, max_size, bigEndian); buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
@ -158,9 +158,9 @@ uint32_t CpuUsage::ThreadData::getSerializedSize() const {
} }
ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer, ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer,
int32_t* size, bool bigEndian) { int32_t* size, Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter<uint32_t>::deSerialize(&id, buffer, ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer,
size, bigEndian); size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
@ -169,13 +169,13 @@ ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer,
} }
memcpy(name, *buffer, MAX_LENGTH_OF_THREAD_NAME); memcpy(name, *buffer, MAX_LENGTH_OF_THREAD_NAME);
*buffer -= MAX_LENGTH_OF_THREAD_NAME; *buffer -= MAX_LENGTH_OF_THREAD_NAME;
result = SerializeAdapter<float>::deSerialize(&timeRunning, result = SerializeAdapter::deSerialize(&timeRunning,
buffer, size, bigEndian); buffer, size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<float>::deSerialize(&percentUsage, result = SerializeAdapter::deSerialize(&percentUsage,
buffer, size, bigEndian); buffer, size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }

View File

@ -18,13 +18,13 @@ public:
float timeRunning; float timeRunning;
float percentUsage; float percentUsage;
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
virtual uint32_t getSerializedSize() const; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian); Endianness streamEndianness) override;
}; };
CpuUsage(); CpuUsage();
@ -41,13 +41,13 @@ public:
void clear(); void clear();
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
virtual uint32_t getSerializedSize() const; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian); Endianness streamEndianness) override;
}; };
#endif /* CPUUSAGE_H_ */ #endif /* CPUUSAGE_H_ */

View File

@ -49,9 +49,9 @@ QueueFactory::QueueFactory() {
QueueFactory::~QueueFactory() { QueueFactory::~QueueFactory() {
} }
MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth,
uint32_t max_message_size) { size_t maxMessageSize) {
return new MessageQueue(message_depth, max_message_size); return new MessageQueue(messageDepth, maxMessageSize);
} }
void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) {

View File

@ -83,7 +83,7 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) {
ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id,
const ParameterWrapper* description) { const ParameterWrapper* description) {
uint32_t serializedSize = description->getSerializedSize(); size_t serializedSize = description->getSerializedSize();
uint8_t *storeElement; uint8_t *storeElement;
store_address_t address; store_address_t address;
@ -94,10 +94,10 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id,
return result; return result;
} }
uint32_t storeElementSize = 0; size_t storeElementSize = 0;
result = description->serialize(&storeElement, &storeElementSize, result = description->serialize(&storeElement, &storeElementSize,
serializedSize, true); serializedSize, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
storage->deleteData(address); storage->deleteData(address);

View File

@ -2,41 +2,41 @@
ParameterWrapper::ParameterWrapper() : ParameterWrapper::ParameterWrapper() :
pointsToStream(false), type(Type::UNKNOWN_TYPE), rows(0), columns(0), data( pointsToStream(false), type(Type::UNKNOWN_TYPE), rows(0), columns(0), data(
NULL), readonlyData(NULL) { NULL), readonlyData(NULL) {
} }
ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns,
void* data) : void *data) :
pointsToStream(false), type(type), rows(rows), columns(columns), data( pointsToStream(false), type(type), rows(rows), columns(columns), data(
data), readonlyData(data) { data), readonlyData(data) {
} }
ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns,
const void* data) : const void *data) :
pointsToStream(false), type(type), rows(rows), columns(columns), data( pointsToStream(false), type(type), rows(rows), columns(columns), data(
NULL), readonlyData(data) { NULL), readonlyData(data) {
} }
ParameterWrapper::~ParameterWrapper() { ParameterWrapper::~ParameterWrapper() {
} }
ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t ParameterWrapper::serialize(uint8_t **buffer, size_t *size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result; ReturnValue_t result;
result = SerializeAdapter<Type>::serialize(&type, buffer, size, max_size, result = SerializeAdapter::serialize(&type, buffer, size, maxSize,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&columns, buffer, size, result = SerializeAdapter::serialize(&columns, buffer, size, maxSize,
max_size, bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&rows, buffer, size, max_size, result = SerializeAdapter::serialize(&rows, buffer, size, maxSize,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
@ -47,28 +47,33 @@ ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size,
} }
switch (type) { switch (type) {
case Type::UINT8_T: case Type::UINT8_T:
result = serializeData<uint8_t>(buffer, size, max_size, bigEndian); result = serializeData<uint8_t>(buffer, size, maxSize,
streamEndianness);
break; break;
case Type::INT8_T: case Type::INT8_T:
result = serializeData<int8_t>(buffer, size, max_size, bigEndian); result = serializeData<int8_t>(buffer, size, maxSize, streamEndianness);
break; break;
case Type::UINT16_T: case Type::UINT16_T:
result = serializeData<uint16_t>(buffer, size, max_size, bigEndian); result = serializeData<uint16_t>(buffer, size, maxSize,
streamEndianness);
break; break;
case Type::INT16_T: case Type::INT16_T:
result = serializeData<int16_t>(buffer, size, max_size, bigEndian); result = serializeData<int16_t>(buffer, size, maxSize,
streamEndianness);
break; break;
case Type::UINT32_T: case Type::UINT32_T:
result = serializeData<uint32_t>(buffer, size, max_size, bigEndian); result = serializeData<uint32_t>(buffer, size, maxSize,
streamEndianness);
break; break;
case Type::INT32_T: case Type::INT32_T:
result = serializeData<int32_t>(buffer, size, max_size, bigEndian); result = serializeData<int32_t>(buffer, size, maxSize,
streamEndianness);
break; break;
case Type::FLOAT: case Type::FLOAT:
result = serializeData<float>(buffer, size, max_size, bigEndian); result = serializeData<float>(buffer, size, maxSize, streamEndianness);
break; break;
case Type::DOUBLE: case Type::DOUBLE:
result = serializeData<double>(buffer, size, max_size, bigEndian); result = serializeData<double>(buffer, size, maxSize, streamEndianness);
break; break;
default: default:
result = UNKNOW_DATATYPE; result = UNKNOW_DATATYPE;
@ -77,7 +82,7 @@ ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size,
return result; return result;
} }
uint32_t ParameterWrapper::getSerializedSize() const { size_t ParameterWrapper::getSerializedSize() const {
uint32_t serializedSize = 0; uint32_t serializedSize = 0;
serializedSize += type.getSerializedSize(); serializedSize += type.getSerializedSize();
serializedSize += sizeof(rows); serializedSize += sizeof(rows);
@ -88,14 +93,14 @@ uint32_t ParameterWrapper::getSerializedSize() const {
} }
template<typename T> template<typename T>
ReturnValue_t ParameterWrapper::serializeData(uint8_t** buffer, uint32_t* size, ReturnValue_t ParameterWrapper::serializeData(uint8_t **buffer, size_t *size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
const T *element = (const T*) readonlyData; const T *element = (const T*) readonlyData;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
uint16_t dataSize = columns * rows; uint16_t dataSize = columns * rows;
while (dataSize != 0) { while (dataSize != 0) {
result = SerializeAdapter<T>::serialize(element, buffer, size, max_size, result = SerializeAdapter::serialize(element, buffer, size, maxSize,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
@ -111,21 +116,21 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow,
uint8_t fromColumns) { uint8_t fromColumns) {
//treat from as a continuous Stream as we copy all of it //treat from as a continuous Stream as we copy all of it
const uint8_t *fromAsStream = (const uint8_t *) from; const uint8_t *fromAsStream = (const uint8_t*) from;
int32_t streamSize = fromRows * fromColumns * sizeof(T); size_t streamSize = fromRows * fromColumns * sizeof(T);
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) { for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) {
//get the start element of this row in data //get the start element of this row in data
T *dataWithDataType = ((T *) data) T *dataWithDataType = ((T*) data)
+ (((startingRow + fromRow) * columns) + startingColumn); + (((startingRow + fromRow) * columns) + startingColumn);
for (uint8_t fromColumn = 0; fromColumn < fromColumns; fromColumn++) { for (uint8_t fromColumn = 0; fromColumn < fromColumns; fromColumn++) {
result = SerializeAdapter<T>::deSerialize( result = SerializeAdapter::deSerialize(
dataWithDataType + fromColumn, &fromAsStream, &streamSize, dataWithDataType + fromColumn, &fromAsStream, &streamSize,
true); SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
@ -136,13 +141,14 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow,
} }
ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer, ReturnValue_t ParameterWrapper::deSerialize(const uint8_t **buffer,
int32_t* size, bool bigEndian) { size_t *size, Endianness streamEndianness) {
return deSerialize(buffer, size, bigEndian, 0); return deSerialize(buffer, size, streamEndianness, 0);
} }
ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer, ReturnValue_t ParameterWrapper::deSerialize(const uint8_t **buffer,
int32_t* size, bool bigEndian, uint16_t startWritingAtIndex) { size_t *size, Endianness streamEndianness,
uint16_t startWritingAtIndex) {
ParameterWrapper streamDescription; ParameterWrapper streamDescription;
ReturnValue_t result = streamDescription.set(*buffer, *size, buffer, size); ReturnValue_t result = streamDescription.set(*buffer, *size, buffer, size);
@ -153,26 +159,26 @@ ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer,
return copyFrom(&streamDescription, startWritingAtIndex); return copyFrom(&streamDescription, startWritingAtIndex);
} }
ReturnValue_t ParameterWrapper::set(const uint8_t* stream, int32_t streamSize, ReturnValue_t ParameterWrapper::set(const uint8_t *stream, size_t streamSize,
const uint8_t **remainingStream, int32_t *remainingSize) { const uint8_t **remainingStream, size_t *remainingSize) {
ReturnValue_t result = SerializeAdapter<Type>::deSerialize(&type, &stream, ReturnValue_t result = SerializeAdapter::deSerialize(&type, &stream,
&streamSize, true); &streamSize, SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::deSerialize(&columns, &stream, result = SerializeAdapter::deSerialize(&columns, &stream, &streamSize,
&streamSize, true); SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::deSerialize(&rows, &stream, &streamSize, result = SerializeAdapter::deSerialize(&rows, &stream, &streamSize,
true); SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
int32_t dataSize = type.getSize() * rows * columns; size_t dataSize = type.getSize() * rows * columns;
if (streamSize < dataSize) { if (streamSize < dataSize) {
return SerializeIF::STREAM_TOO_SHORT; return SerializeIF::STREAM_TOO_SHORT;
@ -194,7 +200,7 @@ ReturnValue_t ParameterWrapper::set(const uint8_t* stream, int32_t streamSize,
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper* from, ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from,
uint16_t startWritingAtIndex) { uint16_t startWritingAtIndex) {
if (data == NULL) { if (data == NULL) {
return READONLY; return READONLY;
@ -261,7 +267,7 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper* from,
} }
} else { } else {
//need a type to do arithmetic //need a type to do arithmetic
uint8_t *toDataWithType = (uint8_t *) data; uint8_t *toDataWithType = (uint8_t*) data;
for (uint8_t fromRow = 0; fromRow < from->rows; fromRow++) { for (uint8_t fromRow = 0; fromRow < from->rows; fromRow++) {
memcpy( memcpy(
toDataWithType toDataWithType

View File

@ -25,16 +25,16 @@ public:
const void *data); const void *data);
virtual ~ParameterWrapper(); virtual ~ParameterWrapper();
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
virtual uint32_t getSerializedSize() const; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian); Endianness streamEndianness) override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian, uint16_t startWritingAtIndex = 0); Endianness streamEndianness, uint16_t startWritingAtIndex = 0);
template<typename T> template<typename T>
ReturnValue_t getElement(T *value, uint8_t row = 0, uint8_t column = 0) const { ReturnValue_t getElement(T *value, uint8_t row = 0, uint8_t column = 0) const {
@ -54,7 +54,7 @@ public:
const uint8_t *streamWithtype = (const uint8_t *) readonlyData; const uint8_t *streamWithtype = (const uint8_t *) readonlyData;
streamWithtype += (row * columns + column) * type.getSize(); streamWithtype += (row * columns + column) * type.getSize();
int32_t size = type.getSize(); int32_t size = type.getSize();
return SerializeAdapter<T>::deSerialize(value, &streamWithtype, return SerializeAdapter::deSerialize(value, &streamWithtype,
&size, true); &size, true);
} else { } else {
const T *dataWithType = (const T *) readonlyData; const T *dataWithType = (const T *) readonlyData;
@ -111,8 +111,8 @@ public:
void setMatrix(const T& member) { void setMatrix(const T& member) {
this->set(member[0], sizeof(member)/sizeof(member[0]), sizeof(member[0])/sizeof(member[0][0])); this->set(member[0], sizeof(member)/sizeof(member[0]), sizeof(member[0])/sizeof(member[0][0]));
} }
ReturnValue_t set(const uint8_t *stream, int32_t streamSize, ReturnValue_t set(const uint8_t *stream, size_t streamSize,
const uint8_t **remainingStream = NULL, int32_t *remainingSize = const uint8_t **remainingStream = NULL, size_t *remainingSize =
NULL); NULL);
ReturnValue_t copyFrom(const ParameterWrapper *from, ReturnValue_t copyFrom(const ParameterWrapper *from,
@ -128,8 +128,8 @@ private:
const void *readonlyData; const void *readonlyData;
template<typename T> template<typename T>
ReturnValue_t serializeData(uint8_t** buffer, uint32_t* size, ReturnValue_t serializeData(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const;
template<typename T> template<typename T>
ReturnValue_t deSerializeData(uint8_t startingRow, uint8_t startingColumn, ReturnValue_t deSerializeData(uint8_t startingRow, uint8_t startingColumn,

View File

@ -86,12 +86,12 @@ ReturnValue_t Fuse::check() {
return result; return result;
} }
ReturnValue_t Fuse::serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t Fuse::serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = RETURN_FAILED; ReturnValue_t result = RETURN_FAILED;
for (DeviceList::const_iterator iter = devices.begin(); for (DeviceList::const_iterator iter = devices.begin();
iter != devices.end(); iter++) { iter != devices.end(); iter++) {
result = (*iter)->serialize(buffer, size, max_size, bigEndian); result = (*iter)->serialize(buffer, size, maxSize, streamEndianness);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
@ -99,7 +99,7 @@ ReturnValue_t Fuse::serialize(uint8_t** buffer, uint32_t* size,
return RETURN_OK; return RETURN_OK;
} }
uint32_t Fuse::getSerializedSize() const { size_t Fuse::getSerializedSize() const {
uint32_t size = 0; uint32_t size = 0;
for (DeviceList::const_iterator iter = devices.begin(); for (DeviceList::const_iterator iter = devices.begin();
iter != devices.end(); iter++) { iter != devices.end(); iter++) {
@ -108,12 +108,12 @@ uint32_t Fuse::getSerializedSize() const {
return size; return size;
} }
ReturnValue_t Fuse::deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t Fuse::deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
ReturnValue_t result = RETURN_FAILED; ReturnValue_t result = RETURN_FAILED;
for (DeviceList::iterator iter = devices.begin(); iter != devices.end(); for (DeviceList::iterator iter = devices.begin(); iter != devices.end();
iter++) { iter++) {
result = (*iter)->deSerialize(buffer, size, bigEndian); result = (*iter)->deSerialize(buffer, size, streamEndianness);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }

View File

@ -11,14 +11,15 @@
#include <framework/parameters/ParameterHelper.h> #include <framework/parameters/ParameterHelper.h>
#include <list> #include <list>
namespace Factory{ namespace Factory {
void setStaticFrameworkObjectIds(); void setStaticFrameworkObjectIds();
} }
class Fuse: public SystemObject, class Fuse: public SystemObject,
public HasHealthIF, public HasHealthIF,
public HasReturnvaluesIF, public HasReturnvaluesIF,
public ReceivesParameterMessagesIF { public ReceivesParameterMessagesIF,
public SerializeIF {
friend void (Factory::setStaticFrameworkObjectIds)(); friend void (Factory::setStaticFrameworkObjectIds)();
private: private:
static constexpr float RESIDUAL_POWER = 0.005 * 28.5; //!< This is the upper limit of residual power lost by fuses and switches. Worst case is Fuse and one of two switches on. See PCDU ICD 1.9 p29 bottom static constexpr float RESIDUAL_POWER = 0.005 * 28.5; //!< This is the upper limit of residual power lost by fuses and switches. Worst case is Fuse and one of two switches on. See PCDU ICD 1.9 p29 bottom
@ -40,7 +41,7 @@ public:
Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids, Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids,
float maxCurrent, uint16_t confirmationCount = 2); float maxCurrent, uint16_t confirmationCount = 2);
virtual ~Fuse(); virtual ~Fuse();
void addDevice(PowerComponentIF* set); void addDevice(PowerComponentIF *set);
float getPower(); float getPower();
bool isPowerValid(); bool isPowerValid();
@ -49,11 +50,11 @@ public:
uint8_t getFuseId() const; uint8_t getFuseId() const;
ReturnValue_t initialize(); ReturnValue_t initialize();
DeviceList devices; DeviceList devices;
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
const uint32_t max_size, bool bigEndian) const; SerializeIF::Endianness streamEndianness) const override;
uint32_t getSerializedSize() const; size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian); SerializeIF::Endianness streamEndianness) override;
void setAllMonitorsToUnchecked(); void setAllMonitorsToUnchecked();
ReturnValue_t performOperation(uint8_t opCode); ReturnValue_t performOperation(uint8_t opCode);
MessageQueueId_t getCommandQueue() const; MessageQueueId_t getCommandQueue() const;
@ -62,13 +63,13 @@ public:
HasHealthIF::HealthState getHealth(); HasHealthIF::HealthState getHealth();
ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex); const ParameterWrapper *newValues, uint16_t startAtIndex);
private: private:
uint8_t oldFuseState; uint8_t oldFuseState;
uint8_t fuseId; uint8_t fuseId;
PowerSwitchIF* powerIF; //could be static in our case. PowerSwitchIF *powerIF; //could be static in our case.
AbsLimitMonitor<float> currentLimit; AbsLimitMonitor<float> currentLimit;
class PowerMonitor: public MonitorReporter<float> { class PowerMonitor: public MonitorReporter<float> {
public: public:
@ -88,11 +89,11 @@ private:
PIDReader<float> current; PIDReader<float> current;
PIDReader<uint8_t> state; PIDReader<uint8_t> state;
db_float_t power; db_float_t power;
MessageQueueIF* commandQueue; MessageQueueIF *commandQueue;
ParameterHelper parameterHelper; ParameterHelper parameterHelper;
HealthHelper healthHelper; HealthHelper healthHelper;
static object_id_t powerSwitchId; static object_id_t powerSwitchId;
void calculatePowerLimits(float* low, float* high); void calculatePowerLimits(float *low, float *high);
void calculateFusePower(); void calculateFusePower();
void checkFuseState(); void checkFuseState();
void reportEvents(Event event); void reportEvents(Event event);

View File

@ -17,18 +17,18 @@ PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, f
twoSwitches), min(min), max(max), moduleId(moduleId) { twoSwitches), min(min), max(max), moduleId(moduleId) {
} }
ReturnValue_t PowerComponent::serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t PowerComponent::serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result = SerializeAdapter<float>::serialize(&min, buffer, ReturnValue_t result = SerializeAdapter::serialize(&min, buffer,
size, max_size, bigEndian); size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return SerializeAdapter<float>::serialize(&max, buffer, size, max_size, return SerializeAdapter::serialize(&max, buffer, size, maxSize,
bigEndian); streamEndianness);
} }
uint32_t PowerComponent::getSerializedSize() const { size_t PowerComponent::getSerializedSize() const {
return sizeof(min) + sizeof(max); return sizeof(min) + sizeof(max);
} }
@ -56,14 +56,14 @@ float PowerComponent::getMax() {
return max; return max;
} }
ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter<float>::deSerialize(&min, buffer, ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer,
size, bigEndian); size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
return SerializeAdapter<float>::deSerialize(&max, buffer, size, bigEndian); return SerializeAdapter::deSerialize(&max, buffer, size, streamEndianness);
} }
ReturnValue_t PowerComponent::getParameter(uint8_t domainId, ReturnValue_t PowerComponent::getParameter(uint8_t domainId,

View File

@ -19,13 +19,13 @@ public:
float getMin(); float getMin();
float getMax(); float getMax();
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
uint32_t getSerializedSize() const; size_t getSerializedSize() const override;
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian); Endianness streamEndianness) override;
ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,

View File

@ -55,12 +55,15 @@ enum {
HAS_ACTIONS_IF, //HF HAS_ACTIONS_IF, //HF
DEVICE_COMMUNICATION_IF, //DC DEVICE_COMMUNICATION_IF, //DC
BSP, //BSP BSP, //BSP
TIME_STAMPER_IF, //TSI 52 TIME_STAMPER_IF, //TSI 53
//TODO This will shift all IDs for FLP //TODO This will shift all IDs for FLP
SGP4PROPAGATOR_CLASS, //SGP4 53 SGP4PROPAGATOR_CLASS, //SGP4 54
MUTEX_IF, //MUX 54 MUTEX_IF, //MUX 55
MESSAGE_QUEUE_IF,//MQI 55 MESSAGE_QUEUE_IF,//MQI 56
SEMAPHORE_IF, //SPH 56 SEMAPHORE_IF, //SPH 57
LOCAL_POOL_OWNER_IF, //LPIF 58
POOL_VARIABLE_IF, //PVA 59
HOUSEKEEPING_MANAGER, //HKM 60
FW_CLASS_ID_COUNT //is actually count + 1 ! FW_CLASS_ID_COUNT //is actually count + 1 !
}; };

View File

@ -1,27 +1,23 @@
#ifndef HASRETURNVALUESIF_H_ #ifndef FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_
#define HASRETURNVALUESIF_H_ #define FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_
#include <stdint.h>
#include <framework/returnvalues/FwClassIds.h> #include <framework/returnvalues/FwClassIds.h>
#include <config/returnvalues/classIds.h> #include <config/returnvalues/classIds.h>
#include <cstdint>
#define MAKE_RETURN_CODE( number ) ((INTERFACE_ID << 8) + (number)) #define MAKE_RETURN_CODE( number ) ((INTERFACE_ID << 8) + (number))
typedef uint16_t ReturnValue_t; typedef uint16_t ReturnValue_t;
class HasReturnvaluesIF { class HasReturnvaluesIF {
public: public:
static const ReturnValue_t RETURN_OK = 0; static const ReturnValue_t RETURN_OK = 0;
static const ReturnValue_t RETURN_FAILED = 1; static const ReturnValue_t RETURN_FAILED = 1;
virtual ~HasReturnvaluesIF() { virtual ~HasReturnvaluesIF() {}
}
static ReturnValue_t makeReturnCode(uint8_t interfaceId, uint8_t number) {
return (interfaceId << 8) + number;
}
}; };
#endif /* FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ */
#endif /* HASRETURNVALUESIF_H_ */

View File

@ -1,12 +1,12 @@
#ifndef RMAPCOOKIE_H_ #ifndef RMAPCOOKIE_H_
#define RMAPCOOKIE_H_ #define RMAPCOOKIE_H_
#include <framework/devicehandlers/Cookie.h> #include <framework/devicehandlers/CookieIF.h>
#include <framework/rmap/rmapStructs.h> #include <framework/rmap/rmapStructs.h>
class RMAPChannelIF; class RMAPChannelIF;
class RMAPCookie : public Cookie{ class RMAPCookie : public CookieIF {
public: public:
//To Uli: Sorry, I need an empty ctor to initialize an array of cookies. //To Uli: Sorry, I need an empty ctor to initialize an array of cookies.
RMAPCookie(); RMAPCookie();

View File

@ -5,43 +5,43 @@
RmapDeviceCommunicationIF::~RmapDeviceCommunicationIF() { RmapDeviceCommunicationIF::~RmapDeviceCommunicationIF() {
} }
ReturnValue_t RmapDeviceCommunicationIF::sendMessage(Cookie* cookie, ReturnValue_t RmapDeviceCommunicationIF::sendMessage(CookieIF* cookie,
uint8_t* data, uint32_t len) { uint8_t* data, uint32_t len) {
return RMAP::sendWriteCommand((RMAPCookie *) cookie, data, len); return RMAP::sendWriteCommand((RMAPCookie *) cookie, data, len);
} }
ReturnValue_t RmapDeviceCommunicationIF::getSendSuccess(Cookie* cookie) { ReturnValue_t RmapDeviceCommunicationIF::getSendSuccess(CookieIF* cookie) {
return RMAP::getWriteReply((RMAPCookie *) cookie); return RMAP::getWriteReply((RMAPCookie *) cookie);
} }
ReturnValue_t RmapDeviceCommunicationIF::requestReceiveMessage( ReturnValue_t RmapDeviceCommunicationIF::requestReceiveMessage(
Cookie* cookie) { CookieIF* cookie) {
return RMAP::sendReadCommand((RMAPCookie *) cookie, return RMAP::sendReadCommand((RMAPCookie *) cookie,
((RMAPCookie *) cookie)->getMaxReplyLen()); ((RMAPCookie *) cookie)->getMaxReplyLen());
} }
ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(Cookie* cookie, ReturnValue_t RmapDeviceCommunicationIF::readReceivedMessage(CookieIF* cookie,
uint8_t** buffer, uint32_t* size) { uint8_t** buffer, uint32_t* size) {
return RMAP::getReadReply((RMAPCookie *) cookie, buffer, size); return RMAP::getReadReply((RMAPCookie *) cookie, buffer, size);
} }
ReturnValue_t RmapDeviceCommunicationIF::setAddress(Cookie* cookie, ReturnValue_t RmapDeviceCommunicationIF::setAddress(CookieIF* cookie,
uint32_t address) { uint32_t address) {
((RMAPCookie *) cookie)->setAddress(address); ((RMAPCookie *) cookie)->setAddress(address);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
uint32_t RmapDeviceCommunicationIF::getAddress(Cookie* cookie) { uint32_t RmapDeviceCommunicationIF::getAddress(CookieIF* cookie) {
return ((RMAPCookie *) cookie)->getAddress(); return ((RMAPCookie *) cookie)->getAddress();
} }
ReturnValue_t RmapDeviceCommunicationIF::setParameter(Cookie* cookie, ReturnValue_t RmapDeviceCommunicationIF::setParameter(CookieIF* cookie,
uint32_t parameter) { uint32_t parameter) {
//TODO Empty? //TODO Empty?
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
uint32_t RmapDeviceCommunicationIF::getParameter(Cookie* cookie) { uint32_t RmapDeviceCommunicationIF::getParameter(CookieIF* cookie) {
return 0; return 0;
} }

View File

@ -25,7 +25,7 @@ public:
* @param maxReplyLen Maximum length of expected reply * @param maxReplyLen Maximum length of expected reply
* @return * @return
*/ */
virtual ReturnValue_t open(Cookie **cookie, uint32_t address, virtual ReturnValue_t open(CookieIF **cookie, uint32_t address,
uint32_t maxReplyLen) = 0; uint32_t maxReplyLen) = 0;
/** /**
@ -39,7 +39,7 @@ public:
* @param maxReplyLen * @param maxReplyLen
* @return * @return
*/ */
virtual ReturnValue_t reOpen(Cookie *cookie, uint32_t address, virtual ReturnValue_t reOpen(CookieIF *cookie, uint32_t address,
uint32_t maxReplyLen) = 0; uint32_t maxReplyLen) = 0;
@ -47,7 +47,7 @@ public:
* Closing call of connection and memory free of cookie. Mission dependent call * Closing call of connection and memory free of cookie. Mission dependent call
* @param cookie * @param cookie
*/ */
virtual void close(Cookie *cookie) = 0; virtual void close(CookieIF *cookie) = 0;
//SHOULDDO can data be const? //SHOULDDO can data be const?
/** /**
@ -58,23 +58,23 @@ public:
* @param len Length of the data to be send * @param len Length of the data to be send
* @return - Return codes of RMAP::sendWriteCommand() * @return - Return codes of RMAP::sendWriteCommand()
*/ */
virtual ReturnValue_t sendMessage(Cookie *cookie, uint8_t *data, virtual ReturnValue_t sendMessage(CookieIF *cookie, uint8_t *data,
uint32_t len); uint32_t len);
virtual ReturnValue_t getSendSuccess(Cookie *cookie); virtual ReturnValue_t getSendSuccess(CookieIF *cookie);
virtual ReturnValue_t requestReceiveMessage(Cookie *cookie); virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie);
virtual ReturnValue_t readReceivedMessage(Cookie *cookie, uint8_t **buffer, virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
uint32_t *size); uint32_t *size);
virtual ReturnValue_t setAddress(Cookie *cookie, uint32_t address); virtual ReturnValue_t setAddress(CookieIF *cookie, uint32_t address);
virtual uint32_t getAddress(Cookie *cookie); virtual uint32_t getAddress(CookieIF *cookie);
virtual ReturnValue_t setParameter(Cookie *cookie, uint32_t parameter); virtual ReturnValue_t setParameter(CookieIF *cookie, uint32_t parameter);
virtual uint32_t getParameter(Cookie *cookie); virtual uint32_t getParameter(CookieIF *cookie);
}; };
#endif /* MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_ */ #endif /* MISSION_RMAP_RMAPDEVICECOMMUNICATIONINTERFACE_H_ */

126
serialize/EndianConverter.h Normal file
View File

@ -0,0 +1,126 @@
#ifndef ENDIANSWAPPER_H_
#define ENDIANSWAPPER_H_
#include <framework/osal/Endiness.h>
#include <cstring>
#include <iostream>
/**
* Helper class to convert variables or bitstreams between machine
* endian and either big or little endian.
* Machine endian is the endianness used by the machine running the
* program and is one of big or little endian. As this is portable
* code, it is not known at coding time which it is. At compile time
* it is however, which is why this is implemented using compiler
* macros and translates to a copy operation at runtime.
*
* This changes the layout of multi-byte variables in the machine's
* memory. In most cases, you should not need to use this class.
* Probably what you are looking for is the SerializeAdapter.
* If you still decide you need this class, please read and understand
* the code first.
*
* The order of the individual bytes of the multi-byte variable is
* reversed, the byte at the highest address is moved to the lowest
* address and vice versa, same for the bytes in between.
*
* Note that the conversion is also its inversion, that is converting
* from machine to a specified endianness is the same operation as
* converting from specified to machine (I looked it up, mathematicians
* would call it an involution):
*
* X == convertBigEndian(convertBigEndian(X))
*
* Thus, there is only one function supplied to do the conversion.
*/
class EndianConverter {
private:
EndianConverter() {
}
;
public:
/**
* Convert a typed variable between big endian and machine endian.
* Intended for plain old datatypes.
*/
template<typename T>
static T convertBigEndian(T in) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
T tmp;
uint8_t *pointerOut = (uint8_t*) &tmp;
uint8_t *pointerIn = (uint8_t*) &in;
for (size_t count = 0; count < sizeof(T); count++) {
pointerOut[sizeof(T) - count - 1] = pointerIn[count];
}
return tmp;
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
return in;
#else
#error Unknown Byte Order
#endif
}
/**
* convert a bytestream representing a single variable between big endian
* and machine endian.
*/
static void convertBigEndian(uint8_t *out, const uint8_t *in,
size_t size) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
for (size_t count = 0; count < size; count++) {
out[size - count - 1] = in[count];
}
return;
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
memcpy(out, in, size);
return;
#endif
}
/**
* Convert a typed variable between little endian and machine endian.
* Intended for plain old datatypes.
*/
template<typename T>
static T convertLittleEndian(T in) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
T tmp;
uint8_t *pointerOut = (uint8_t *) &tmp;
uint8_t *pointerIn = (uint8_t *) &in;
for (size_t count = 0; count < sizeof(T); count++) {
pointerOut[sizeof(T) - count - 1] = pointerIn[count];
}
return tmp;
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
return in;
#else
#error Unknown Byte Order
#endif
}
/**
* convert a bytestream representing a single variable between little endian
* and machine endian.
*/
static void convertLittleEndian(uint8_t *out, const uint8_t *in,
size_t size) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
for (size_t count = 0; count < size; count++) {
out[size - count - 1] = in[count];
}
return;
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
memcpy(out, in, size);
return;
#endif
}
};
#endif /* ENDIANSWAPPER_H_ */

View File

@ -1,47 +0,0 @@
#ifndef ENDIANSWAPPER_H_
#define ENDIANSWAPPER_H_
#include <framework/osal/Endiness.h>
#include <cstring>
#include <iostream>
class EndianSwapper {
private:
EndianSwapper() {
}
;
public:
template<typename T>
static T swap(T in) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
T tmp;
uint8_t *pointerOut = (uint8_t *) &tmp;
uint8_t *pointerIn = (uint8_t *) &in;
for (uint8_t count = 0; count < sizeof(T); count++) {
pointerOut[sizeof(T) - count - 1] = pointerIn[count];
}
return tmp;
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
return in;
#else
#error Unknown Byte Order
#endif
}
static void swap(uint8_t* out, const uint8_t* in, uint32_t size) {
#ifndef BYTE_ORDER_SYSTEM
#error BYTE_ORDER_SYSTEM not defined
#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN
for (uint8_t count = 0; count < size; count++) {
out[size - count - 1] = in[count];
}
return;
#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN
memcpy(out, in, size);
return;
#endif
}
};
#endif /* ENDIANSWAPPER_H_ */

View File

@ -20,25 +20,25 @@ public:
SerialArrayListAdapter(ArrayList<T, count_t> *adaptee) : adaptee(adaptee) { SerialArrayListAdapter(ArrayList<T, count_t> *adaptee) : adaptee(adaptee) {
} }
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
return serialize(adaptee, buffer, size, max_size, bigEndian); return serialize(adaptee, buffer, size, maxSize, streamEndianness);
} }
static ReturnValue_t serialize(const ArrayList<T, count_t>* list, uint8_t** buffer, uint32_t* size, static ReturnValue_t serialize(const ArrayList<T, count_t>* list, uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) { size_t maxSize, Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter<count_t>::serialize(&list->size, ReturnValue_t result = SerializeAdapter::serialize(&list->size,
buffer, size, max_size, bigEndian); buffer, size, maxSize, streamEndianness);
count_t i = 0; count_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) {
result = SerializeAdapter<T>::serialize(&list->entries[i], buffer, size, result = SerializeAdapter::serialize(&list->entries[i], buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
++i; ++i;
} }
return result; return result;
} }
virtual uint32_t getSerializedSize() const { virtual size_t getSerializedSize() const {
return getSerializedSize(adaptee); return getSerializedSize(adaptee);
} }
@ -47,31 +47,31 @@ public:
count_t i = 0; count_t i = 0;
for (i = 0; i < list->size; ++i) { for (i = 0; i < list->size; ++i) {
printSize += SerializeAdapter<T>::getSerializedSize(&list->entries[i]); printSize += SerializeAdapter::getSerializedSize(&list->entries[i]);
} }
return printSize; return printSize;
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
return deSerialize(adaptee, buffer, size, bigEndian); return deSerialize(adaptee, buffer, size, streamEndianness);
} }
static ReturnValue_t deSerialize(ArrayList<T, count_t>* list, const uint8_t** buffer, int32_t* size, static ReturnValue_t deSerialize(ArrayList<T, count_t>* list, const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
count_t tempSize = 0; count_t tempSize = 0;
ReturnValue_t result = SerializeAdapter<count_t>::deSerialize(&tempSize, ReturnValue_t result = SerializeAdapter::deSerialize(&tempSize,
buffer, size, bigEndian); buffer, size, streamEndianness);
if (tempSize > list->maxSize()) { if (tempSize > list->maxSize()) {
return SerializeIF::TOO_MANY_ELEMENTS; return SerializeIF::TOO_MANY_ELEMENTS;
} }
list->size = tempSize; list->size = tempSize;
count_t i = 0; count_t i = 0;
while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) {
result = SerializeAdapter<T>::deSerialize( result = SerializeAdapter::deSerialize(
&list->front()[i], buffer, size, &list->front()[i], buffer, size,
bigEndian); streamEndianness);
++i; ++i;
} }
return result; return result;

View File

@ -22,19 +22,19 @@ SerialBufferAdapter<T>::~SerialBufferAdapter() {
} }
template<typename T> template<typename T>
ReturnValue_t SerialBufferAdapter<T>::serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t SerialBufferAdapter<T>::serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
uint32_t serializedLength = bufferLength; uint32_t serializedLength = bufferLength;
if (serializeLength) { if (serializeLength) {
serializedLength += AutoSerializeAdapter::getSerializedSize( serializedLength += SerializeAdapter::getSerializedSize(
&bufferLength); &bufferLength);
} }
if (*size + serializedLength > max_size) { if (*size + serializedLength > maxSize) {
return BUFFER_TOO_SHORT; return BUFFER_TOO_SHORT;
} else { } else {
if (serializeLength) { if (serializeLength) {
AutoSerializeAdapter::serialize(&bufferLength, buffer, size, SerializeAdapter::serialize(&bufferLength, buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
} }
if (this->constBuffer != NULL) { if (this->constBuffer != NULL) {
memcpy(*buffer, this->constBuffer, bufferLength); memcpy(*buffer, this->constBuffer, bufferLength);
@ -50,20 +50,20 @@ ReturnValue_t SerialBufferAdapter<T>::serialize(uint8_t** buffer, uint32_t* size
} }
template<typename T> template<typename T>
uint32_t SerialBufferAdapter<T>::getSerializedSize() const { size_t SerialBufferAdapter<T>::getSerializedSize() const {
if (serializeLength) { if (serializeLength) {
return bufferLength + AutoSerializeAdapter::getSerializedSize(&bufferLength); return bufferLength + SerializeAdapter::getSerializedSize(&bufferLength);
} else { } else {
return bufferLength; return bufferLength;
} }
} }
template<typename T> template<typename T>
ReturnValue_t SerialBufferAdapter<T>::deSerialize(const uint8_t** buffer, ReturnValue_t SerialBufferAdapter<T>::deSerialize(const uint8_t** buffer,
int32_t* size, bool bigEndian) { size_t* size, Endianness streamEndianness) {
//TODO Ignores Endian flag! //TODO Ignores Endian flag!
if (buffer != NULL) { if (buffer != NULL) {
if(serializeLength){ if(serializeLength){
T serializedSize = AutoSerializeAdapter::getSerializedSize( T serializedSize = SerializeAdapter::getSerializedSize(
&bufferLength); &bufferLength);
if((*size - bufferLength - serializedSize) >= 0){ if((*size - bufferLength - serializedSize) >= 0){
*buffer += serializedSize; *buffer += serializedSize;

View File

@ -16,13 +16,13 @@ public:
virtual ~SerialBufferAdapter(); virtual ~SerialBufferAdapter();
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const; size_t maxSize, Endianness streamEndianness) const override;
virtual uint32_t getSerializedSize() const; virtual size_t getSerializedSize() const override;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian); Endianness streamEndianness) override;
private: private:
bool serializeLength; bool serializeLength;
const uint8_t *constBuffer; const uint8_t *constBuffer;

View File

@ -13,16 +13,16 @@ public:
template<typename... Args> template<typename... Args>
SerialFixedArrayListAdapter(Args... args) : FixedArrayList<T, MAX_SIZE, count_t>(std::forward<Args>(args)...) { SerialFixedArrayListAdapter(Args... args) : FixedArrayList<T, MAX_SIZE, count_t>(std::forward<Args>(args)...) {
} }
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
return SerialArrayListAdapter<T, count_t>::serialize(this, buffer, size, max_size, bigEndian); return SerialArrayListAdapter<T, count_t>::serialize(this, buffer, size, maxSize, streamEndianness);
} }
uint32_t getSerializedSize() const { size_t getSerializedSize() const {
return SerialArrayListAdapter<T, count_t>::getSerializedSize(this); return SerialArrayListAdapter<T, count_t>::getSerializedSize(this);
} }
ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
return SerialArrayListAdapter<T, count_t>::deSerialize(this, buffer, size, bigEndian); return SerialArrayListAdapter<T, count_t>::deSerialize(this, buffer, size, streamEndianness);
} }
}; };

View File

@ -31,32 +31,32 @@ public:
SinglyLinkedList<T>(), printCount(printCount) { SinglyLinkedList<T>(), printCount(printCount) {
} }
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const override {
if (printCount) { if (printCount) {
count_t mySize = SinglyLinkedList<T>::getSize(); count_t mySize = SinglyLinkedList<T>::getSize();
ReturnValue_t result = SerializeAdapter<count_t>::serialize(&mySize, ReturnValue_t result = SerializeAdapter::serialize(&mySize,
buffer, size, max_size, bigEndian); buffer, size, maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
} }
return serialize(SinglyLinkedList<T>::start, buffer, size, max_size, return serialize(SinglyLinkedList<T>::start, buffer, size, maxSize,
bigEndian); streamEndianness);
} }
static ReturnValue_t serialize(const LinkedElement<T>* element, static ReturnValue_t serialize(const LinkedElement<T>* element,
uint8_t** buffer, uint32_t* size, const uint32_t max_size, uint8_t** buffer, size_t* size, size_t maxSize,
bool bigEndian) { Endianness streamEndianness) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) {
result = element->value->serialize(buffer, size, max_size, result = element->value->serialize(buffer, size, maxSize,
bigEndian); streamEndianness);
element = element->getNext(); element = element->getNext();
} }
return result; return result;
} }
virtual uint32_t getSerializedSize() const { virtual size_t getSerializedSize() const override {
if (printCount) { if (printCount) {
return SerialLinkedListAdapter<T>::getSerializedSize() return SerialLinkedListAdapter<T>::getSerializedSize()
+ sizeof(count_t); + sizeof(count_t);
@ -64,8 +64,8 @@ public:
return getSerializedSize(SinglyLinkedList<T>::start); return getSerializedSize(SinglyLinkedList<T>::start);
} }
} }
static uint32_t getSerializedSize(const LinkedElement<T> *element) { static size_t getSerializedSize(const LinkedElement<T> *element) {
uint32_t size = 0; size_t size = 0;
while (element != NULL) { while (element != NULL) {
size += element->value->getSerializedSize(); size += element->value->getSerializedSize();
element = element->getNext(); element = element->getNext();
@ -73,16 +73,16 @@ public:
return size; return size;
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) override {
return deSerialize(SinglyLinkedList<T>::start, buffer, size, bigEndian); return deSerialize(SinglyLinkedList<T>::start, buffer, size, streamEndianness);
} }
static ReturnValue_t deSerialize(LinkedElement<T>* element, static ReturnValue_t deSerialize(LinkedElement<T>* element,
const uint8_t** buffer, int32_t* size, bool bigEndian) { const uint8_t** buffer, size_t* size, Endianness streamEndianness) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) { while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) {
result = element->value->deSerialize(buffer, size, bigEndian); result = element->value->deSerialize(buffer, size, streamEndianness);
element = element->getNext(); element = element->getNext();
} }
return result; return result;

View File

@ -3,123 +3,121 @@
#include <framework/container/IsDerivedFrom.h> #include <framework/container/IsDerivedFrom.h>
#include <framework/returnvalues/HasReturnvaluesIF.h> #include <framework/returnvalues/HasReturnvaluesIF.h>
#include <framework/serialize/EndianSwapper.h> #include <framework/serialize/EndianConverter.h>
#include <framework/serialize/SerializeIF.h> #include <framework/serialize/SerializeIF.h>
#include <string.h> #include <string.h>
/** /**
* \ingroup serialize * \ingroup serialize
*/ */
template<typename T, int>
class SerializeAdapter_ {
public:
static ReturnValue_t serialize(const T* object, uint8_t** buffer,
uint32_t* size, const uint32_t max_size, bool bigEndian) {
uint32_t ignoredSize = 0;
if (size == NULL) {
size = &ignoredSize;
}
if (sizeof(T) + *size <= max_size) {
T tmp;
if (bigEndian) {
tmp = EndianSwapper::swap<T>(*object);
} else {
tmp = *object;
}
memcpy(*buffer, &tmp, sizeof(T));
*size += sizeof(T);
(*buffer) += sizeof(T);
return HasReturnvaluesIF::RETURN_OK;
} else {
return SerializeIF::BUFFER_TOO_SHORT;
}
}
ReturnValue_t deSerialize(T* object, const uint8_t** buffer, int32_t* size,
bool bigEndian) {
T tmp;
*size -= sizeof(T);
if (*size >= 0) {
memcpy(&tmp, *buffer, sizeof(T));
if (bigEndian) {
*object = EndianSwapper::swap<T>(tmp);
} else {
*object = tmp;
}
*buffer += sizeof(T);
return HasReturnvaluesIF::RETURN_OK;
} else {
return SerializeIF::STREAM_TOO_SHORT;
}
}
uint32_t getSerializedSize(const T * object) {
return sizeof(T);
}
};
template<typename T>
class SerializeAdapter_<T, 1> {
public:
ReturnValue_t serialize(const T* object, uint8_t** buffer, uint32_t* size,
const uint32_t max_size, bool bigEndian) const {
uint32_t ignoredSize = 0;
if (size == NULL) {
size = &ignoredSize;
}
return object->serialize(buffer, size, max_size, bigEndian);
}
uint32_t getSerializedSize(const T* object) const {
return object->getSerializedSize();
}
ReturnValue_t deSerialize(T* object, const uint8_t** buffer, int32_t* size,
bool bigEndian) {
return object->deSerialize(buffer, size, bigEndian);
}
};
template<typename T>
class SerializeAdapter { class SerializeAdapter {
public:
static ReturnValue_t serialize(const T* object, uint8_t** buffer,
uint32_t* size, const uint32_t max_size, bool bigEndian) {
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
return adapter.serialize(object, buffer, size, max_size, bigEndian);
}
static uint32_t getSerializedSize(const T* object) {
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
return adapter.getSerializedSize(object);
}
static ReturnValue_t deSerialize(T* object, const uint8_t** buffer,
int32_t* size, bool bigEndian) {
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
return adapter.deSerialize(object, buffer, size, bigEndian);
}
};
class AutoSerializeAdapter {
public: public:
template<typename T> template<typename T>
static ReturnValue_t serialize(const T* object, uint8_t** buffer, static ReturnValue_t serialize(const T *object, uint8_t **buffer,
uint32_t* size, const uint32_t max_size, bool bigEndian) { size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) {
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter; InternalSerializeAdapter<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
return adapter.serialize(object, buffer, size, max_size, bigEndian); return adapter.serialize(object, buffer, size, maxSize,
streamEndianness);
} }
template<typename T> template<typename T>
static uint32_t getSerializedSize(const T* object) { static uint32_t getSerializedSize(const T *object) {
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter; InternalSerializeAdapter<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
return adapter.getSerializedSize(object); return adapter.getSerializedSize(object);
} }
template<typename T> template<typename T>
static ReturnValue_t deSerialize(T* object, const uint8_t** buffer, static ReturnValue_t deSerialize(T *object, const uint8_t **buffer,
int32_t* size, bool bigEndian) { size_t *size, SerializeIF::Endianness streamEndianness) {
SerializeAdapter_<T, IsDerivedFrom<T, SerializeIF>::Is> adapter; InternalSerializeAdapter<T, IsDerivedFrom<T, SerializeIF>::Is> adapter;
return adapter.deSerialize(object, buffer, size, bigEndian); return adapter.deSerialize(object, buffer, size, streamEndianness);
} }
private:
template<typename T, int>
class InternalSerializeAdapter {
public:
static ReturnValue_t serialize(const T *object, uint8_t **buffer,
size_t *size, size_t max_size, SerializeIF::Endianness streamEndianness) {
size_t ignoredSize = 0;
if (size == NULL) {
size = &ignoredSize;
}
//TODO check integer overflow of *size
if (sizeof(T) + *size <= max_size) {
T tmp;
switch (streamEndianness) {
case SerializeIF::Endianness::BIG:
tmp = EndianConverter::convertBigEndian<T>(*object);
break;
case SerializeIF::Endianness::LITTLE:
tmp = EndianConverter::convertLittleEndian<T>(*object);
break;
default:
case SerializeIF::Endianness::MACHINE:
tmp = *object;
break;
}
memcpy(*buffer, &tmp, sizeof(T));
*size += sizeof(T);
(*buffer) += sizeof(T);
return HasReturnvaluesIF::RETURN_OK;
} else {
return SerializeIF::BUFFER_TOO_SHORT;
}
}
ReturnValue_t deSerialize(T *object, const uint8_t **buffer,
size_t *size, SerializeIF::Endianness streamEndianness) {
T tmp;
if (*size >= sizeof(T)) {
*size -= sizeof(T);
memcpy(&tmp, *buffer, sizeof(T));
switch (streamEndianness) {
case SerializeIF::Endianness::BIG:
*object = EndianConverter::convertBigEndian<T>(tmp);
break;
case SerializeIF::Endianness::LITTLE:
*object = EndianConverter::convertLittleEndian<T>(tmp);
break;
default:
case SerializeIF::Endianness::MACHINE:
*object = tmp;
break;
}
*buffer += sizeof(T);
return HasReturnvaluesIF::RETURN_OK;
} else {
return SerializeIF::STREAM_TOO_SHORT;
}
}
uint32_t getSerializedSize(const T *object) {
return sizeof(T);
}
};
template<typename T>
class InternalSerializeAdapter<T, 1> {
public:
ReturnValue_t serialize(const T *object, uint8_t **buffer,
size_t *size, size_t max_size,
SerializeIF::Endianness streamEndianness) const {
size_t ignoredSize = 0;
if (size == NULL) {
size = &ignoredSize;
}
return object->serialize(buffer, size, max_size, streamEndianness);
}
uint32_t getSerializedSize(const T *object) const {
return object->getSerializedSize();
}
ReturnValue_t deSerialize(T *object, const uint8_t **buffer,
size_t *size, SerializeIF::Endianness streamEndianness) {
return object->deSerialize(buffer, size, streamEndianness);
}
};
}; };
#endif /* SERIALIZEADAPTER_H_ */ #endif /* SERIALIZEADAPTER_H_ */

View File

@ -9,41 +9,43 @@
* \ingroup serialize * \ingroup serialize
*/ */
template<typename T> template<typename T>
class SerializeElement : public SerializeIF, public LinkedElement<SerializeIF> { class SerializeElement: public SerializeIF, public LinkedElement<SerializeIF> {
public: public:
template<typename... Args> template<typename ... Args>
SerializeElement(Args... args) : LinkedElement<SerializeIF>(this), entry(std::forward<Args>(args)...) { SerializeElement(Args ... args) :
LinkedElement<SerializeIF>(this), entry(std::forward<Args>(args)...) {
} }
SerializeElement() : LinkedElement<SerializeIF>(this) { SerializeElement() :
LinkedElement<SerializeIF>(this) {
} }
T entry; T entry;
ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
const uint32_t max_size, bool bigEndian) const { Endianness streamEndianness) const override {
return SerializeAdapter<T>::serialize(&entry, buffer, size, max_size, bigEndian); return SerializeAdapter::serialize(&entry, buffer, size, maxSize,
streamEndianness);
} }
uint32_t getSerializedSize() const { size_t getSerializedSize() const override {
return SerializeAdapter<T>::getSerializedSize(&entry); return SerializeAdapter::getSerializedSize(&entry);
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian) { Endianness streamEndianness) override {
return SerializeAdapter<T>::deSerialize(&entry, buffer, size, bigEndian); return SerializeAdapter::deSerialize(&entry, buffer, size,
streamEndianness);
} }
operator T() { operator T() {
return entry; return entry;
} }
SerializeElement<T> &operator=(T newValue) { SerializeElement<T>& operator=(T newValue) {
entry = newValue; entry = newValue;
return *this; return *this;
} }
T *operator->() { T* operator->() {
return &entry; return &entry;
} }
}; };
#endif /* SERIALIZEELEMENT_H_ */ #endif /* SERIALIZEELEMENT_H_ */

View File

@ -2,6 +2,7 @@
#define SERIALIZEIF_H_ #define SERIALIZEIF_H_
#include <framework/returnvalues/HasReturnvaluesIF.h> #include <framework/returnvalues/HasReturnvaluesIF.h>
#include <stddef.h>
/** /**
* \defgroup serialize Serialization * \defgroup serialize Serialization
@ -14,6 +15,10 @@
*/ */
class SerializeIF { class SerializeIF {
public: public:
enum class Endianness : uint8_t {
BIG, LITTLE, MACHINE
};
static const uint8_t INTERFACE_ID = CLASS_ID::SERIALIZE_IF; static const uint8_t INTERFACE_ID = CLASS_ID::SERIALIZE_IF;
static const ReturnValue_t BUFFER_TOO_SHORT = MAKE_RETURN_CODE(1); static const ReturnValue_t BUFFER_TOO_SHORT = MAKE_RETURN_CODE(1);
static const ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(2); static const ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(2);
@ -22,13 +27,13 @@ public:
virtual ~SerializeIF() { virtual ~SerializeIF() {
} }
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size,
const uint32_t max_size, bool bigEndian) const = 0; size_t maxSize, Endianness streamEndianness) const = 0;
virtual uint32_t getSerializedSize() const = 0; virtual size_t getSerializedSize() const = 0;
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
bool bigEndian) = 0; Endianness streamEndianness) = 0;
}; };

View File

@ -1,11 +1,58 @@
#include <framework/timemanager/Clock.h> #include <framework/timemanager/Clock.h>
#include <framework/serviceinterface/ServiceInterfaceBuffer.h> #include <framework/serviceinterface/ServiceInterfaceBuffer.h>
#include <cstring> #include <cstring>
#include <inttypes.h>
// to be implemented by bsp // to be implemented by bsp
extern "C" void printChar(const char*); extern "C" void printChar(const char*, bool errStream);
#ifndef UT699
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage,
bool addCrToPreamble, bool buffered , bool errStream, uint16_t port):
isActive(true), logMessage(setMessage),
addCrToPreamble(addCrToPreamble), buffered(buffered),
errStream(errStream) {
if(buffered) {
// Set pointers if the stream is buffered.
setp( buf, buf + BUF_SIZE );
}
preamble.reserve(MAX_PREAMBLE_SIZE);
preamble.resize(MAX_PREAMBLE_SIZE);
}
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
char array[BUF_SIZE];
uint32_t length = end - begin;
if (length > sizeof(array)) {
length = sizeof(array);
}
memcpy(array, begin, length);
for(; begin != end; begin++){
if(errStream) {
printChar(begin, true);
}
else {
printChar(begin, false);
}
}
}
#endif
int ServiceInterfaceBuffer::overflow(int c) { int ServiceInterfaceBuffer::overflow(int c) {
if(not buffered and this->isActive) {
if (c != Traits::eof()) {
if(errStream) {
printChar(reinterpret_cast<const char*>(&c), true);
}
else {
printChar(reinterpret_cast<const char*>(&c), false);
}
}
return 0;
}
// Handle output // Handle output
putChars(pbase(), pptr()); putChars(pbase(), pptr());
if (c != Traits::eof()) { if (c != Traits::eof()) {
@ -20,52 +67,70 @@ int ServiceInterfaceBuffer::overflow(int c) {
} }
int ServiceInterfaceBuffer::sync(void) { int ServiceInterfaceBuffer::sync(void) {
if (this->isActive) { if(not this->isActive and not buffered) {
Clock::TimeOfDay_t loggerTime; if(not buffered) {
Clock::getDateAndTime(&loggerTime); setp(buf, buf + BUF_SIZE - 1);
char preamble[96] = { 0 }; }
sprintf(preamble, "%s: | %lu:%02lu:%02lu.%03lu | ", return 0;
this->log_message.c_str(), (unsigned long) loggerTime.hour,
(unsigned long) loggerTime.minute,
(unsigned long) loggerTime.second,
(unsigned long) loggerTime.usecond /1000);
// Write log_message and time
this->putChars(preamble, preamble + sizeof(preamble));
// Handle output
this->putChars(pbase(), pptr());
} }
if(not buffered) {
return 0;
}
size_t preambleSize = 0;
auto preamble = getPreamble(&preambleSize);
// Write logMessage and time
this->putChars(preamble.data(), preamble.data() + preambleSize);
// Handle output
this->putChars(pbase(), pptr());
// This tells that buffer is empty again // This tells that buffer is empty again
setp(buf, buf + BUF_SIZE - 1); setp(buf, buf + BUF_SIZE - 1);
return 0; return 0;
} }
#ifndef UT699 bool ServiceInterfaceBuffer::isBuffered() const {
return buffered;
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, uint16_t port) {
this->log_message = set_message;
this->isActive = true;
setp( buf, buf + BUF_SIZE );
} }
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { std::string ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) {
char array[BUF_SIZE]; Clock::TimeOfDay_t loggerTime;
uint32_t length = end - begin; Clock::getDateAndTime(&loggerTime);
if (length > sizeof(array)) { size_t currentSize = 0;
length = sizeof(array); char* parsePosition = &preamble[0];
if(addCrToPreamble) {
preamble[0] = '\r';
currentSize += 1;
parsePosition += 1;
} }
memcpy(array, begin, length); int32_t charCount = sprintf(parsePosition,
"%s: | %02" SCNu32 ":%02" SCNu32 ":%02" SCNu32 ".%03" SCNu32 " | ",
for( ; begin != end; begin++){ this->logMessage.c_str(), loggerTime.hour,
printChar(begin); loggerTime.minute,
loggerTime.second,
loggerTime.usecond /1000);
if(charCount < 0) {
printf("ServiceInterfaceBuffer: Failure parsing preamble\r\n");
return "";
} }
if(charCount > MAX_PREAMBLE_SIZE) {
printf("ServiceInterfaceBuffer: Char count too large for maximum "
"preamble size");
return "";
}
currentSize += charCount;
if(preambleSize != nullptr) {
*preambleSize = currentSize;
}
return preamble;
} }
#endif
#ifdef UT699 #ifdef UT699
#include <framework/osal/rtems/Interrupt.h> #include <framework/osal/rtems/Interrupt.h>
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, uint16_t port) { ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message,
uint16_t port) {
this->log_message = set_message; this->log_message = set_message;
this->isActive = true; this->isActive = true;
setp( buf, buf + BUF_SIZE ); setp( buf, buf + BUF_SIZE );

View File

@ -1,51 +1,71 @@
#ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_ #ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_
#define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_ #define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_
#include <framework/returnvalues/HasReturnvaluesIF.h>
#include <iostream> #include <iostream>
#include <iosfwd>
#include <sstream> #include <sstream>
#include <cstdio> #include <iomanip>
#ifndef UT699 #ifndef UT699
class ServiceInterfaceBuffer: public std::basic_streambuf<char,
std::char_traits<char> > { /**
* @brief This is the underlying stream buffer which implements the
* streambuf class and overloads the overflow() and sync() methods
* @details
* This class is used to modify the output of the stream, for example by adding.
* It also calls the char printing function which is implemented in the
* board supply package (BSP).
*/
class ServiceInterfaceBuffer:
public std::streambuf {
friend class ServiceInterfaceStream; friend class ServiceInterfaceStream;
public: public:
ServiceInterfaceBuffer(std::string set_message, uint16_t port); static constexpr uint8_t MAX_PREAMBLE_SIZE = 40;
ServiceInterfaceBuffer(std::string setMessage, bool addCrToPreamble,
bool buffered, bool errStream, uint16_t port);
protected: protected:
bool isActive; bool isActive;
// This is called when buffer becomes full. If //! This is called when buffer becomes full. If
// buffer is not used, then this is called every //! buffer is not used, then this is called every
// time when characters are put to stream. //! time when characters are put to stream.
virtual int overflow(int c = Traits::eof()); int overflow(int c = Traits::eof()) override;
// This function is called when stream is flushed, //! This function is called when stream is flushed,
// for example when std::endl is put to stream. //! for example when std::endl is put to stream.
virtual int sync(void); int sync(void) override;
bool isBuffered() const;
private: private:
// For additional message information //! For additional message information
std::string log_message; std::string logMessage;
std::string preamble;
// For EOF detection // For EOF detection
typedef std::char_traits<char> Traits; typedef std::char_traits<char> Traits;
// Work in buffer mode. It is also possible to work without buffer. //! This is useful for some terminal programs which do not have
//! implicit carriage return with newline characters.
bool addCrToPreamble;
//! Specifies whether the stream operates in buffered or unbuffered mode.
bool buffered;
//! This specifies to print to stderr and work in unbuffered mode.
bool errStream;
//! Needed for buffered mode.
static size_t const BUF_SIZE = 128; static size_t const BUF_SIZE = 128;
char buf[BUF_SIZE]; char buf[BUF_SIZE];
// In this function, the characters are parsed. //! In this function, the characters are parsed.
void putChars(char const* begin, char const* end); void putChars(char const* begin, char const* end);
std::string getPreamble(size_t * preambleSize = nullptr);
}; };
#endif #endif
#ifdef UT699 #ifdef UT699
class ServiceInterfaceBuffer: public std::basic_streambuf<char, class ServiceInterfaceBuffer: public std::basic_streambuf<char,
std::char_traits<char> > { std::char_traits<char> > {

View File

@ -1,11 +1,32 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
ServiceInterfaceStream::ServiceInterfaceStream(std::string setMessage,
bool addCrToPreamble, bool buffered, bool errStream, uint16_t port) :
std::ostream(&streambuf),
streambuf(setMessage, addCrToPreamble, buffered, errStream, port) {}
void ServiceInterfaceStream::setActive( bool myActive) { void ServiceInterfaceStream::setActive( bool myActive) {
this->buf.isActive = myActive; this->streambuf.isActive = myActive;
} }
ServiceInterfaceStream::ServiceInterfaceStream(std::string set_message, std::string ServiceInterfaceStream::getPreamble() {
uint16_t port) : return streambuf.getPreamble();
std::basic_ostream<char, std::char_traits<char> >(&buf), buf( }
set_message, port) {
void ServiceInterfaceStream::print(std::string error,
bool withPreamble, bool withNewline, bool flush) {
if(not streambuf.isBuffered() and withPreamble) {
*this << getPreamble() << error;
}
else {
*this << error;
}
if(withNewline) {
*this << "\n";
}
// if mode is non-buffered, no need to flush.
if(flush and streambuf.isBuffered()) {
this->flush();
}
} }

View File

@ -3,28 +3,56 @@
#include <framework/serviceinterface/ServiceInterfaceBuffer.h> #include <framework/serviceinterface/ServiceInterfaceBuffer.h>
#include <iostream> #include <iostream>
#include <iosfwd>
#include <sstream>
#include <cstdio> #include <cstdio>
// Unfortunately, there must be a forward declaration of log_fe /**
// (MUST be defined in main), to let the system know where to write to. * Generic service interface stream which can be used like std::cout or
namespace sif { * std::cerr but has additional capability. Add preamble and timestamp
extern std::ostream debug; * to output. Can be run in buffered or unbuffered mode.
extern std::ostream info; */
extern std::ostream warning; class ServiceInterfaceStream : public std::ostream {
extern std::ostream error;
}
class ServiceInterfaceStream : public std::basic_ostream< char, std::char_traits< char > > {
protected:
ServiceInterfaceBuffer buf;
public: public:
ServiceInterfaceStream( std::string set_message, uint16_t port = 1234 ); /**
* This constructor is used by specifying the preamble message.
* Optionally, the output can be directed to stderr and a CR character
* can be prepended to the preamble.
* @param setMessage message of preamble.
* @param addCrToPreamble Useful for applications like Puttty.
* @param buffered specify whether to use buffered mode.
* @param errStream specify which output stream to use (stderr or stdout).
*/
ServiceInterfaceStream(std::string setMessage,
bool addCrToPreamble = false, bool buffered = true,
bool errStream = false, uint16_t port = 1234);
//! An inactive stream will not print anything.
void setActive( bool ); void setActive( bool );
/**
* This can be used to retrieve the preamble in case it should be printed in
* the unbuffered mode.
* @return Preamle consisting of log message and timestamp.
*/
std::string getPreamble();
/**
* This prints an error with a preamble. Useful if using the unbuffered
* mode. Flushes in default mode (prints immediately).
*/
void print(std::string error, bool withPreamble = true,
bool withNewline = true, bool flush = true);
protected:
ServiceInterfaceBuffer streambuf;
}; };
// Forward declaration of interface streams. These should be instantiated in
// main. They can then be used like std::cout or std::cerr.
namespace sif {
extern ServiceInterfaceStream debug;
extern ServiceInterfaceStream info;
extern ServiceInterfaceStream warning;
extern ServiceInterfaceStream error;
}
#endif /* FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ */ #endif /* FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ */

View File

@ -13,7 +13,7 @@ Subsystem::Subsystem(object_id_t setObjectId, object_id_t parent,
false), uptimeStartTable(0), currentTargetTable(), targetMode( false), uptimeStartTable(0), currentTargetTable(), targetMode(
0), targetSubmode(SUBMODE_NONE), initialMode(0), currentSequenceIterator(), modeTables( 0), targetSubmode(SUBMODE_NONE), initialMode(0), currentSequenceIterator(), modeTables(
maxNumberOfTables), modeSequences(maxNumberOfSequences), IPCStore( maxNumberOfTables), modeSequences(maxNumberOfSequences), IPCStore(
NULL) NULL)
#ifdef USE_MODESTORE #ifdef USE_MODESTORE
,modeStore(NULL) ,modeStore(NULL)
#endif #endif
@ -75,7 +75,8 @@ void Subsystem::performChildOperation() {
if (isInTransition) { if (isInTransition) {
if (commandsOutstanding <= 0) { //all children of the current table were commanded and replied if (commandsOutstanding <= 0) { //all children of the current table were commanded and replied
if (currentSequenceIterator.value == NULL) { //we're through with this sequence if (currentSequenceIterator.value == NULL) { //we're through with this sequence
if (checkStateAgainstTable(currentTargetTable, targetSubmode) == RETURN_OK) { if (checkStateAgainstTable(currentTargetTable, targetSubmode)
== RETURN_OK) {
setMode(targetMode, targetSubmode); setMode(targetMode, targetSubmode);
isInTransition = false; isInTransition = false;
return; return;
@ -86,7 +87,8 @@ void Subsystem::performChildOperation() {
} }
} }
if (currentSequenceIterator->checkSuccess()) { if (currentSequenceIterator->checkSuccess()) {
if (checkStateAgainstTable(getCurrentTable(), targetSubmode) != RETURN_OK) { if (checkStateAgainstTable(getCurrentTable(), targetSubmode)
!= RETURN_OK) {
transitionFailed(TABLE_CHECK_FAILED, transitionFailed(TABLE_CHECK_FAILED,
currentSequenceIterator->getTableId()); currentSequenceIterator->getTableId());
return; return;
@ -117,7 +119,8 @@ void Subsystem::performChildOperation() {
childrenChangedHealth = false; childrenChangedHealth = false;
startTransition(mode, submode); startTransition(mode, submode);
} else if (childrenChangedMode) { } else if (childrenChangedMode) {
if (checkStateAgainstTable(currentTargetTable, submode) != RETURN_OK) { if (checkStateAgainstTable(currentTargetTable, submode)
!= RETURN_OK) {
triggerEvent(CANT_KEEP_MODE, mode, submode); triggerEvent(CANT_KEEP_MODE, mode, submode);
cantKeepMode(); cantKeepMode();
} }
@ -147,7 +150,7 @@ HybridIterator<ModeListEntry> Subsystem::getTable(Mode_t id) {
} }
} }
ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { ReturnValue_t Subsystem::handleCommandMessage(CommandMessage *message) {
ReturnValue_t result; ReturnValue_t result;
switch (message->getCommand()) { switch (message->getCommand()) {
case HealthMessage::HEALTH_INFO: { case HealthMessage::HEALTH_INFO: {
@ -168,12 +171,13 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) {
&sizeRead); &sizeRead);
if (result == RETURN_OK) { if (result == RETURN_OK) {
Mode_t fallbackId; Mode_t fallbackId;
int32_t size = sizeRead; size_t size = sizeRead;
result = SerializeAdapter<Mode_t>::deSerialize(&fallbackId, result = SerializeAdapter::deSerialize(&fallbackId, &pointer, &size,
&pointer, &size, true); SerializeIF::Endianness::BIG);
if (result == RETURN_OK) { if (result == RETURN_OK) {
result = SerialArrayListAdapter<ModeListEntry>::deSerialize( result = SerialArrayListAdapter<ModeListEntry>::deSerialize(
&sequence, &pointer, &size, true); &sequence, &pointer, &size,
SerializeIF::Endianness::BIG);
if (result == RETURN_OK) { if (result == RETURN_OK) {
result = addSequence(&sequence, result = addSequence(&sequence,
ModeSequenceMessage::getSequenceId(message), ModeSequenceMessage::getSequenceId(message),
@ -193,9 +197,9 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) {
ModeSequenceMessage::getStoreAddress(message), &pointer, ModeSequenceMessage::getStoreAddress(message), &pointer,
&sizeRead); &sizeRead);
if (result == RETURN_OK) { if (result == RETURN_OK) {
int32_t size = sizeRead; size_t size = sizeRead;
result = SerialArrayListAdapter<ModeListEntry>::deSerialize(&table, result = SerialArrayListAdapter<ModeListEntry>::deSerialize(&table,
&pointer, &size, true); &pointer, &size, SerializeIF::Endianness::BIG);
if (result == RETURN_OK) { if (result == RETURN_OK) {
result = addTable(&table, result = addTable(&table,
ModeSequenceMessage::getSequenceId(message)); ModeSequenceMessage::getSequenceId(message));
@ -339,7 +343,7 @@ void Subsystem::replyToCommand(ReturnValue_t status, uint32_t parameter) {
} }
} }
ReturnValue_t Subsystem::addSequence(ArrayList<ModeListEntry>* sequence, ReturnValue_t Subsystem::addSequence(ArrayList<ModeListEntry> *sequence,
Mode_t id, Mode_t fallbackSequence, bool inStore, bool preInit) { Mode_t id, Mode_t fallbackSequence, bool inStore, bool preInit) {
ReturnValue_t result; ReturnValue_t result;
@ -507,7 +511,7 @@ MessageQueueId_t Subsystem::getSequenceCommandQueue() const {
} }
ReturnValue_t Subsystem::checkModeCommand(Mode_t mode, Submode_t submode, ReturnValue_t Subsystem::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) { uint32_t *msToReachTheMode) {
//Need to accept all submodes to be able to inherit submodes //Need to accept all submodes to be able to inherit submodes
// if (submode != SUBMODE_NONE) { // if (submode != SUBMODE_NONE) {
// return INVALID_SUBMODE; // return INVALID_SUBMODE;
@ -599,15 +603,15 @@ void Subsystem::transitionFailed(ReturnValue_t failureCode,
} }
void Subsystem::sendSerializablesAsCommandMessage(Command_t command, void Subsystem::sendSerializablesAsCommandMessage(Command_t command,
SerializeIF** elements, uint8_t count) { SerializeIF **elements, uint8_t count) {
ReturnValue_t result; ReturnValue_t result;
uint32_t maxSize = 0; size_t maxSize = 0;
for (uint8_t i = 0; i < count; i++) { for (uint8_t i = 0; i < count; i++) {
maxSize += elements[i]->getSerializedSize(); maxSize += elements[i]->getSerializedSize();
} }
uint8_t *storeBuffer; uint8_t *storeBuffer;
store_address_t address; store_address_t address;
uint32_t size = 0; size_t size = 0;
result = IPCStore->getFreeElement(&address, maxSize, &storeBuffer); result = IPCStore->getFreeElement(&address, maxSize, &storeBuffer);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
@ -615,7 +619,8 @@ void Subsystem::sendSerializablesAsCommandMessage(Command_t command,
return; return;
} }
for (uint8_t i = 0; i < count; i++) { for (uint8_t i = 0; i < count; i++) {
elements[i]->serialize(&storeBuffer, &size, maxSize, true); elements[i]->serialize(&storeBuffer, &size, maxSize,
SerializeIF::Endianness::BIG);
} }
CommandMessage reply; CommandMessage reply;
ModeSequenceMessage::setModeSequenceMessage(&reply, command, address); ModeSequenceMessage::setModeSequenceMessage(&reply, command, address);

View File

@ -18,65 +18,65 @@ public:
uint8_t value3; uint8_t value3;
uint8_t value4; uint8_t value4;
virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size,
const uint32_t max_size, bool bigEndian) const { size_t maxSize, Endianness streamEndianness) const {
ReturnValue_t result; ReturnValue_t result;
result = SerializeAdapter<uint32_t>::serialize(&value1, buffer, size, result = SerializeAdapter::serialize(&value1, buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint32_t>::serialize(&value2, buffer, size, result = SerializeAdapter::serialize(&value2, buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&value3, buffer, size, result = SerializeAdapter::serialize(&value3, buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::serialize(&value4, buffer, size, result = SerializeAdapter::serialize(&value4, buffer, size,
max_size, bigEndian); maxSize, streamEndianness);
return result; return result;
} }
virtual uint32_t getSerializedSize() const { virtual size_t getSerializedSize() const {
return sizeof(value1) + sizeof(value2) + sizeof(value3) + sizeof(value4); return sizeof(value1) + sizeof(value2) + sizeof(value3) + sizeof(value4);
} }
virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
bool bigEndian) { Endianness streamEndianness) {
ReturnValue_t result; ReturnValue_t result;
result = SerializeAdapter<uint32_t>::deSerialize(&value1, buffer, size, result = SerializeAdapter::deSerialize(&value1, buffer, size,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint32_t>::deSerialize(&value2, buffer, size, result = SerializeAdapter::deSerialize(&value2, buffer, size,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::deSerialize(&value3, buffer, size, result = SerializeAdapter::deSerialize(&value3, buffer, size,
bigEndian); streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = SerializeAdapter<uint8_t>::deSerialize(&value4, buffer, size, result = SerializeAdapter::deSerialize(&value4, buffer, size,
bigEndian); streamEndianness);
return result; return result;
} }

View File

@ -1,15 +1,5 @@
/** #ifndef FRAMEWORK_TASKS_EXECUTABLEOBJECTIF_H_
* @file ExecutableObjectIF.h #define FRAMEWORK_TASKS_EXECUTABLEOBJECTIF_H_
*
* @brief This file contains the definition for the ExecutableObjectIF interface.
*
* @author Bastian Baetz
*
* @date 12.03.2012
*/
#ifndef EXECUTABLEOBJECTIF_H_
#define EXECUTABLEOBJECTIF_H_
class PeriodicTaskIF; class PeriodicTaskIF;
@ -20,6 +10,7 @@ class PeriodicTaskIF;
* @brief The interface provides a method to execute objects within a task. * @brief The interface provides a method to execute objects within a task.
* @details The performOperation method, that is required by the interface is * @details The performOperation method, that is required by the interface is
* executed cyclically within a task context. * executed cyclically within a task context.
* @author Bastian Baetz
*/ */
class ExecutableObjectIF { class ExecutableObjectIF {
public: public:
@ -37,13 +28,26 @@ public:
/** /**
* @brief Function called during setup assignment of object to task * @brief Function called during setup assignment of object to task
* @details Has to be called from the function that assigns the object to a task and * @details
* enables the object implementation to overwrite this function and get a reference to the executing task * Has to be called from the function that assigns the object to a task and
* enables the object implementation to overwrite this function and get
* a reference to the executing task
* @param task_ Pointer to the taskIF of this task * @param task_ Pointer to the taskIF of this task
*/ */
virtual void setTaskIF(PeriodicTaskIF* task_) { virtual void setTaskIF(PeriodicTaskIF* task_) {};
/**
* This function should be called after the object was assigned to a
* specific task.
*
* Example: Can be used to get task execution frequency.
* The task is created after initialize() and the object ctors have been
* called so the execution frequency can't be cached in initialize()
* @return
*/
virtual ReturnValue_t initializeAfterTaskCreation() {
return HasReturnvaluesIF::RETURN_OK;
} }
}; };
#endif /* EXECUTABLEOBJECTIF_H_ */ #endif /* FRAMEWORK_TASKS_EXECUTABLEOBJECTIF_H_ */

Some files were not shown because too many files have changed in this diff Show More