-Coding Style
-============
+.. _coding_style:
+
+DPDK Coding Style
+=================
Description
-----------
~~~~~~~~~~~~~~
These comments should be used in normal cases.
-To document a public API, a doxygen-like format must be used: refer to Doxygen Documentation.
+To document a public API, a doxygen-like format must be used: refer to :ref:`doxygen_guidelines`.
.. code-block:: c
* Function prototypes should be listed in a logical order, preferably alphabetical unless there is a compelling reason to use a different ordering.
* Functions that are used locally in more than one module go into a separate header file, for example, "extern.h".
* Do not use the ``__P`` macro.
-* Functions that are part of an external API should be documented using Doxygen-like comments above declarations. See the Doxgen documentation topic for details.
+* Functions that are part of an external API should be documented using Doxygen-like comments above declarations. See :ref:`doxygen_guidelines` for details.
* Functions that are part of the external API must have an ``rte_`` prefix on the function name.
* Do not use uppercase letters - either in the form of ALL_UPPERCASE, or CamelCase - in function names. Lower-case letters and underscores only.
* When prototyping functions, associate names with parameter types, for example:
usage();
/* NOTREACHED */
}
-
-Doxygen Documentation
----------------------
-
-The API documentation is automatically generated in the DPDK framework.
-That is why all files that are part of the public API must be documented using Doxygen syntax.
-
-The public API comprises functions of DPDK that can be used by an external application that will use the SDK.
-Only the Doxygen syntax described in the coding rules (this document) should be used in the code.
-All the Doxygen features are described in the Doxygen manual online.
-
-Documenting a Function
-~~~~~~~~~~~~~~~~~~~~~~
-
-All public functions must be documented. The documentation is placed in the header file, above the declaration of the function.
-The definition of the function may be documented, but using standard comments (not in doxygen format).
-The following is an example of function documentation:
-
-.. code-block:: c
-
- /**
- * Summary here; one sentence on one line (should not exceed 80 chars).
- *
- * A more detailed description goes here.
- *
- * A blank line forms a paragraph. There should be no trailing white-space
- * anywhere.
- *
- * @param first
- * "@param" is a Doxygen directive to describe a function parameter. Like
- * some other directives, it takes a term/summary on the same line and a
- * description (this text) indented by 2 spaces on the next line. All
- * descriptive text should wrap at 80 chars, without going over.
- * Newlines are NOT supported within directives; if a newline would be
- * before this text, it would be appended to the general description above.
- * @param second
- * There should be no newline between multiple directives (of the same
- * type).
- *
- * @return
- * "@return" is a different Doxygen directive to describe the return value
- * of a function, if there is any.
- */
- int rte_foo(int first, int second)
-
-
-Documenting Files
-~~~~~~~~~~~~~~~~~
-
-Each public file may start with a comment describing what the file does. For example:
-
-.. code-block:: c
-
- /**
- * @file
- * This file describes the coding rules of RTE.
- *
- * It contains the coding rules of C code, ASM code, reStructured
- * Text documentation, and of course how to use doxygen to document
- * public API.
- */
-
-
-Documenting Constants and Variables
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Examples:
-
-.. code-block:: c
-
- /**
- * The definition of a funny TRUE.
- */
- #define TRUE 0
-
- #define TRUE 1 /**< another way to document a macro */
-
- /**
- * Frequency of the HPET counter in Hz
- *
- * @see rte_eal_hpet_init()
- */
- extern uint64_t eal_hpet_resolution_hz;
-
-
-Documenting Structures
-~~~~~~~~~~~~~~~~~~~~~~
-
-Public structures should also be documented.
-The ``/**<`` sequence can be used to documented the fields of the structure, as shown in the following example:
-
-.. code-block:: c
-
- /**
- * Structure describing a memzone, which is a contiguous portions of
- * physical memory identified by a name.
- */
- struct rte_memzone {
-
- #define MEMZONE_NAMESIZE 32
- char name[MEMZONE_NAMESIZE]; /**< name of the memory zone */
-
- phys_addr_t phys_addr; /**< start physical address */
- void *addr; /**< start virtual address */
- uint64_t len; /**< len of the memzone */
-
- int socket_id; /**< NUMA socket id */
- };
-
-
-See Also Sections
-~~~~~~~~~~~~~~~~~
-
-The @see keyword can be used to highlight a link to an existing function, file, or URL.
-This directive should be placed on one line, without anything else, at the bottom of the documentation header.
-
-.. code-block:: c
-
- /**
- * (documentation of function, file, ...)
- *
- * @see rte_foo()
- * @see eal_memzone.c
- */
* The use of a label is preferred since it works across files and will still work if the header text changes.
+
+.. _doxygen_guidelines:
+
+Doxygen Guidelines
+------------------
+
+The DPDK API is documented using Doxygen comment annotations in the header files.
+Doxygen is a very powerful tool, it is extremely configurable and with a little effort can be used to create expressive documents.
+See the `Doxygen website <http://www.stack.nl/~dimitri/doxygen/>`_ for full details on how to use it.
+
+The following are some guidelines for use of Doxygen in the DPDK API documentation:
+
+* New libraries that are documented with Doxygen should be added to the Doxygen configuration file: ``doc/api/doxy-api.conf``.
+ It is only required to add the directory that contains the files.
+ It isn't necessary to explicitly name each file since the configuration matches all ``rte_*.h`` files in the directory.
+
+* Use proper capitalization and punctuation in the Doxygen comments since they will become sentences in the documentation.
+ This in particular applies to single line comments, which is the case the is most often forgotten.
+
+* Use ``@`` style Doxygen commands instead of ``\`` style commands.
+
+* Add a general description of each library at the head of the main header files:
+
+ .. code-block:: c
+
+ /**
+ * @file
+ * RTE Mempool.
+ *
+ * A memory pool is an allocator of fixed-size object. It is
+ * identified by its name, and uses a ring to store free objects.
+ * ...
+ */
+
+* Document the purpose of a function, the parameters used and the return
+ value:
+
+ .. code-block:: c
+
+ /**
+ * Attach a new Ethernet device specified by arguments.
+ *
+ * @param devargs
+ * A pointer to a strings array describing the new device
+ * to be attached. The strings should be a pci address like
+ * `0000:01:00.0` or **virtual** device name like `eth_pcap0`.
+ * @param port_id
+ * A pointer to a port identifier actually attached.
+ *
+ * @return
+ * 0 on success and port_id is filled, negative on error.
+ */
+ int rte_eth_dev_attach(const char *devargs, uint8_t *port_id);
+
+* Doxygen supports Markdown style syntax such as bold, italics, fixed width text and lists.
+ For example the second line in the ``devargs`` parameter in the previous example will be rendered as:
+
+ The strings should be a pci address like ``0000:01:00.0`` or **virtual** device name like ``eth_pcap0``.
+
+* Use ``-`` instead of ``*`` for lists within the Doxygen comment since the latter can get confused with the comment delimiter.
+
+* Add an empty line between the function description, the ``@params`` and ``@return`` for readability.
+
+* Place the ``@params`` description on separate line and indent it by 2 spaces.
+ (It would be better to use no indentation since this is more common and also because checkpatch complains about leading
+ whitespace in comments.
+ However this is the convention used in the existing DPDK code.)
+
+* Documented functions can be linked to simply by adding ``()`` to the function name:
+
+ .. code-block:: c
+
+ /**
+ * The functions exported by the application Ethernet API to setup
+ * a device designated by its port identifier must be invoked in
+ * the following order:
+ * - rte_eth_dev_configure()
+ * - rte_eth_tx_queue_setup()
+ * - rte_eth_rx_queue_setup()
+ * - rte_eth_dev_start()
+ */
+
+ In the API documentation the functions will be rendered as links, see the
+ `online section of the rte_ethdev.h docs <http://dpdk.org/doc/api/rte__ethdev_8h.html>`_ that contains the above text.
+
+* The ``@see`` keyword can be used to create a *see also* link to another file or library.
+ This directive should be placed on one line at the bottom of the documentation section.
+
+ .. code-block:: c
+
+ /**
+ * ...
+ *
+ * Some text that references mempools.
+ *
+ * @see eal_memzone.c
+ */
+
+* Doxygen supports two types of comments for documenting variables, constants and members: prefix and postfix:
+
+ .. code-block:: c
+
+ /** This is a prefix comment. */
+ #define RTE_FOO_ERROR 0x023.
+
+ #define RTE_BAR_ERROR 0x024. /**< This is a postfix comment. */
+
+* Postfix comments are preferred for struct members and constants if they can be documented in the same way:
+
+ .. code-block:: c
+
+ struct rte_eth_stats {
+ uint64_t ipackets; /**< Total number of received packets. */
+ uint64_t opackets; /**< Total number of transmitted packets.*/
+ uint64_t ibytes; /**< Total number of received bytes. */
+ uint64_t obytes; /**< Total number of transmitted bytes. */
+ uint64_t imissed; /**< Total of RX missed packets. */
+ uint64_t ibadcrc; /**< Total of RX packets with CRC error. */
+ uint64_t ibadlen; /**< Total of RX packets with bad length. */
+ }
+
+ Note: postfix comments should be aligned with spaces not tabs in accordance
+ with the :ref:`coding_style`.
+
+* If a single comment type can't be used, due to line length limitations then
+ prefix comments should be preferred.
+ For example this section of the code contains prefix comments, postfix comments on the same line and postfix
+ comments on a separate line:
+
+ .. code-block:: c
+
+ /** Number of elements in the elt_pa array. */
+ uint32_t pg_num __rte_cache_aligned;
+ uint32_t pg_shift; /**< LOG2 of the physical pages. */
+ uintptr_t pg_mask; /**< Physical page mask value. */
+ uintptr_t elt_va_start;
+ /**< Virtual address of the first mempool object. */
+ uintptr_t elt_va_end;
+ /**< Virtual address of the <size + 1> mempool object. */
+ phys_addr_t elt_pa[MEMPOOL_PG_NUM_DEFAULT];
+ /**< Array of physical page addresses for the mempool buffer. */
+
+ This doesn't have an effect on the rendered documentation but it is confusing for the developer reading the code.
+ It this case it would be clearer to use prefix comments throughout:
+
+ .. code-block:: c
+
+ /** Number of elements in the elt_pa array. */
+ uint32_t pg_num __rte_cache_aligned;
+ /** LOG2 of the physical pages. */
+ uint32_t pg_shift;
+ /** Physical page mask value. */
+ uintptr_t pg_mask;
+ /** Virtual address of the first mempool object. */
+ uintptr_t elt_va_start;
+ /** Virtual address of the <size + 1> mempool object. */
+ uintptr_t elt_va_end;
+ /** Array of physical page addresses for the mempool buffer. */
+ phys_addr_t elt_pa[MEMPOOL_PG_NUM_DEFAULT];
+
+* Check for Doxygen warnings in new code by checking the API documentation build::
+
+ make doc-api-html >/dev/null
+
+* Read the rendered section of the documentation that you have added for correctness, clarity and consistency
+ with the surrounding text.