From 85833018ae981303a87c43c16a16c5078e0731b6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 19 Mar 2020 12:53:36 +0100 Subject: [PATCH] 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