8. Software Style Guide

8.1. General

All plain text files must end with a single empty line (POSIX, 3.206 Line).

8.2. File Templates

All file templates are found in /tools/styleguide/file-templates

8.2.1. Source Code

In short: For foxbms we use for the embedded code 1TBS (check by cpplint) and flake8 for the python code.

Listing 8.1 Template for C files
/**
 *
 * @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
 *  angewandten Forschung e.V. All rights reserved.
 *
 * BSD 3-Clause License
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1.  Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of the copyright holder nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * We kindly request you to use one or more of the following phrases to refer
 * to foxBMS in your hardware, software, documentation or advertising
 * materials:
 *
 * ″This product uses parts of foxBMS®″
 *
 * ″This product includes parts of foxBMS®″
 *
 * ″This product is derived from foxBMS®″
 *
 */

/**
 * @file    file.c
 * @author  foxBMS Team
 * @date    00.00.0000 (date of creation)
 * @ingroup X_INGROUP
 * @prefix  XXX
 *
 * @brief   abc
 *
 * @details def
 *
 */

/*================== Includes ===============================================*/
#include "template.h"

/*================== Macros and Definitions =================================*/

/*================== Static Constant and Variable Definitions ===============*/

/*================== Extern Constant and Variable Definitions ===============*/

/*================== Static Function Prototypes =============================*/

/*================== Static Function Implementations ========================*/

/*================== Extern Function Implementations ========================*/
Listing 8.2 Template for h files
/**
 *
 * @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
 *  angewandten Forschung e.V. All rights reserved.
 *
 * BSD 3-Clause License
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1.  Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of the copyright holder nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * We kindly request you to use one or more of the following phrases to refer
 * to foxBMS in your hardware, software, documentation or advertising
 * materials:
 *
 * ″This product uses parts of foxBMS®″
 *
 * ″This product includes parts of foxBMS®″
 *
 * ″This product is derived from foxBMS®″
 *
 */

/**
 * @file    file.h
 * @author  foxBMS Team
 * @date    00.00.0000 (date of creation)
 * @ingroup X_INGROUP
 * @prefix  XXX
 *
 * @brief   abc
 *
 * @details def
 *
 */

#ifndef TEMPLATE_H_
#define TEMPLATE_H_

/*================== Includes ===============================================*/

/*================== Macros and Definitions =================================*/

/*================== Extern Constant and Variable Declarations ==============*/

/*================== Extern Function Prototypes =============================*/

#endif /* TEMPLATE_H_ */
Listing 8.3 Template for python scripts
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
#   angewandten Forschung e.V. All rights reserved.
#
# BSD 3-Clause License
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1.  Redistributions of source code must retain the above copyright notice,
#     this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions and the following disclaimer in the documentation
#     and/or other materials provided with the distribution.
# 3.  Neither the name of the copyright holder nor the names of its
#     contributors may be used to endorse or promote products derived from this
#     software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# We kindly request you to use one or more of the following phrases to refer to
# foxBMS in your hardware, software, documentation or advertising materials:
#
# ″This product uses parts of foxBMS®″
#
# ″This product includes parts of foxBMS®″
#
# ″This product is derived from foxBMS®″

"""Example docstring

MUST BE GIVEN
"""
import os
import sys
import argparse
import logging

__version__ = 0.1
__date__ = '2017-12-05'
__updated__ = '2017-12-05'


def main():
    """Use google style docstrings
from http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html
    """
    program_name = os.path.basename(sys.argv[0])
    program_version = '{}'.format(__version__)
    program_build_date = str(__updated__)
    program_version_message = '{} {}'.format(
        program_version, program_build_date)
    program_shortdesc = __import__('__main__').__doc__.split('\n')[1]
    program_license = '''{}
{}

    Created by the foxBMS Team on {}.
    Copyright 2018 foxBMS. All rights reserved.

    Licensed under the BSD 3-Clause License.

    Distributed on an "AS IS" basis without warranties
    or conditions of any kind, either express or implied.

USAGE
'''.format(program_name, program_shortdesc, str(__date__))

    parser = argparse.ArgumentParser(
        description=program_license,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument(
        '-v',
        '--verbosity',
        dest='verbosity',
        action='count',
        default=0,
        help='set verbosity level')
    parser.add_argument(
        '-V',
        '--version',
        action='version',
        version=program_version_message)

    args = parser.parse_args()

    if args.verbosity == 1:
        logging.basicConfig(level=logging.INFO)
    elif args.verbosity > 1:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.ERROR)


