ChibiOS Code Style Guide

ChibiOS/RT code follows well define style conventions that must be followed in order to have code accepted in the distribution.

Why so much focus on Style

Simply because we believe that a good product must be consistent, it is not acceptable to have different modules following different styles.

C dialect

The whole portable code base must be C99 compliant. Compiler-specific constructs must be restricted in non-portable modules or abstraction macros, modules tagged as portable must be strict C99.

In addition, portable modules must be MISRA-94 compliant and checked, deviation to the rules must be marked either with code tagging or a global waiver.

C Code style conventions

ChibiOS follows the K&R indentation style with few modifications:

  • Only two spaces are used for indentation.
  • TAB characters are forbidden everywhere.
  • Non UTF-8 characters are forbidden everywhere.
  • EOL must be CRLF (windows convention).
  • The else statement goes to the line after the closing }.
  • Column 80 must not be exceeded unless there is some technical reason because the line cannot be split. Consider column 100 to be an hard limit.
  • A single space must follow the statements: if, while, do and switch before the expression opening (.
  • The expression following a return statement must not be surrounded by ( and ).
  • #ifdef and #ifndef are not recommended, use #if defined() and #if !defined() instead.
  • The case statements are indented to the same level of their switch statement.
  • Pointer variable names are usually suffixed by a “p”, there are no other concessions to types into names.
  • Automatic variables are recommended to be all lower case with an underscore as separator.
  • Defined types must be all lower case and be suffixed by “_t”. There is a legacy exception to this in HAL where driver structure types are camel case.
  • Multiple statement on a single line are discouraged.
  • API functions are camel case with first letter lower case.
  • Internal functions, including static functions, must be all lower case with an underscore as separator.

Empty Lines

The use of empty lines varies:

  • More than one consecutive empty lines are forbidden everywhere.
  • An empty line between functions is mandatory.
  • Empty lines between logical code blocks are mandatory.
    • Code blocks start and end at the same indentation level.
    • Code blocks can include higher indentation sub-blocks.

Example:

  /* Comment about the block1.*/
  Block1 statements...
 
  /* Comment about the block2.*/
  Block2 statements...
 
  /* Comment about the block3.*/
  Block3 statements...
  statement {
    /* Comment about the sub-block1.*/
    Sub-block1 statements...
  }
  Block3 more statements...

Comments

Of course there are rules about comments.

Global objects

  • Comments must be written using Doxygen tags using the /** prefix, the /*! prefix is forbidden.
  • Comments of private or static objects should be done using Doxygen but it is not mandatory.

Doxygen usage

Please use the following general Doxygen template:

/**
 * @brief   A brief description, one sentence, one line.
 * @details A detailed description of the functionality, it can span over
 *          multiple lines, can be omitted.
 * @pre     Prerequisites about the use of the functionality, there can be
 *          more than one "pre" tags, can be omitted.
 * @post    Postrequisites about the use of the functionality, there can be
 *          more than one "post" tags, can be omitted.
 * @note    There can be one or more notes, can be omitted.
 *
 * @param[in] p1        description of parameter one
 * @param[out] p2       description of parameter two
 * @param[in,out] p3    description of parameter three
 * @return              Description of the returned value, must be omitted if
 *                      a function returns void.
 * @retval VALUE1       description of the special returned value one, can be
 *                      omitted.
 * @retval VALUE2       description of the special returned value two, can be
 *                      omitted.
 *
 * @api|@notapi|@special|@init|@sclass|@iclass|@xclass|@isr
 */

Notes:

  • Brief description and documentation of all parameters and return are mandatory.
  • The shown indenting columns are mandatory.
  • The text sections always begin with an upper case with the exception of text following @param and @retval.
  • The last tag is ChibiOS-defined and has the following meaning:
    • @api, a normal API usable from thread context.
    • @notapi, not an API, internal use only.
    • @special, an API with special usage protocol, see notes.
    • @init, an API that initializes an object, can be invoked even before the system is started.
    • @sclass, an S-Class API.
    • @iclass, an I-Class API.
    • @xclass, an X-class API.
    • @isr, an IRQ handler.
  • Text sections are always terminated with a dot except the text following @param and unless the text following @param is composed of multiple sentences.
  • The tag @p is mandatory before words representing code objects, for example: @p NULL, @p foo(), @p i2cp param.

Comments inside functions

The preferred style of comment are the following, note:

  • There must be one space after the /*.
  • Comments always start with an upper case.
  • Comments are always terminated with a dot.
  • There is no space between the final dot and the closing */.
  • Multiple line comments do not have a * as line start.
  /* This is a single line comment.*/
 
  /* This is a very long comment that necessarily has to span over
     multiple lines.*/
  • Comments on the right of a code line are not recommended unless can all be aligned elegantly to the same column. Alignment must be followed for both the /* and the */ using spaces for padding.