-
Notifications
You must be signed in to change notification settings - Fork 108
Doxygen standards
All public C API must be documented with Doxygen.
List of commands:
https://www.stack.nl/~dimitri/doxygen/manual/commands.html
Doxygen supports many ways to write docs, so we'll try to follow some standards for our project, exemplified below
How you should write a function documentation:
-
@brief with a very small description to be listed together with the function signature. Otherwise everything only will be displayed on "Detailed Description" section, reducing documentation readability.
-
More details in extra paragraphs
-
Eventual notes should be done with @note
-
Extra function references for the reader can be made with @see
-
If parameters must be referenced, use command @a
-
If something else must be referenced, like structs, use @ref command.
-
For values, use @c so it'll use typewriter font
-
Add @param for each parameter. On same cases may be useful to highlight values that can or cannot be passed, like NULL, etc
-
Finally, add a @return command if function isn't void. If memory must be freed for the user, you must tell her here. If other specific functions must be used too.
/**
- @brief Opens a given pin by its board label as general purpose input or output.
- This function only works when the board was successfully detected
- by Soletta and a corresponding
- pin multiplexer module was found.
- @note A pin defined by @a label should be opened just once, calling this function more than once
- for the same pin results in undefined behavior - per platform basis.
- @see sol_gpio_open_raw(), sol_gpio_close().
- @param label The pin to be opened.
- @param config Contains the pin configuration.
- @return A new @ref sol_gpio instance on success, @c NULL otherwise. */ struct sol_gpio *sol_gpio_open_by_label(const char *label, const struct sol_gpio_config *config) SOL_ATTR_WARN_UNUSED_RESULT;
Fields can be documented inline (with /**< ... */) or above (specially useful for complex stuff).
Remember to keep a @brief with a very small description to be listed together with the struct / enum in any case. Otherwise everything only will be displayed on "Detailed Description" section, reducing documentation readability.
/**
* @brief Enum for I2C bus speed.
*
* Must be choosen when opening a bus with sol_i2c_open() and
* sol_i2c_open_raw().
*/
enum sol_i2c_speed {
SOL_I2C_SPEED_10KBIT = 0, /**< flag for low speed */
SOL_I2C_SPEED_100KBIT, /**< flag for normal speed */
SOL_I2C_SPEED_400KBIT, /**< flag for fast speed */
SOL_I2C_SPEED_1MBIT, /**< flag for fast plus speed */
SOL_I2C_SPEED_3MBIT_400KBIT /**< flag for high speed */
};
/**
* @brief Structure to hold the configuration of a GPIO device.
*
* When opening a GPIO with sol_gpio_open_by_label(), sol_gpio_open() or
* sol_gpio_open_raw(), the parameters with which the GPIO is configured are
* those defined in this structure.
*
* If there's a need to change any of these parameters, the GPIO must be closed
* and opened again with a new configuration.
*/
struct sol_gpio_config {
#ifndef SOL_NO_API_VERSION
#define SOL_GPIO_CONFIG_API_VERSION (1)
uint16_t api_version;
#endif
/**
* The direction in which to open the GPIO.
*/
enum sol_gpio_direction dir;
/**
* Whether the GPIO is considered active when it's in a low state.
*
* If set, then the logical state of the GPIO will be reversed in relation
* to the physical state. That is, for input GPIOs, when the current on
* the wire goes to a low state, the value returned by sol_gpio_read() will
* be @c true. Conversely, it will be @c false when the physical state is
* high.
*
* The same logic applies for output GPIOs when a value is written through
* sol_gpio_write().
*
* This is useful to keep the application logic simpler in the face of
* different hardware configurations.
*/
bool active_low;
/**
* Pull-up or pull-down resistor state for this GPIO.
*
* One of #sol_gpio_drive. Some platforms will configure GPIO taking
* this in consideration, as Continki and RIOT.
*/
enum sol_gpio_drive drive_mode;
union {
/**
* Configuration parameters for input GPIOs.
*/
struct {
/**
* When to trigger events for this GPIO.
*
* One of #sol_gpio_edge. If the value set is anything other
* than #SOL_GPIO_EDGE_NONE, then the @c cb member must be set.
*/
enum sol_gpio_edge trigger_mode;
/**
* The function to call when an event happens.
*
* Different systems handle interruptions differently, and so to
* maintain consistency across them, there is no queue of values
* triggered by interruptions. Instead, when an interruption
* happens, the main loop will handle it and call the user function
* provided here, with the value of the GPIO at that time.
* This means that the if the application takes too long to return
* to the main loop while interruptions are happening, some of those
* values will be lost.
*
* @param data The user data pointer provided in @c user_data.
* @param gpio The GPIO instance that triggered the event.
* @param value The value of the GPIO at the moment the function
* is called.
*/
void (*cb)(void *data, struct sol_gpio *gpio, bool value);
* [...]
/**
* @defgroup GPIO GPIO
* @ingroup IO
*
* GPIO (General Purpose Input/Output) API for Soletta.
*
* @{
*/
Root groups must be added to our mainpage list at src/lib/common/include/sol-mainloop.h
E.g.:
/**
* @mainpage Soletta Project Documentation
*
* [...]
* For a better reference, check the following groups:
* @li @ref Comms
* @li @ref Datatypes
* @li @ref Flow
* @li @ref IO
* [...]
*/
/**
* @file
* @brief These routines are used for GPIO access under Soletta.
*/
* SML is divided in the following groups:
*
* @li @ref Engine
* @li @ref Fuzzy_Engine
* @li @ref Log
* @li @ref Mainloop
* @li @ref Ann_Engine
* @li @ref Variables
* Choosing engines and creating variables is straight-forward after
* [...]
*
* @dontinclude example_doc.c
* @skip main
* @until sml_set_output_state_changed_callback
*
* Terms are a way to split the values in the range in meaningful parts.
* [...]
*
* @until }