if __name__ == '__main__':
    main()

8.2.2. Documentation

Listing 8.4 Template for reStructuredText
.. include:: ../../macros.rst (RELATIVE LINK, MUST BE ADAPTED)


.. _DEFINE_A_LABEL_WHICH_STARTS_WITH_UNDERSCORE:

========
HEADINGS
========

TEXT TEXT

.. _DEFINE_Another_LABEL_WHICH_STARTS_WITH_UNDERSCORE:

SMALLER HEADING
---------------

TEXT TEXT

8.3. Details

8.3.1. C Sources

8.3.1.1. Doxygen

Every function has doxygen style documentation. For extern function these are in the header file, for static function these are in the c file at the implementation.

/**
 * @brief   sets the current state request of the state variable cont_state.
 *
 * @details This function is used to make a state request to the state machine,e.g, start voltage
 *          measurement, read result of voltage measurement, re-initialization.
 *          It calls CONT_CheckStateRequest() to check if the request is valid. The state request
 *          is rejected if is not valid. The result of the check is returned immediately, so that
 *          the requester can act in case it made a non-valid state request.
 *
 * @param   state request to set
 *
 * @return  CONT_OK if a state request was made, CONT_STATE_NO_REQUEST if no state request was made
 */
CONT_RETURN_TYPE_e CONT_SetStateRequest(CONT_STATE_REQUEST_e statereq) {
    CONT_RETURN_TYPE_e retVal = CONT_STATE_NO_REQUEST;

    taskENTER_CRITICAL();
    retVal = CONT_CheckStateRequest(statereq);

    if (retVal == CONT_OK) {
            cont_state.statereq   = statereq;
    }
    taskEXIT_CRITICAL();

    return retVal;
}

8.3.1.2. Include Guard

The include guard must have the following form (considerng the filename is template.h)

#ifndef TEMPLATE_H_
#define TEMPLATE_H_

#endif /* TEMPLATE_H_ */

8.3.1.3. Naming conventions

Variables

  • The module acronym must be used as prefix.
  • All variable names must be in lower case.
  • No prefix or suffix is required to distinguish global from static variables.
  • Underscores may be used in the name of variables.

Functions

  • The module acronym must be used as prefix.
  • All function names starts with its acronym in capital letters followed by a concatenation of words where first letter of each word should start with capital letters.
  • No prefix or suffix is required to distinguish extern from static functions.
  • Underscores may be used in the name of functions.

Macros

  • The module acronym must be used as prefix.
  • All macro names must be in uppercase letters.
  • Underscores may be used in the name of macros.

Examples

Module Acronym Example
spi.c/h SPI
SPI_Init()
spi_state
SPI_MACRO
measurement.c/h MEAS
MEAS_Init()
meas_state
MEAS_MACRO

Typedefs, Enums and Structs

  • The module acronym must be used as prefix.
  • All enum/struct names must be in uppercase letters.
  • Underscores may be used in the name of enums/structs.
  • Every enum/struct must be typedefed.
  • Every enum/struct must have a general doxygen documentation comment in the form of /** documentation comment */
  • Every enum/struct entry must be documented by a doxygen comment in the form of /*!< documentation comment */.
