From 85833018ae981303a87c43c16a16c5078e0731b6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 19 Mar 2020 12:53:36 +0100 Subject: [PATCH 1/6] documentation related stuff --- action/HasActionsIF.h | 6 ++- container/SimpleRingBuffer.h | 29 ++++++++++++ datapool/PoolVariable.h | 3 +- devicehandlers/Cookie.h | 9 ++++ devicehandlers/FixedSequenceSlot.h | 2 +- devicehandlers/FixedSlotSequence.h | 2 +- health/HealthHelper.h | 2 +- ipc/MessageQueueIF.h | 49 ++++++++++++-------- ipc/MutexIF.h | 7 +++ serialize/SerialBufferAdapter.h | 50 +++++++++++++++++++-- serialize/SerialFixedArrayListAdapter.h | 38 +++++++++++++--- serialize/SerialLinkedListAdapter.h | 43 +++++++++++++++++- serialize/SerializeAdapter.h | 59 +++++++++++++++++++++++-- serialize/SerializeElement.h | 14 +++++- serialize/SerializeIF.h | 20 +++++++-- 15 files changed, 290 insertions(+), 43 deletions(-) diff --git a/action/HasActionsIF.h b/action/HasActionsIF.h index f30fcb45..4d66ad1f 100644 --- a/action/HasActionsIF.h +++ b/action/HasActionsIF.h @@ -7,8 +7,10 @@ #include #include /** - * \brief Interface for component which uses actions + * @brief + * Interface for component which uses actions * + * @details * This interface is used to execute actions in the component. Actions, in the sense of this interface, are activities with a well-defined beginning and * end in time. They may adjust sub-states of components, but are not supposed to change * the main mode of operation, which is handled with the HasModesIF described below. @@ -23,6 +25,8 @@ * parameters and immediately start execution of the action. It is, however, not required to * immediately finish execution. Instead, this may be deferred to a later point in time, at * which the component needs to inform the caller about finished or failed execution. + * + * \ingroup interfaces */ class HasActionsIF { public: diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index 6d7d67e1..4552a1c0 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -4,12 +4,41 @@ #include #include +/** + * @brief Circular buffer implementation, useful for buffering into data streams. + * @details Note that the deleteData() has to be called to increment the read pointer + * @ingroup containers + */ class SimpleRingBuffer: public RingBufferBase<> { public: SimpleRingBuffer(uint32_t size, bool overwriteOld); virtual ~SimpleRingBuffer(); + + /** + * Write to circular buffer and increment write pointer by amount + * @param data + * @param amount + * @return + */ ReturnValue_t writeData(const uint8_t* data, uint32_t amount); + + /** + * Read from circular buffer at read pointer + * @param data + * @param amount + * @param readRemaining + * @param trueAmount + * @return + */ ReturnValue_t readData(uint8_t* data, uint32_t amount, bool readRemaining = false, uint32_t* trueAmount = NULL); + + /** + * Delete data starting by incrementing read pointer + * @param amount + * @param deleteRemaining + * @param trueAmount + * @return + */ ReturnValue_t deleteData(uint32_t amount, bool deleteRemaining = false, uint32_t* trueAmount = NULL); private: // static const uint8_t TEMP_READ_PTR = 1; diff --git a/datapool/PoolVariable.h b/datapool/PoolVariable.h index 25345c0a..2c48ca3e 100644 --- a/datapool/PoolVariable.h +++ b/datapool/PoolVariable.h @@ -112,8 +112,7 @@ public: * corresponds to. * \param dataSet The data set in which the variable shall register itself. If NULL, * the variable is not registered. - * \param setWritable If this flag is set to true, changes in the value attribute can be - * written back to the data pool, otherwise not. + * \param setReadWriteMode */ PoolVariable(uint32_t set_id, DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode) : diff --git a/devicehandlers/Cookie.h b/devicehandlers/Cookie.h index 495c8c40..ec22ec3a 100644 --- a/devicehandlers/Cookie.h +++ b/devicehandlers/Cookie.h @@ -1,6 +1,15 @@ #ifndef COOKIE_H_ #define COOKIE_H_ +/** + * @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. This cookie + * can be used in the device communication interface by performing + * a C++ dynamic cast. The cookie can be used to store all kinds of information + * about the communication between read and send calls. + */ class Cookie{ public: virtual ~Cookie(){} diff --git a/devicehandlers/FixedSequenceSlot.h b/devicehandlers/FixedSequenceSlot.h index 5aff0f4f..0ed285b3 100644 --- a/devicehandlers/FixedSequenceSlot.h +++ b/devicehandlers/FixedSequenceSlot.h @@ -31,7 +31,7 @@ public: * \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 - * smaller than the period length of the polling sequence, what is ensured by automated calculation + * smaller than the period length of the polling sequence, which is ensured by automated calculation * from a database. */ uint32_t pollingTimeMs; diff --git a/devicehandlers/FixedSlotSequence.h b/devicehandlers/FixedSlotSequence.h index f8fd9a36..d72de913 100644 --- a/devicehandlers/FixedSlotSequence.h +++ b/devicehandlers/FixedSlotSequence.h @@ -104,7 +104,7 @@ protected: * \brief This list contains all OPUSPollingSlot objects, defining order and execution time of the * device handler objects. * - * \details The slot list is a std:list object that contains all created OPUSPollingSlot instances. + * @details The slot list is a std:list object that contains all created PollingSlot instances. * They are NOT ordered automatically, so by 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. diff --git a/health/HealthHelper.h b/health/HealthHelper.h index a1ca2c52..24fd0d14 100644 --- a/health/HealthHelper.h +++ b/health/HealthHelper.h @@ -27,8 +27,8 @@ public: /** * ctor * + * @param owner * @param objectId the object Id to use when communication with the HealthTable - * @param useAsFrom id to use as from id when sending replies, can be set to 0 */ HealthHelper(HasHealthIF* owner, object_id_t objectId); diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index 18e2d99a..47da694c 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -3,12 +3,16 @@ // COULDDO: We could support blocking calls +/** + * @defgroup message_queue Message Queue + * @brief Message Queue related software components + */ + #include #include #include class MessageQueueIF { public: - static const MessageQueueId_t NO_QUEUE = MessageQueueSenderIF::NO_QUEUE; //!< Ugly hack. static const uint8_t INTERFACE_ID = CLASS_ID::MESSAGE_QUEUE_IF; @@ -54,6 +58,8 @@ public: * lastPartner attribute. Else, the lastPartner information remains untouched, the * message's content is cleared and the function returns immediately. * @param message A pointer to a message in which the received data is stored. + * @return -@c RETURN_OK on success + * -@c MessageQueueIF::EMPTY if queue is empty */ virtual ReturnValue_t receiveMessage(MessageQueueMessage* message) = 0; /** @@ -72,33 +78,38 @@ public: virtual MessageQueueId_t getId() const = 0; /** - * \brief With the sendMessage call, a queue message is sent to a receiving queue. - * \details This method takes the message provided, adds the sentFrom information and passes + * @brief With the sendMessage call, a queue message is sent to a receiving queue. + * @details This method takes the message provided, adds the sentFrom information and passes * it on to the destination provided with an operating system call. The OS's return * value is returned. - * \param sendTo This parameter specifies the message queue id to send the message to. - * \param message This is a pointer to a previously created message, which is sent. - * \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message. + * @param sendTo This parameter specifies the message queue id to send the message to. + * @param message This is a pointer to a previously created message, which is sent. + * @param sentFrom The sentFrom information can be set to inject the sender's queue id into the message. * This variable is set to zero by default. - * \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full (if implemented). + * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full (if implemented). + * @return -@c RETURN_OK on success + * -@c MessageQueueIF::FULL if queue is full */ virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessage* message, MessageQueueId_t sentFrom, bool ignoreFault = false ) = 0; + /** - * @brief This operation sends a message to the given destination. - * @details It directly uses the sendMessage call of the MessageQueueSender parent, but passes its - * queue id as "sentFrom" parameter. - * @param sendTo This parameter specifies the message queue id of the destination message queue. - * @param message A pointer to a previously created message, which is sent. - * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. - */ + * @brief This operation sends a message to the given destination. + * @details It directly uses the sendMessage call of the MessageQueueSender parent, but passes its + * queue id as "sentFrom" parameter. + * @param sendTo This parameter specifies the message queue id of the destination message queue. + * @param message A pointer to a previously created message, which is sent. + * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. + */ virtual ReturnValue_t sendMessage( MessageQueueId_t sendTo, MessageQueueMessage* message, bool ignoreFault = false ) = 0; /** - * \brief The sendToDefaultFrom method sends a queue message to the default destination. - * \details In all other aspects, it works identical to the sendMessage method. - * \param message This is a pointer to a previously created message, which is sent. - * \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message. + * @brief The sendToDefaultFrom method sends a queue message to the default destination. + * @details In all other aspects, it works identical to the sendMessage method. + * @param message This is a pointer to a previously created message, which is sent. + * @param sentFrom The sentFrom information can be set to inject the sender's queue id into the message. * This variable is set to zero by default. + * @return -@c RETURN_OK on success + * -@c MessageQueueIF::FULL if queue is full */ virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, MessageQueueId_t sentFrom, bool ignoreFault = false ) = 0; /** @@ -106,6 +117,8 @@ public: * @details As in the sendMessage method, this function uses the sendToDefault call of the * Implementation class and adds its queue id as "sentFrom" information. * @param message A pointer to a previously created message, which is sent. + * @return -@c RETURN_OK on success + * -@c MessageQueueIF::FULL if queue is full */ virtual ReturnValue_t sendToDefault( MessageQueueMessage* message ) = 0; /** diff --git a/ipc/MutexIF.h b/ipc/MutexIF.h index 35786d6a..a4aff1cd 100644 --- a/ipc/MutexIF.h +++ b/ipc/MutexIF.h @@ -3,6 +3,13 @@ #include +/** + * @brief Common interface for OS Mutex objects which provide MUTual EXclusion. + * + * @details https://en.wikipedia.org/wiki/Lock_(computer_science) + * @ingroup osal + * @ingroup interface + */ class MutexIF { public: static const uint32_t NO_TIMEOUT; //!< Needs to be defined in implementation. diff --git a/serialize/SerialBufferAdapter.h b/serialize/SerialBufferAdapter.h index 7cd75d55..600bd692 100644 --- a/serialize/SerialBufferAdapter.h +++ b/serialize/SerialBufferAdapter.h @@ -5,14 +5,46 @@ #include /** + * This adapter provides an interface for SerializeIF to serialize or deserialize + * buffers with no length header but a known size. + * + * Additionally, the buffer length can be serialized too and will be put in front of the serialized buffer. + * + * Can be used with SerialLinkedListAdapter by declaring a SerializeElement with + * SerialElement> serialBufferElement. + * Right now, the SerialBufferAdapter must always be initialized with the buffer and size ! + * * \ingroup serialize */ template class SerialBufferAdapter: public SerializeIF { public: - SerialBufferAdapter(const uint8_t * buffer, T bufferLength, bool serializeLenght = false); - SerialBufferAdapter(uint8_t* buffer, T bufferLength, - bool serializeLenght = false); + /** + * Constructor for constant uint8_t buffer. Length field can be serialized optionally. + * Type of length can be supplied as template type. + * @param buffer + * @param bufferLength + * @param serializeLength + */ + SerialBufferAdapter(const uint8_t * buffer, T bufferLength, bool serializeLength = false); + + /** + * Constructor for non-constant uint8_t buffer. Length field can be serialized optionally. + * Type of length can be supplied as template type. + * @param buffer + * @param bufferLength + * @param serializeLength + */ + SerialBufferAdapter(uint8_t* buffer, T bufferLength, bool serializeLength = false); + + /** + * Constructoor for non-constant uint32_t buffer. Length field can be serialized optionally. + * Type of length can be supplied as template type. + * @param buffer + * @param bufferLength + * @param serializeLength + */ + SerialBufferAdapter(uint32_t* buffer,T bufferLength, bool serializeLength = false); virtual ~SerialBufferAdapter(); @@ -23,7 +55,19 @@ public: virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian); + + uint8_t * getBuffer(); + const uint8_t * getConstBuffer(); + void setBuffer(uint8_t * buffer_, T bufferLength_); + void setBuffer(uint32_t * buffer_, T bufferLength_); private: + + enum bufferType { + NORMAL, + CONST + }; + bufferType currentBufferType; + bool serializeLength; const uint8_t *constBuffer; uint8_t *buffer; diff --git a/serialize/SerialFixedArrayListAdapter.h b/serialize/SerialFixedArrayListAdapter.h index 16919b62..67954d68 100644 --- a/serialize/SerialFixedArrayListAdapter.h +++ b/serialize/SerialFixedArrayListAdapter.h @@ -5,24 +5,48 @@ #include /** - * \ingroup serialize + * @brief This adapter provides an interface for SerializeIF to serialize and deserialize + * buffers with a header containing the buffer length. + * @details + * + * Can be used by SerialLinkedListAdapter by declaring + * as a linked element with SerializeElement>. + * The sequence of objects is defined in the constructor by using the setStart and setNext functions. + * + * 1. Buffers with a size header inside that class can be declared with + * SerialFixedArrayListAdapter. + * 2. MAX_BUFFER_LENGTH specifies the maximum allowed number of elements in FixedArrayList + * 3. LENGTH_FIELD_TYPE specifies the data type of the buffer header containing the buffer size + * (defaults to 1 byte length field) that follows + * + * @ingroup serialize */ -template -class SerialFixedArrayListAdapter : public FixedArrayList, public SerializeIF { +template +class SerialFixedArrayListAdapter : public FixedArrayList, public SerializeIF { public: + /** + * Constructor Arguments are forwarded to FixedArrayList constructor + * @param args + */ template - SerialFixedArrayListAdapter(Args... args) : FixedArrayList(std::forward(args)...) { + SerialFixedArrayListAdapter(Args... args) : FixedArrayList(std::forward(args)...) { } + ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - return SerialArrayListAdapter::serialize(this, buffer, size, max_size, bigEndian); + return SerialArrayListAdapter::serialize(this, buffer, size, max_size, bigEndian); } + uint32_t getSerializedSize() const { - return SerialArrayListAdapter::getSerializedSize(this); + return SerialArrayListAdapter::getSerializedSize(this); } ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - return SerialArrayListAdapter::deSerialize(this, buffer, size, bigEndian); + return SerialArrayListAdapter::deSerialize(this, buffer, size, bigEndian); + } + + void swapArrayListEndianness() { + SerialArrayListAdapter::swapArrayListEndianness(this); } }; diff --git a/serialize/SerialLinkedListAdapter.h b/serialize/SerialLinkedListAdapter.h index 29952c4a..ef1fa200 100644 --- a/serialize/SerialLinkedListAdapter.h +++ b/serialize/SerialLinkedListAdapter.h @@ -13,8 +13,30 @@ #include //This is where we need the SerializeAdapter! -/** - * \ingroup serialize + /** + * @brief Implement the conversion of object data to data streams + * or vice-versa, using linked lists. + * @details + * An alternative to the AutoSerializeAdapter functions + * - All object members with a datatype are declared as SerializeElement + * members inside the class implementing this adapter. + * - The element type can also be a SerialBufferAdapter to de-/serialize buffers, + * with a known size, where the size can also be serialized + * - The element type can also be a SerialFixedArrayListAdapter to de-/serialize buffers + * with a size header, which is scanned automatically + * + * The sequence of objects is defined in the constructor by using + * the setStart and setNext functions. + * + * - The serialization process is done by instantiating the class and + * calling serializ after all SerializeElement entries have been set by + * using the constructor or setter functions. An additional size variable can be supplied + * which is calculated/incremented automatically + * - The deserialization process is done by instantiating the class and supplying + * a buffer with the data which is converted into an object. The size of + * data to serialize can be supplied and is decremented in the function + * + * @ingroup serialize */ template class SerialLinkedListAdapter: public SinglyLinkedList, public SerializeIF { @@ -31,6 +53,16 @@ public: SinglyLinkedList(), printCount(printCount) { } + /** + * Serialize object implementing this adapter into the supplied buffer + * and calculate the serialized size + * @param buffer [out] Object is serialized into this buffer. Note that the buffer pointer + * *buffer is incremented automatically inside the respective serialize functions + * @param size [out] Calculated serialized size. Don't forget to set to 0. + * @param max_size + * @param bigEndian Specify endianness + * @return + */ virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { if (printCount) { @@ -73,6 +105,13 @@ public: return size; } + /** + * Deserialize supplied buffer with supplied size into object implementing this adapter + * @param buffer + * @param size Decremented in respective deSerialize functions automatically + * @param bigEndian Specify endianness + * @return + */ virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { return deSerialize(SinglyLinkedList::start, buffer, size, bigEndian); diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index fd9e1b6a..18240a95 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -7,8 +7,53 @@ #include #include -/** - * \ingroup serialize + /** + * @brief This adapter provides an interface to use the SerializeIF functions + * with arbitrary template objects to facilitate and simplify the serialization of classes + * with different multiple different data types into buffers and vice-versa. + * @details + * Examples: + * A report class is converted into a TM buffer. The report class implements a serialize functions and calls + * the AutoSerializeAdapter::serialize function repeatedly on all object data fields. + * The getSerializedSize function is implemented by calling the + * AutoSerializeAdapter::getSerializedSize function repeatedly on all data fields. + * + * The AutoSerializeAdapter functions can also be used as an alternative to memcpy + * to retrieve data out of a buffer directly into a class variable with data type T while being able to specify endianness. + * The boolean bigEndian specifies whether an endian swap is performed on the data before + * serialization or deserialization. + * + * If the target architecture is little endian (ARM), any data types created might + * have the wrong endiness if they are to be used for the FSFW. + * There are three ways to retrieve data out of a buffer to be used in the FSFW + * to use regular aligned (big endian) data. + * This can also be applied to uint32_t and uint64_t: + * + * 1. Use the AutoSerializeAdapter::deSerialize function + * The pointer *buffer will be incremented automatically by the typeSize of the object, + * so this function can be called on &buffer repeatedly without adjusting pointer position. + * Set bigEndian parameter to true to perform endian swapping. + * + * uint16_t data; + * int32_t dataLen = sizeof(data); + * ReturnValue_t result = AutoSerializeAdapter::deSerialize(&data,&buffer,&dataLen,true); + * + * 2. Perform a bitshift operation. Perform endian swapping if necessary: + * + * uint16_t data; + * data = buffer[targetByte1] << 8 | buffer[targetByte2]; + * data = EndianSwapper::swap(data); + * + * 3. Memcpy can be used when data is little-endian. Perform endian-swapping if necessary. + * + * uint16_t data; + * memcpy(&data,buffer + positionOfTargetByte1,sizeof(data)); + * data = EndianSwapper::swap(data); + * + * When serializing for downlink, the packets are generally serialized assuming big endian data format + * like seen in TmPacketStored.cpp for example. + * + * @ingroup serialize */ template class SerializeAdapter_ { @@ -35,6 +80,14 @@ public: } } + /** + * Deserialize buffer into object + * @param object [out] Object to be deserialized with buffer data + * @param buffer buffer containing the data. Non-Const pointer to non-const pointer to const buffer. + * @param size int32_t type to allow value to be values smaller than 0, needed for range/size checking + * @param bigEndian Specify endianness + * @return + */ ReturnValue_t deSerialize(T* object, const uint8_t** buffer, int32_t* size, bool bigEndian) { T tmp; @@ -100,7 +153,7 @@ public: } }; - +// No type specification necessary here. class AutoSerializeAdapter { public: template diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index db7db20a..cd040c0f 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -6,11 +6,23 @@ #include /** - * \ingroup serialize + * @brief This class is used to mark datatypes for serialization with the + * SerialLinkedListAdapter + * @details + * Used by declaring any arbitrary datatype with SerializeElement myVariable, + * inside a SerialLinkedListAdapter implementation and setting the sequence + * of objects with setNext() and setStart(). + * Serilization and Deserialization is then performed automatically in + * specified sequence order. + * @ingroup serialize */ template class SerializeElement : public SerializeIF, public LinkedElement { public: + /** + * Arguments are forwarded to the element datatype constructor + * @param args + */ template SerializeElement(Args... args) : LinkedElement(this), entry(std::forward(args)...) { diff --git a/serialize/SerializeIF.h b/serialize/SerializeIF.h index 701fbf56..fb750a08 100644 --- a/serialize/SerializeIF.h +++ b/serialize/SerializeIF.h @@ -4,13 +4,27 @@ #include /** - * \defgroup serialize Serialization + * @defgroup serialize Serialization * Contains serialisation services. */ /** - * Translation of objects into data streams. - * \ingroup serialize + * @brief An interface for alle classes which require + * translation of objects data into data streams and vice-versa. + * @details + * If the target architecture is little endian (e.g. ARM), any data types created might + * have the wrong endiness if they are to be used for the FSFW. + * There are three ways to retrieve data out of a buffer to be used in the FSFW to use + * regular aligned (big endian) data. This can also be applied to uint32_t and uint64_t: + * + * 1. Use the @c AutoSerializeAdapter::deSerialize function with @c bigEndian = true + * 2. Perform a bitshift operation + * 3. @c memcpy can be used when data is in little-endian format. Otherwise, @c EndianSwapper has to be used in conjuction. + * + * When serializing for downlink, the packets are generally serialized assuming big endian data format + * like seen in TmPacketStored.cpp for example. + * + * @ingroup serialize */ class SerializeIF { public: -- 2.43.0 From e9704181c7514aad54de93328925030ac3e2e003 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 18 Apr 2020 16:37:47 +0200 Subject: [PATCH 2/6] decoupling doc from functional changes --- serialize/SerialBufferAdapter.h | 50 +-------------- serialize/SerialFixedArrayListAdapter.h | 38 ++--------- serialize/SerializeAdapter.h | 85 ++++++++++++------------- serialize/SerializeElement.h | 14 +--- 4 files changed, 53 insertions(+), 134 deletions(-) diff --git a/serialize/SerialBufferAdapter.h b/serialize/SerialBufferAdapter.h index 600bd692..7cd75d55 100644 --- a/serialize/SerialBufferAdapter.h +++ b/serialize/SerialBufferAdapter.h @@ -5,46 +5,14 @@ #include /** - * This adapter provides an interface for SerializeIF to serialize or deserialize - * buffers with no length header but a known size. - * - * Additionally, the buffer length can be serialized too and will be put in front of the serialized buffer. - * - * Can be used with SerialLinkedListAdapter by declaring a SerializeElement with - * SerialElement> serialBufferElement. - * Right now, the SerialBufferAdapter must always be initialized with the buffer and size ! - * * \ingroup serialize */ template class SerialBufferAdapter: public SerializeIF { public: - /** - * Constructor for constant uint8_t buffer. Length field can be serialized optionally. - * Type of length can be supplied as template type. - * @param buffer - * @param bufferLength - * @param serializeLength - */ - SerialBufferAdapter(const uint8_t * buffer, T bufferLength, bool serializeLength = false); - - /** - * Constructor for non-constant uint8_t buffer. Length field can be serialized optionally. - * Type of length can be supplied as template type. - * @param buffer - * @param bufferLength - * @param serializeLength - */ - SerialBufferAdapter(uint8_t* buffer, T bufferLength, bool serializeLength = false); - - /** - * Constructoor for non-constant uint32_t buffer. Length field can be serialized optionally. - * Type of length can be supplied as template type. - * @param buffer - * @param bufferLength - * @param serializeLength - */ - SerialBufferAdapter(uint32_t* buffer,T bufferLength, bool serializeLength = false); + SerialBufferAdapter(const uint8_t * buffer, T bufferLength, bool serializeLenght = false); + SerialBufferAdapter(uint8_t* buffer, T bufferLength, + bool serializeLenght = false); virtual ~SerialBufferAdapter(); @@ -55,19 +23,7 @@ public: virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian); - - uint8_t * getBuffer(); - const uint8_t * getConstBuffer(); - void setBuffer(uint8_t * buffer_, T bufferLength_); - void setBuffer(uint32_t * buffer_, T bufferLength_); private: - - enum bufferType { - NORMAL, - CONST - }; - bufferType currentBufferType; - bool serializeLength; const uint8_t *constBuffer; uint8_t *buffer; diff --git a/serialize/SerialFixedArrayListAdapter.h b/serialize/SerialFixedArrayListAdapter.h index 67954d68..16919b62 100644 --- a/serialize/SerialFixedArrayListAdapter.h +++ b/serialize/SerialFixedArrayListAdapter.h @@ -5,48 +5,24 @@ #include /** - * @brief This adapter provides an interface for SerializeIF to serialize and deserialize - * buffers with a header containing the buffer length. - * @details - * - * Can be used by SerialLinkedListAdapter by declaring - * as a linked element with SerializeElement>. - * The sequence of objects is defined in the constructor by using the setStart and setNext functions. - * - * 1. Buffers with a size header inside that class can be declared with - * SerialFixedArrayListAdapter. - * 2. MAX_BUFFER_LENGTH specifies the maximum allowed number of elements in FixedArrayList - * 3. LENGTH_FIELD_TYPE specifies the data type of the buffer header containing the buffer size - * (defaults to 1 byte length field) that follows - * - * @ingroup serialize + * \ingroup serialize */ -template -class SerialFixedArrayListAdapter : public FixedArrayList, public SerializeIF { +template +class SerialFixedArrayListAdapter : public FixedArrayList, public SerializeIF { public: - /** - * Constructor Arguments are forwarded to FixedArrayList constructor - * @param args - */ template - SerialFixedArrayListAdapter(Args... args) : FixedArrayList(std::forward(args)...) { + SerialFixedArrayListAdapter(Args... args) : FixedArrayList(std::forward(args)...) { } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - return SerialArrayListAdapter::serialize(this, buffer, size, max_size, bigEndian); + return SerialArrayListAdapter::serialize(this, buffer, size, max_size, bigEndian); } - uint32_t getSerializedSize() const { - return SerialArrayListAdapter::getSerializedSize(this); + return SerialArrayListAdapter::getSerializedSize(this); } ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - return SerialArrayListAdapter::deSerialize(this, buffer, size, bigEndian); - } - - void swapArrayListEndianness() { - SerialArrayListAdapter::swapArrayListEndianness(this); + return SerialArrayListAdapter::deSerialize(this, buffer, size, bigEndian); } }; diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index 18240a95..7dac5758 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -8,50 +8,57 @@ #include /** - * @brief This adapter provides an interface to use the SerializeIF functions - * with arbitrary template objects to facilitate and simplify the serialization of classes - * with different multiple different data types into buffers and vice-versa. + * @brief These adapters provides an interface to use the SerializeIF functions + * with arbitrary template objects to facilitate and simplify the + * serialization of classes with different multiple different data types + * into buffers and vice-versa. * @details - * Examples: - * A report class is converted into a TM buffer. The report class implements a serialize functions and calls - * the AutoSerializeAdapter::serialize function repeatedly on all object data fields. - * The getSerializedSize function is implemented by calling the - * AutoSerializeAdapter::getSerializedSize function repeatedly on all data fields. * - * The AutoSerializeAdapter functions can also be used as an alternative to memcpy - * to retrieve data out of a buffer directly into a class variable with data type T while being able to specify endianness. - * The boolean bigEndian specifies whether an endian swap is performed on the data before + * A report class is converted into a TM buffer. The report class implements a + * serialize functions and calls the AutoSerializeAdapter::serialize function + * repeatedly on all object data fields. The getSerializedSize function is + * implemented by calling the AutoSerializeAdapter::getSerializedSize function + * repeatedly on all data fields. + * + * The AutoSerializeAdapter functions can also be used as an alternative to + * memcpy to retrieve data out of a buffer directly into a class variable + * with data type T while being able to specify endianness. The boolean + * bigEndian specifies whether an endian swap is performed on the data before * serialization or deserialization. * - * If the target architecture is little endian (ARM), any data types created might - * have the wrong endiness if they are to be used for the FSFW. * There are three ways to retrieve data out of a buffer to be used in the FSFW - * to use regular aligned (big endian) data. - * This can also be applied to uint32_t and uint64_t: + * to use regular aligned (big endian) data. Examples: * * 1. Use the AutoSerializeAdapter::deSerialize function - * The pointer *buffer will be incremented automatically by the typeSize of the object, - * so this function can be called on &buffer repeatedly without adjusting pointer position. - * Set bigEndian parameter to true to perform endian swapping. + * The pointer *buffer will be incremented automatically by the typeSize + * of the object, so this function can be called on &buffer repeatedly + * without adjusting pointer position. Set bigEndian parameter to true + * to perform endian swapping, if necessary + * @code + * uint16_t data; + * int32_t dataLen = sizeof(data); + * ReturnValue_t result = + * AutoSerializeAdapter::deSerialize(&data,&buffer,&dataLen,true); + * @endcode * - * uint16_t data; - * int32_t dataLen = sizeof(data); - * ReturnValue_t result = AutoSerializeAdapter::deSerialize(&data,&buffer,&dataLen,true); + * 2. Perform a bitshift operation. Watch for for endianness: + * @code + * uint16_t data; + * data = buffer[targetByte1] << 8 | buffer[targetByte2]; + * data = EndianSwapper::swap(data); //optional, or swap order above + * @endcode * - * 2. Perform a bitshift operation. Perform endian swapping if necessary: + * 3. memcpy or std::copy can also be used, but watch out if system + * endianness is different from required data endianness. + * Perform endian-swapping if necessary. + * @code + * uint16_t data; + * memcpy(&data,buffer + positionOfTargetByte1,sizeof(data)); + * data = EndianSwapper::swap(data); //optional + * @endcode * - * uint16_t data; - * data = buffer[targetByte1] << 8 | buffer[targetByte2]; - * data = EndianSwapper::swap(data); - * - * 3. Memcpy can be used when data is little-endian. Perform endian-swapping if necessary. - * - * uint16_t data; - * memcpy(&data,buffer + positionOfTargetByte1,sizeof(data)); - * data = EndianSwapper::swap(data); - * - * When serializing for downlink, the packets are generally serialized assuming big endian data format - * like seen in TmPacketStored.cpp for example. + * When serializing for downlink, the packets are generally serialized assuming + * big endian data format like seen in TmPacketStored.cpp for example. * * @ingroup serialize */ @@ -80,14 +87,6 @@ public: } } - /** - * Deserialize buffer into object - * @param object [out] Object to be deserialized with buffer data - * @param buffer buffer containing the data. Non-Const pointer to non-const pointer to const buffer. - * @param size int32_t type to allow value to be values smaller than 0, needed for range/size checking - * @param bigEndian Specify endianness - * @return - */ ReturnValue_t deSerialize(T* object, const uint8_t** buffer, int32_t* size, bool bigEndian) { T tmp; @@ -153,7 +152,7 @@ public: } }; -// No type specification necessary here. + class AutoSerializeAdapter { public: template diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index cd040c0f..db7db20a 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -6,23 +6,11 @@ #include /** - * @brief This class is used to mark datatypes for serialization with the - * SerialLinkedListAdapter - * @details - * Used by declaring any arbitrary datatype with SerializeElement myVariable, - * inside a SerialLinkedListAdapter implementation and setting the sequence - * of objects with setNext() and setStart(). - * Serilization and Deserialization is then performed automatically in - * specified sequence order. - * @ingroup serialize + * \ingroup serialize */ template class SerializeElement : public SerializeIF, public LinkedElement { public: - /** - * Arguments are forwarded to the element datatype constructor - * @param args - */ template SerializeElement(Args... args) : LinkedElement(this), entry(std::forward(args)...) { -- 2.43.0 From 794928a2d8d9abbdaa2c0aa27f8a30b6ae5fddca Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 18 Apr 2020 17:00:48 +0200 Subject: [PATCH 3/6] doc updates --- serialize/SerializeElement.h | 24 ++++++++++++++++++++---- serialize/SerializeIF.h | 22 +++++++++++++--------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index db7db20a..be27ef03 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -6,21 +6,34 @@ #include /** - * \ingroup serialize + * @brief This class is used to mark datatypes for serialization with the + * SerialLinkedListAdapter + * @details + * Used by declaring any arbitrary datatype with SerializeElement myVariable, + * inside a SerialLinkedListAdapter implementation and setting the sequence + * of objects with setNext() and setStart(). + * Serilization and Deserialization is then performed automatically in + * specified sequence order. + * @ingroup serialize */ + template class SerializeElement : public SerializeIF, public LinkedElement { public: template - SerializeElement(Args... args) : LinkedElement(this), entry(std::forward(args)...) { + SerializeElement(Args... args) : LinkedElement(this), + entry(std::forward(args)...) { } SerializeElement() : LinkedElement(this) { } + T entry; + ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&entry, buffer, size, max_size, bigEndian); + return SerializeAdapter::serialize(&entry, buffer, size, + max_size, bigEndian); } uint32_t getSerializedSize() const { @@ -29,8 +42,10 @@ public: virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - return SerializeAdapter::deSerialize(&entry, buffer, size, bigEndian); + return SerializeAdapter::deSerialize(&entry, buffer, + size, bigEndian); } + operator T() { return entry; } @@ -39,6 +54,7 @@ public: entry = newValue; return *this; } + T *operator->() { return &entry; } diff --git a/serialize/SerializeIF.h b/serialize/SerializeIF.h index fb750a08..72942b86 100644 --- a/serialize/SerializeIF.h +++ b/serialize/SerializeIF.h @@ -12,17 +12,21 @@ * @brief An interface for alle classes which require * translation of objects data into data streams and vice-versa. * @details - * If the target architecture is little endian (e.g. ARM), any data types created might - * have the wrong endiness if they are to be used for the FSFW. - * There are three ways to retrieve data out of a buffer to be used in the FSFW to use - * regular aligned (big endian) data. This can also be applied to uint32_t and uint64_t: + * If the target architecture is little endian (e.g. ARM), any data types + * created might have the wrong endianess if they are to be used for the FSFW. + * Depending on the system architecture, endian correctness must be assured, + * This is important for incoming and outgoing data. The internal handling + * of data should be performed in the native system endianness. + * There are three ways to copy data (with different options to ensure + * endian correctness): * - * 1. Use the @c AutoSerializeAdapter::deSerialize function with @c bigEndian = true - * 2. Perform a bitshift operation - * 3. @c memcpy can be used when data is in little-endian format. Otherwise, @c EndianSwapper has to be used in conjuction. + * 1. Use the @c AutoSerializeAdapter::deSerialize function (with + * the endian flag) + * 2. Perform a bitshift operation (with correct order) + * 3. @c memcpy (with @c EndianSwapper if necessary) * - * When serializing for downlink, the packets are generally serialized assuming big endian data format - * like seen in TmPacketStored.cpp for example. + * When serializing for downlink, the packets are generally serialized + * assuming big endian data format like seen in TmPacketStored.cpp for example. * * @ingroup serialize */ -- 2.43.0 From 7068043cfc33bd1ce6ba78538c4a4ab2c5511dce Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 18 Apr 2020 17:01:39 +0200 Subject: [PATCH 4/6] SerialFixedArrayListAdapter update This is a little bit more than documentation as I renamed the first template name to make it clearer what each template type means. However, this should not change the way SerialFixedArrayListAdapter behaves. --- serialize/SerialFixedArrayListAdapter.h | 46 ++++++++++++++++++++----- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/serialize/SerialFixedArrayListAdapter.h b/serialize/SerialFixedArrayListAdapter.h index 16919b62..a2d7891d 100644 --- a/serialize/SerialFixedArrayListAdapter.h +++ b/serialize/SerialFixedArrayListAdapter.h @@ -5,27 +5,55 @@ #include /** - * \ingroup serialize + * @brief This adapter provides an interface for SerializeIF to serialize and + * deserialize buffers with a header containing the buffer length. + * @details + * Can be used by SerialLinkedListAdapter by declaring + * as a linked element with SerializeElement>. + * The sequence of objects is defined in the constructor by + * using the setStart and setNext functions. + * + * 1. Buffers with a size header inside that class can be declared with + * @code + * SerialFixedArrayListAdapter mySerialFixedArrayList(...). + * @endcode + * 2. MAX_SIZE specifies the maximum allowed number of elements + * in FixedArrayList. + * 3. BUFFER_TYPE specifies the data type of the buffer header + * containing the buffer size (defaults to 1 byte length field) + * that follows. + * 4. count_t specifies the type of the length field + * + * @ingroup serialize */ -template -class SerialFixedArrayListAdapter : public FixedArrayList, public SerializeIF { +template +class SerialFixedArrayListAdapter : + public FixedArrayList, + public SerializeIF { public: template - SerialFixedArrayListAdapter(Args... args) : FixedArrayList(std::forward(args)...) { + SerialFixedArrayListAdapter(Args... args): + FixedArrayList( + std::forward(args)...) { } + ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - return SerialArrayListAdapter::serialize(this, buffer, size, max_size, bigEndian); + return SerialArrayListAdapter::serialize(this, + buffer, size, max_size, bigEndian); } + uint32_t getSerializedSize() const { - return SerialArrayListAdapter::getSerializedSize(this); + return SerialArrayListAdapter::getSerializedSize(this); } + ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - return SerialArrayListAdapter::deSerialize(this, buffer, size, bigEndian); + return SerialArrayListAdapter::deSerialize(this, + buffer, size, bigEndian); } }; - - #endif /* SERIALFIXEDARRAYLISTADAPTER_H_ */ -- 2.43.0 From 3244f18d41897289964ec4d82b588f721c7eb397 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 18 Apr 2020 17:03:43 +0200 Subject: [PATCH 5/6] removed cookie comment new comment in new CookieIF.h --- devicehandlers/Cookie.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/devicehandlers/Cookie.h b/devicehandlers/Cookie.h index ec22ec3a..495c8c40 100644 --- a/devicehandlers/Cookie.h +++ b/devicehandlers/Cookie.h @@ -1,15 +1,6 @@ #ifndef COOKIE_H_ #define COOKIE_H_ -/** - * @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. This cookie - * can be used in the device communication interface by performing - * a C++ dynamic cast. The cookie can be used to store all kinds of information - * about the communication between read and send calls. - */ class Cookie{ public: virtual ~Cookie(){} -- 2.43.0 From 20d6f1ae2d70c7cbe96b72742d112a6e71bc6f7e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 18 Apr 2020 17:12:26 +0200 Subject: [PATCH 6/6] serial fixed array list adapter doc fix --- serialize/SerialFixedArrayListAdapter.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/serialize/SerialFixedArrayListAdapter.h b/serialize/SerialFixedArrayListAdapter.h index a2d7891d..53cf6070 100644 --- a/serialize/SerialFixedArrayListAdapter.h +++ b/serialize/SerialFixedArrayListAdapter.h @@ -13,17 +13,17 @@ * The sequence of objects is defined in the constructor by * using the setStart and setNext functions. * - * 1. Buffers with a size header inside that class can be declared with - * @code - * SerialFixedArrayListAdapter mySerialFixedArrayList(...). - * @endcode - * 2. MAX_SIZE specifies the maximum allowed number of elements - * in FixedArrayList. - * 3. BUFFER_TYPE specifies the data type of the buffer header - * containing the buffer size (defaults to 1 byte length field) - * that follows. - * 4. count_t specifies the type of the length field + * @endcode + * + * - MAX_SIZE: specifies the maximum allowed number of elements + * in FixedArrayList. + * - BUFFER_TYPE: specifies the data type of the buffer + * - count_t: specifies the type/size of the length field + * which defaults to one byte. * * @ingroup serialize */ -- 2.43.0