/** diagnosis handler return types */
typedef enum {
    DIAG_HANDLER_RETURN_OK                  = 0,            /*!<  error not occured or occured but threshold not reached */
    DIAG_HANDLER_RETURN_ERR_OCCURED         = 2,            /*!<  error occured and enabled */
    DIAG_HANDLER_RETURN_WARNING_OCCURRED    = 3,            /*!<  warning occured (error occured but not enabled) */
    DIAG_HANDLER_RETURN_ERR_OCCURRED        = 4,            /*!<  error occured and enabled */
    DIAG_HANDLER_RETURN_WRONG_ID            = 5,            /*!<  wrong diagnosis id */
    DIAG_HANDLER_RETURN_UNKNOWN             = 6,            /*!<  unknown return type */
    DIAG_HANDLER_INVALID_TYPE               = 7,            /*!<  invalid diagnosis type, error in configuration */
    DIAG_HANDLER_INVALID_DATA               = 8,            /*!<  invalid data, dependent of the diagHandler */
    DIAG_HANDLER_RETURN_NOT_READY           = 0xFFFFFFFF,   /*!<  diagnosis handler not ready */
} DIAG_RETURNTYPE_e;

8.3.2. Includes

There are two scenarios to be considered for file includes. These are shown below.

8.3.2.1. Scenario 1

Normally a every software part has the following structure, considering a driver called abc:

  • *\config\abc_cfg.c
  • *\config\abc_cfg.h
  • *\abc\abc.c
  • *\abc\abc.h

The include strcture has then always to be like this:

Listing 8.5 abc_cfg.h
/* THE DRIVER CONFIGURATION HEADER abc_cfg.h ALWAYS INCLUDES general.h FIRST */
/* IF ADDITIONAL HEADERS ARE NEEDED FOR TYPES ETC. THESE ARE INCLUDED BELOW */
#include "general.h"
#include "additionally_needed_header_1.h"
Listing 8.6 abc_cfg.c
/* THE DRIVER CONFIGURATION IMPLEMENTATION abc_cfg.c ALWAYS INCLUDES THE CONFIGURATION HEADER abc_cfg.h FIRST */
/* NEVER INCLUDE general.h IN THE DRIVER CONFIGURATION IMPLEMENTATION FILE abc_cfg.c */
/* IF ADDITIONAL HEADERS ARE NEEDED FOR TYPES ETC. THESE ARE INCLUDED BELOW */
#include "abc_cfg.h"
#include "additionally_needed_header_2.h"
Listing 8.7 abc.h
/* THE DRIVER HEADER abc.h ALWAYS INCLUDES THE DRIVER CONFIGURATION HEADER abc_cfg.h FIRST */
/* NEVER INCLUDE general.h IN THE DRIVER HEADER FILE abc.h */
/* IF ADDITIONAL HEADERS ARE NEEDED FOR TYPES ETC. THESE ARE INCLUDED BELOW */
#include "abc_cfg.h"
#include "additionally_needed_header_3.h"
Listing 8.8 abc.c
/* THE DRIVER IMPLEMENTATION abc.c ALWAYS INCLUDES THE DRIVER HEADER abc.h FIRST */
/* NEVER INCLUDE general.h IN THE DRIVER IMPLEMENTATION FILE abc.c */
/* IF ADDITIONAL HEADERS ARE NEEDED FOR TYPES ETC. THESE ARE INCLUDED BELOW */
#include "abc.h"
#include "additionally_needed_header_4.h"

8.3.2.2. Scenario 2

If a software only has a driver header and a driver implementation

  • *\abc\abc.c
  • *\abc\abc.h

the include rules changed to

Listing 8.9 abc.h
/* THE DRIVER HEADER abc.h ALWAYS INCLUDES general.h FIRST */
/* IF ADDITIONAL HEADERS ARE NEEDED FOR TYPES ETC. THESE ARE INCLUDED BELOW */
#include "general.h"
#include "additionally_needed_header_1.h"
Listing 8.10 abc.c
/* THE DRIVER IMPLEMENTATION abc.c ALWAYS INCLUDES THE DRIVER HEADER abc.h FIRST */
/* NEVER INCLUDE general.h IN THE DRIVER IMPLEMENTATION FILE abc.c */
/* IF ADDITIONAL HEADERS ARE NEEDED FOR TYPES ETC. THESE ARE INCLUDED BELOW */
#include "abc.h"
#include "additionally_needed_header_2.h"