2.2. C Coding Guidelines

These coding guidelines MUST be applied to all C source and header files.

The source files MUST be successfully checked by running the pre-commit check before files can be merged into the master branch of the repository.

Generally foxBMS 2 uses for the embedded code 1TBS. This is checked by clang-format. The clang-format configuration is found in the root of the repository in .clang-format. Directories that should not be automatically formatted must include a .clang-format file to disable automatic formatting:

DisableFormat: true
SortIncludes: false

The C source and header files can be checked by running pre-commit. Using VS Code files are automatically saved correctly (see Creating a Workspace) when clang-format is installed (see Software Prerequisites) using Ctrl-S.

Warning

The style of third party sources (generated HAL sources in build/bin/src/hal/** and src/os) should not be changed. To save without reformatting use Ctrl-K + Ctrl-Shift-S.

The following list shows more detailed rules for foxBMS 2. Every rule has some context and/or rationale and notes that clearly state the rules, followed by a correct examples. If it supports the clarification incorrect examples may also be shown.

The following rules generally apply and follow the naming pattern C:<ongoing-number>.

2.2.1. Filenames (C:001)

Additional to the general file naming rules the following MUST be applied.

File name rules

  • The general file naming rules MUST be applied (see Section 2.1.1).

  • Assembler source files MUST use .asm as file extension.

  • C source files MUST use .c as file extension.

  • C header files MUST use .h as file extension.

  • Software functionalities (e.g., low level driver, algorithms, etc…) should be split in configuration files and the actual implementation. These configuration files MUST end with _cfg.c or _cfg.h respectively.

For example the valid file names for an implementation of driver, that is split into a driver and a configuration part, is:

  • driver.c

  • driver.h

  • driver_cfg.c

  • driver_cfg.h

2.2.2. Header (C:002)

C file header

C source and header files MUST start with the following header:

Listing 2.2 File header for all .c and .h files.
 1/**
 2 *
 3 * @copyright &copy; 2010 - 2024, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
 4 * All rights reserved.
 5 *
 6 * SPDX-License-Identifier: BSD-3-Clause
 7 *
 8 * Redistribution and use in source and binary forms, with or without
 9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice, this
12 *    list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 *    contributors may be used to endorse or promote products derived from
20 *    this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * We kindly request you to use one or more of the following phrases to refer to
34 * foxBMS in your hardware, software, documentation or advertising materials:
35 *
36 * - "This product uses parts of foxBMS&reg;"
37 * - "This product includes parts of foxBMS&reg;"
38 * - "This product is derived from foxBMS&reg;"
39 *
40 */

2.2.3. Line length (C:003)

Line length rules

  • Each line of text in your code SHOULD be at most 120 characters long. A line MAY exceed 120 characters if it is

    • a comment line which is not feasible to split without harming readability, ease of cut and paste or auto-linking, e.g., if a line contains an example command or a literal URL longer than 120 characters or

    • raw-string literal with content that exceeds 120 characters. Except for test code, such literals should appear near the top of a file.

  • Each line of doxygen comment in your code SHOULD be at most 80 characters long. A line MAY exceed 80 characters if it is

    • a comment line which is not feasible to split without harming readability, auto-linking, e.g., a literal URL longer than 80 characters or

    • a raw-string literal with content that exceeds 80 characters.

2.2.4. File level doxygen (C:004)

Doxygen is used to create an API documentation.

File level doxygen rule

  • Every file MUST be documented with doxygen style comments in order to be properly processed by doxygen.

  • The file level doxygen MUST come after the license header separated by a blank line.

  • The following doxygen parameters MUST be included in every file: @file, @author, @date, @updated, @ingroup, @prefix, @brief, @details

  • All doxygen parameter arguments MUST be whitespace aligned.

  • After @prefix, @brief and @details there MUST be an blank line.

  • The @prefix argument MUST use between two and five uppercase alphanumericals starting with an uppercase character.

  • The @prefix argument MAY use abbreviations.

  • The @prefix and @ingroup arguments MUST use alphanumeric uppercase characters including underscores.

  • The @date argument MUST be an ISO 8601 date followed by (date of creation).

  • The @updated argument MUST be an ISO 8601 date followed by (date of last update).

Listing 2.3 shows how this looks for a file c-004.c.

Listing 2.3 File level doxygen for c-004.c
 1/**
 2 * @file    c-004.c
 3 * @author  foxBMS Team
 4 * @date    2021-06-04 (date of creation)
 5 * @updated 2024-08-08 (date of last update)
 6 * @version v1.7.0
 7 * @ingroup GUIDELINES
 8 * @prefix  NONE
 9 *
10 * @brief   Example code to show the application of the C coding guidelines
11 * @details This code implements an example for C:004
12 */

2.2.5. Include guard (C:005)

An include guard is a construct used in C to avoid the problem of multiple inclusion when dealing with the include directive.

Include guard rules

  • All header files MUST implement include guards to prevent multiple inclusions.

  • The include guard MUST come right after the file level doxygen comment.

  • The format of the include guard MUST consist of the prefix FOXBMS__, followed by the file name in uppercase and then followed by _H_.

  • There MUST NOT be a blank line between #ifndef and #define.

  • There MUST be a blank line after #define.

Listing 2.4 shows how this looks for a file c-005.h, where the include guard would be FOXBMS__C_005_H_.

Listing 2.4 Include guard for c-005.h
1#ifndef FOXBMS__C_005_H_
2#define FOXBMS__C_005_H_
3#endif /* FOXBMS__C_005_H_ */

2.2.6. C Sections (C:006)

C sections

Every .c and .h file MUST contain all specific section comments in the correct order. There are different section comments for sources and headers for source files (files in src/**) and test files (files in tests/unit/**).

Listing 2.5 shows how this looks for a file c-006-source.h.

Listing 2.5 section markers for c-006-source.h
1/*========== Includes =======================================================*/
2
3/*========== Macros and Definitions =========================================*/
4
5/*========== Extern Constant and Variable Declarations ======================*/
6
7/*========== Extern Function Prototypes =====================================*/
8
9/*========== Externalized Static Functions Prototypes (Unit Test) ===========*/

Listing 2.6 shows how this looks for a file c-006-source.c.

Listing 2.6 section markers for c-006-source.c
 1/*========== Includes =======================================================*/
 2
 3/*========== Macros and Definitions =========================================*/
 4
 5/*========== Static Constant and Variable Definitions =======================*/
 6
 7/*========== Extern Constant and Variable Definitions =======================*/
 8
 9/*========== Static Function Prototypes =====================================*/
10
11/*========== Static Function Implementations ================================*/
12
13/*========== Extern Function Implementations ================================*/
14
15/*========== Externalized Static Function Implementations (Unit Test) =======*/

Listing 2.7 shows how this looks for a file ./test/c-006-test.h.

Listing 2.7 section markers for ./test/c-006-test.h
1/*========== Includes =======================================================*/
2
3/*========== Unit Testing Framework Directives ==============================*/
4
5/*========== Macros and Definitions =========================================*/

Listing 2.8 shows how this looks for a file ./test/c-006-test.c.

Listing 2.8 section markers for ./test/c-006-test.c
1/*========== Includes =======================================================*/
2
3/*========== Unit Testing Framework Directives ==============================*/
4
5/*========== Definitions and Implementations for Unit Test ==================*/
6
7/*========== Setup and Teardown =============================================*/
8
9/*========== Test Cases =====================================================*/

2.2.7. Includes (C:007)

Includes are used to insert the contents of a second file into the original file. There are two scenarios to be considered for file includes. They distinguish if the software module provides configuration files or not.

Include rules

  • All includes MUST be listed after the includes marker.

  • foxBMS 2 uses the include-what-you-use paradigm.

  • Only required includes MUST be added.

  • Forward declarations MUST NOT be used. Instead, you MUST #include all the headers that declare functions, types etc. you need.

  • Configuration header files MUST apply the following order of includes:

    1. Include general.h, if needed

    2. A blank line

    3. Add required includes in alphabetical order according to rule

  • Other header files MUST apply the following order of includes:

    1. Include general.h, if needed

    2. Include corresponding configuration header if it exists

    3. A blank line

    4. Add required includes in alphabetical order according to rule

  • Source files MUST apply the following order or includes:

    1. Include corresponding header file

    2. A blank line

    3. Add required includes in alphabetical order according to rule

  • The rule for sorting required includes is (omit block if empty):

    1. unity.h (for unit tests only)

    2. A blank line

    3. Generated Mock-header (for unit tests only)

    4. A blank line

    5. Any *_cfg.h that is included

    6. A blank line

    7. HAL-headers starting with HL_-header files and ending with ti_-header files

    8. A blank line

    9. FreeRTOS headers starting with FreeRTOS.h

    10. A blank line

    11. All other required headers except Mocks

Listing 2.9, Listing 2.10, Listing 2.11 and Listing 2.12 show how includes MUST be added.

Listing 2.9 Include order for c-007_abc_cfg.h
1#include "required_additional_header.h"
2#include "required_additional_header2.h"
Listing 2.10 Include order for c-007_abc_cfg.c
1#include "c-007_abc_cfg.h"
2
3#include "some_other_required_header.h"
4#include "some_other_required_header2.h"
Listing 2.11 Include order for c-007_abc.h
1#include "c-007_abc_cfg.h"
2
3#include "required_different_header.h"
4#include "required_very_different_header.h"
Listing 2.12 Include order for c-007_abc.c
1#include "c-007_abc.h"
2
3#include "FreeRTOS.h"
4#include "queue.h"
5
6#include "first_used_header_1.h"
7#include "second_used_header.h"
8#include "xyz.h"

2.2.8. Scoping (C:008)

Scope rules

  • All functions, variables, typedefs, macros etc. MUST be declared in the narrowest scope possible (function, file, global).

    • If a function, macro, typedef or variable is used by multiple files/modules, declare it public.

    • If a function, macro, typedef or variable is only used within a file, declare it static.

    • If a variable is only used within a function, declare it inside the function.

Listing 2.13 Narrowest variable scope
 1/*========== Static Constant and Variable Definitions =======================*/
 2static uint32_t abc_staticVariable = 0; /*!< File static variable that is used within multiple functions */
 3
 4/*========== Extern Constant and Variable Definitions =======================*/
 5uint32_t abc_globalVariable; /*!< Important global variable that is used by multiple files/modules */
 6
 7/*========== Static Function Prototypes =====================================*/
 8/** @brief   Function to do important stuff in this file/module. */
 9static void ABC_StaticImportantFunction(void);
10
11/*========== Static Function Implementations ================================*/
12static void ABC_StaticImportantFunction(void) {
13    uint32_t temporaryVariable = 0; /* Temporary variable to do calculations in this function */
14}
15
16/*========== Extern Function Implementations ================================*/
17extern void ABC_GlobalImportantFunction(void) { /* some code */
18}

2.2.9. Function names (C:009)

Function naming rules

  • Function names MUST start with the uppercase module prefix followed by a capital letter with capital letters for each new word (Pascal Case).

  • The only exception are the unit-test-functions which start with test due to ceedling requiring it.

  • Function names SHOULD start with a verb followed by a noun (verb-noun pattern). After the verb-noun pattern additional words MAY follow.

Listing 2.14, shows correctly named functions.

Listing 2.14 Function names using the uppercase module prefix.
1static void ABC_ImportantFunction(void);
2static void ABC_EvenMoreImportantFunction(void);
3static void ABC_ImportantFunction(void) {
4}
5static void ABC_EvenMoreImportantFunction(void) {
6}

2.2.10. Function scopes (C:010)

Function scope rules

  • Global and static functions MUST be declared respectively with the keywords extern or static. This keyword MUST be used for the function prototype declaration and the function definition.

  • Global function prototypes MUST be declared in the header file.

  • Static function prototypes MUST be declared in the source file.

Listing 2.15 and Listing 2.16 show correctly declared and implemented functions on the header abc.h and respective source file abc.c.

2.2.11. Function doxygen documentation (C:011)

Function scope rules

  • The doxygen documentation describing each function MUST be placed above the prototype declaration.

  • All function prototype declarations and function implementations MUST be placed in the correct sections in the source/header files.

  • The following doxygen parameters MUST be documented for every function: @brief and @details.

  • Doxygen parameter @return MUST be documented if the return type is not of type void.

  • Function arguments MUST be documented using the doxygen parameter @param.

  • If a function argument is a pointer, the data flow direction (indicating if the pointer is used as input, output or both) MUST be indicated with a suffixed [in], [out] or [in,out] after the @param tag.

  • This practice MUST NOT be applied to normal parameters that are passed by value as they are implicitly assumed to be input.

  • All doxygen parameter arguments MUST be whitespace aligned.

Listing 2.15 and Listing 2.16 show doxygen documented functions in a header file c-011.h and source file c-011.c.

Listing 2.15 Global function declaration in c-011.h and its doxygen comment
1/**
2 * @brief   Does this and that
3 * @details Detailed description of this function
4 * @param[out]  pPointer    important function writes to this pointer
5 * @param       length      length that should be written to the pointer
6 * @return  some uint8_t which describes xyz
7 */
8extern uint8_t ABC_ImportantFunction(uint8_t *pPointer, uint8_t length);
Listing 2.16 Static and global functions in c-011.c ant their doxygen comments
 1/**
 2 * @brief   Does something
 3 * @details Detailed description of this function
 4 * @return  some uint8_t which describes xyz
 5 */
 6static uint8_t ABC_AnotherFunction(void);
 7
 8/*========== Static Function Implementations ================================*/
 9static uint8_t ABC_AnotherFunction(void) {
10    /* some code */
11    return 0;
12}
13
14/*========== Extern Function Implementations ================================*/
15extern uint8_t ABC_ImportantFunction(uint8_t *pPointer, uint8_t length) {
16    /* some code */
17    return 0;
18}

2.2.12. Function return statement (C:012)

Return statement rules

Parentheses surrounding the return expression SHOULD NOT be used. Use parentheses in return expressions only in places where you would use them in normal assignments.

Listing 2.17 shows how to correctly use parentheses and the return statement.

Listing 2.17 Correct usage of the return statement.
 1static uint8_t ABC_ReturnAbc(void) {
 2    uint8_t result = 0;
 3    return result; /* No parentheses in the simple case. */
 4}
 5static uint8_t ABC_ReturnDef(uint8_t another_condition, uint8_t some_long_condition) {
 6    uint8_t result = 0;
 7    /* Parentheses ok to make a complex expression more readable. */
 8    /* clang-format off */
 9    return (some_long_condition &&
10            another_condition);
11    /* clang-format on */
12}

2.2.13. Function calls (C:013)

Function call rules

  • Multiple arguments SHOULD be put on a single line to reduce the number of lines necessary for calling a function unless there is a specific readability problem. Some style guides require formatting strictly one argument on each line for simplifying editing the arguments. However, we prioritize readability over the ease of editing arguments, and most readability problems are better addressed with the following techniques.

  • If the arguments do not all fit on one line, they MAY be broken up onto multiple lines, with each subsequent line aligned with the first argument.

  • Arguments MAY also be placed on subsequent lines with an eight space indent.

  • If having multiple arguments in a single line decreases readability due to the complexity or confusing nature of the expressions that make up some arguments, it is RECOMMENDED to

    • create variables that capture those arguments in a descriptive name,

    • put the confusing argument on its own line with an explanatory comment.

    • If there is still a case where one argument is significantly more readable on its own line, then put it on its own line. The decision should be specific to the argument which is made more readable rather than a general policy.

    • Sometimes arguments form a structure that is important for readability. In those cases, it is RECOMMENDED to format the arguments according to that structure

Different correct ways to call functions with multiple parameters or long function names are given in Listing 2.18.

Listing 2.18 Correct formatting of function calls.
 1/* clang-format off */
 2static void ABC_TransformMyWidget(
 3    uint8_t x1, uint8_t x2, uint8_t x3,
 4    uint8_t y1, uint8_t y2, uint8_t y3,
 5    uint8_t z1, uint8_t z2, uint8_t z3);
 6/* clang-format on */
 7/* clang-format off */
 8static void ABC_TransformMyWidget(
 9    uint8_t x1, uint8_t x2, uint8_t x3,
10    uint8_t y1, uint8_t y2, uint8_t y3,
11    uint8_t z1, uint8_t z2, uint8_t z3) {
12}
13/* clang-format on */
14static int16_t ABC_DoSomething(int16_t var, int16_t x, int16_t y, int16_t z) {
15    return 0;
16}
17int16_t ABC_SomeFunction(uint8_t x, uint8_t y, uint8_t z) {
18    /* use variable to capture value, before passing to function */
19    int16_t myHeuristic = scores[x] * y + bases[x];
20    int16_t result      = ABC_DoSomething(myHeuristic, x, y, z);
21
22    /* place confusing argument on own commented line and all other parameters
23       also on an own line */
24    result += ABC_DoSomething(
25        scores[x] * y + bases[x], /* Score heuristic. */
26        x,
27        y,
28        z);
29
30    /* Its a matrix, and therefore it makes sense to format the arguments as a matrix */
31    /* clang-format off */
32    ABC_TransformMyWidget(x1, x2, x3,
33                          y1, y2, y3,
34                          z1, z2, z3);
35    /* clang-format on */
36    return result;
37}

2.2.14. Additional function rules (C:014)

Most of the following rules are checked by the clang-format configuration of the project. If a rule is not checked automatically it is indicated.

Additional Function rules

  • The open parenthesis MUST be on the same line as the function name.

  • There MUST NOT be a space between the function name and the open parenthesis.

  • There MUST NOT be a space between the parentheses and the parameters.

  • The open curly brace MUST be on the end of the last line of the function declaration, not the start of the next line.

  • The close curly brace MUST be either on the last line by itself or on the same line as the open curly brace.

  • There MUST be a space between the close parenthesis and the open curly brace.

  • Spaces after the open or before the close parenthesis MUST NOT be added.

  • All parameters SHOULD be aligned if possible.

  • If you cannot fit the return type and the function name on a single line, you MUST break between them.

  • If you break after the return type of a function declaration or definition, you MUST not indent.

  • You SHOULD use describing parameter names. (Not checked by clang-format)

2.2.15. Function parameter checking (C:015)

Function parameter checking

  • Input values of function parameters SHOULD be checked at the beginning of a function if possible.

  • Pointers passed as parameters MUST be checked against NULL_PTR.

  • The check SHOULD be implemented with an assertion.

  • If no assertion can be made for the parameter (e.g., if the parameter intentionally accepts all possible values), the parameter MUST be marked like this at the start of the function context: /* AXIVION Routine Generic-MissingParameterAssert: *ENTITY_NAME*: *RATIONALE* */.

Parameter checking is shown in Listing 2.19.

Listing 2.19 Input check of function parameters
 1extern uint32_t ABC_ArrayAverage(uint8_t *pArray, uint8_t arrayLength, uint8_t additionalParameter) {
 2    FAS_ASSERT(pArray != NULL_PTR);
 3    FAS_ASSERT(arrayLength > 0u);
 4    /* AXIVION Routine Generic-MissingParameterAssert: additionalParameter: This parameter is unused in this example */
 5
 6    /* unused parameter just for the example */
 7    (void)additionalParameter;
 8
 9    uint32_t sum = 0u;
10
11    for (uint16_t i = 0u; i < arrayLength; i++) {
12        sum += pArray[i];
13    }
14    sum /= arrayLength;
15    return sum;
16}

2.2.16. Variable names (C:016)

Variable naming rules

  • Global and static variables MUST be commented with a doxygen style comment.

  • Variable names (including function parameters) MUST start with a lowercase letter and are written in “camel Case”.

  • If the scope of the variable is at least file wide (more than function scope) or if the variable is declared static it MUST start with the module prefix in lowercase letters. A variable representing a physical unit is followed by a suffix with the SI-unit symbol _<unit> (e.g., _mA for milliampere or K for Kelvin). Exceptions are non-ASCII symbols as

    • _perc for %,

    • _degC for °C and

    • u for μ.

  • A doxygen comment explaining what this variable is used for MUST be added to all static and global variables.

Listing 2.20 Different examples for correctly named variables and functions.
1static uint32_t abc_staticVariable = 0u; /*!< Static variable -> prefix + doxygen comment */
2static int32_t abc_packSoc_perc    = 0;  /*!< Static variable representing physical unit -> prefix + suffix + doxygen */
3extern uint32_t abc_globalVariable; /*!< Global variable -> prefix + doxygen comment */
4    uint8_t maxValue                    = 32u; /* Temporary variable to do calculations in this function */
5    uint32_t maximumTemporaryVoltage_mV = 0u;  /* Variable representing physical unit -> suffix */
6    for (uint8_t counter = 0u; counter < maxValue; counter++) {

2.2.17. Constant names (C:017)

Constant rules

  • Constant variables MUST be commented with a doxygen style comment.

  • Constant variables MUST be named with a module prefix and a leading k followed by camel case.

  • Underscores MAY be used as separators in rare cases where capitalization cannot be used for separation.

Listing 2.21 Correct examples for naming constant variables.
1const static uint16_t abc_kDaysInAWeek = 7; /*!< Number of days in a week */

2.2.18. Pointer rules (C:018)

Pointer rules

  • The general variable name rules apply (see Variable names (C:016)).

  • Variables used for pointers MUST be prefixed with a leading p in the case of a pointer to a variable and fp in the case of a function pointer, followed by camel Case.

  • The const rules also still apply to pointers (Constant names (C:017)), i.e.,

    • for a const pointer the prefix is kp,

    • for a pointer to a const the prefix is pk, and

    • for a const pointer to a const the prefix is kpk.

  • When declaring a pointer variable or argument, the asterisk MUST be placed adjacent to the variable name.

  • As function-pointer syntax can get complicated and lead to errors, a function pointer MUST use a typedef. The typedef of a function has to use the suffix _f.

  • Spaces around . or -> MUST NOT be used when accessing pointers. The following listing contains examples of correctly-formatted pointer and reference expressions:

Listing 2.22 Correct usage of pointers.
 1typedef struct {
 2    uint32_t value;
 3} ABC_INIT_STRUCT_s;
 4
 5typedef uint8_t ABC_SOME_FUNCTION_TYPE_f(void); /* typedef of a function type */
 6static uint32_t *abc_pMyPointer         = NULL_PTR; /* static uint32_t pointer */
 7static ABC_INIT_STRUCT_s abc_initStruct = {0};      /* static init struct */
 8static uint32_t abc_myVariable          = 0;        /* local uint32_t variable */
 9ABC_INIT_STRUCT_s *abc_pInitStruct = NULL_PTR; /* local pointer to some init struct */
10ABC_SOME_FUNCTION_TYPE_f *abc_fpMyFunction;    /* local function pointer using a typedef */
11static void ABC_AssignSomeValue(void) {
12    abc_pMyPointer = &abc_myVariable;
13    abc_myVariable = *abc_pMyPointer;
14    abc_myVariable = abc_initStruct.value;
15    abc_myVariable = abc_pInitStruct->value;
16}

2.2.19. Variable initialization (C:019)

Variable initialization rules

  • All variables SHOULD be initialized at the point of their definition. If this is not done it MUST be commented why it is not done.

  • All variables MUST be initialized with the correct type.

  • Only one variable MUST be initialized or declared per line.

  • No multi-definitions MUST be used.

  • For the initialization, the correct suffixes for unsigned, signed and floating-point types MUST be used. See Table 2.13 for details.

  • Pointers MUST be initialized with NULL_PTR if no other valid initialization is possible.

Table 2.13 Variable initialization suffixes

Type

Suffix

uint8_t

u

uint16_t

u

uint32_t

u

uint64_t

uLL

int8_t

none

int16_t

none

int32_t

none

int64_t

LL

Listing 2.23 Initialization examples for variables and complex types
 1/* Initialization example for structs */
 2typedef struct {
 3    float x;
 4    float y;
 5    float z;
 6} ABC_POINT_s;
 7
 8typedef struct {
 9    ABC_POINT_s point;
10    uint32_t timestamp;
11    uint32_t previousTimestamp;
12    uint8_t name[16];
13} ABC_PATH_s;
14uint8_t abc_myVar0  = 10u;
15uint16_t abc_myVar1 = 10u;
16uint32_t abc_myVar2 = 10u;
17uint64_t abc_myVar3 = 10uLL;
18int8_t abc_myVar4   = -10;
19int16_t abc_myVar5  = -10;
20int32_t abc_myVar6  = -10;
21int64_t abc_myVar7  = -10LL;
22
23/* Initialization example for arrays */
24uint8_t abc_myArrayA[]  = {1, 2, 3}; /* Array has type uint8_t[3] and holds 1,2,3 */
25uint8_t abc_myArrayC[5] = {0};       /* Array has type uint8_t[5] and holds 0,0,0,0,0 */
26
27uint8_t abc_myArrayD[4][3] = {
28    /* array of 4 arrays of 3 uint8_t each (4x3 matrix) */
29    {1},       /* row 0 initialized to {1, 0, 0} */
30    {0, 1},    /* row 1 initialized to {0, 1, 0} */
31    {[2] = 1}, /* row 2 initialized to {0, 0, 1} */
32}; /* row 3 initialized to {0, 0, 0} */
33
34ABC_POINT_s abc_myPoint = {1.2, 1.3}; /* p.x=1.2, p.y=1.3, p.z=0.0 */
35
36ABC_PATH_s abc_myPath = {80.0f, 127.0f, -37.0f, 0, 1, "test"}; /* 80.0f initializes myPath.point.x  */
37                                                               /* 127.0f initializes myPath.point.y */
38                                                               /* -37.0f initializes myPath.point.z */
39                                                               /* 0 initializes myPath.timestamp    */
40                                                               /* 1 initializes ex.in_u.a8[3]       */
41                                                               /* "test" initializes name[0-3]      */
42                                                               /* name[4-15] are set to 0           */

2.2.20. Hexadecimal values (C:020)

Hexadecimal values rules

Hexadecimal digits MUST be written in uppercase letters.

Listing 2.24 Correct usage of hexadecimal digits.
1uint8_t abc_myVar     = 0xFFu;
2int8_t abc_myOtherVar = 0xAA;

2.2.21. Floating-point values (C:021)

Floating-point values rules

  • Floating-point literals MUST always have a radix point, with digits on BOTH sides, even if they use exponential notation. Readability is improved if all floating-point literals take this familiar form, as this helps ensure that they are not mistaken for integer literals, and that the E/e of the exponential notation is not mistaken for a hexadecimal digit.

  • float types SHOULD be used wherever possible as the float operations are performed in hardware while double operations are not.

Table 2.14 Floating-point literal initialization suffixes

Type

Suffix

float_t

f

double

none

Listing 2.25 Usage of floating-point literals.
1static const float kEuler          = 2.71828f;
2static const double kPi            = 3.141592;
3static double abc_number           = 1248.0e6;
4static long double abc_largeNumber = -0.5L;

2.2.22. Structs (C:022)

Struct rules

  • Structs MUST be commented with a doxygen style comment.

  • Struct members MUST be commented with a doxygen style comment.

  • Structs MUST be declared as typedefs.

  • Struct names MUST be all uppercase with underscores (_) between each word starting with the module prefix and ending with the suffix _s.

  • Struct members MUST be named as ordinary variables.

  • Anonymous structs MUST NOT be used, instead the struct type without the suffix _s MUST be defined.

  • A trailing comma MUST be used after the last member.

  • A doxygen comment describing each struct MUST be added above the definition.

  • A doxygen comment describing each struct member MUST be added after the member.

Example:

Listing 2.26 Correct struct implementation.
1/** Symbolic names for battery system state */
2typedef struct {
3    uint16_t year; /*!< year */
4    uint8_t month; /*!< month (1: January ... 12: December) */
5    uint8_t day;   /*!< day of the month */
6} ABC_DATE_s;

2.2.23. Enums (C:023)

Enum rules

  • Enums MUST be commented with a doxygen style comment.

  • Enum members MUST be commented with a doxygen style comment.

  • Enums MUST be declared as typedefs.

  • Enums MUST be named all uppercase with underscores (_) between each word starting with the module prefix and ending with suffix _e.

  • Anonymous enums MUST NOT be used, instead the enum type without the suffix _e MUST be defined.

  • Values MUST NOT be assigned to specific enum members.

  • Members MUST be named all in uppercase beginning with the module prefix.

  • No trailing comma MUST be used after the last entry.

  • The last member MUST be named after the typedef struct replacing the _e with _E and appending the suffix _MAX.

  • A doxygen comment describing each enum MUST be added above the definition.

  • A doxygen comment describing each enum member MUST be added after the member.

Listing 2.27 Correct enum implementation.
1/** Symbolic names for weekdays */
2typedef enum {
3    ABC_MONDAY,    /**< First day of the week */
4    ABC_TUESDAY,   /**< Second day of the week */
5    /* ... */      /* more members */
6    ABC_SUNDAY,    /**< Last day of the week */
7    ABC_DAYS_E_MAX /**< Max marker */
8} ABC_DAYS_e;

2.2.24. Typedefs (C:024)

Typedef general rules

  • Typedef names MUST be all uppercase with underscores (_) between each word.

  • Other typedef names MUST end with the suffix _t.

Listing 2.28 Correct example for usage of typedefs.
1/* Remapping of types */
2}

2.2.25. Macros (C:025)

Macro rules

  • Macro names MUST be capitalized with underscores.

  • Macros MUST start with the module prefix.

  • If macros define a physical value, the name MUST be suffixed with the SI-unit or a SI-derived unit, e.g., use F for a capacity instead of SI units s4_A2__m2_kg_1.

  • If macros are used to define a value, this value MUST be put in parentheses.

  • It is NOT RECOMMENDED to use function-like macros.

Listing 2.29 Correct naming examples of macros.
1#define ABC_PI_ROUNDED               (3.14f)
2#define ABC_NUMBER_OF_DAYS_IN_A_WEEK (7u)
3#define ABC_MAXIMUM_PACK_VOLTAGE_mV  (320000u)

2.2.26. Conditionals (C:026)

Conditionals rules

  • No spaces MUST be used between the parentheses and the condition statement.

  • The if and else keywords MUST be placed in separate lines.

  • A space between the if keyword and the open parenthesis and between the close parenthesis and the curly bracket MUST be placed.

  • Multiple statements in one condition MUST be placed into separate parentheses. If you have a boolean expression that is longer than the standard line length, the logical operator MUST be at the end of the lines.

Listing 2.30 Correct implementation of if-else statements.
 1/* some static variables that are set in some functions of this module */
 2static uint8_t abc_condition        = 0u;
 3static uint8_t abc_other_condition  = 0u;
 4static uint8_t abc_this_one_thing   = 0u;
 5static uint8_t abc_this_other_thing = 0u;
 6static uint8_t abc_a_third_thing    = 0u;
 7static uint8_t abc_a_fourth_thing   = 0u;
 8static uint8_t abc_yet_another      = 0u;
 9static uint8_t abc_last_one         = 0u;
10extern void ABC_ConditionalFunction(void) {
11    if (abc_condition) {              /* no spaces inside parentheses */
12        /* code */                    /* 4 space indent. */
13    } else if (abc_other_condition) { /* The else if goes on the same line as the closing brace. */
14        /* code */                    /* 4 space indent. */
15    } else {                          /* The else if goes on the same line as the closing brace. */
16        /* code */                    /* 4 space indent. */
17    }
18    if ((abc_this_one_thing > abc_this_other_thing) && (abc_a_third_thing == abc_a_fourth_thing) &&
19        (abc_yet_another && abc_last_one)) {
20        /* code */
21    }
22}

2.2.27. switch Statements (C:027)

Switch statement rules

  • Switch statements MUST use parentheses for blocks.

  • Fall-throughs between cases SHOULD NOT be used but instead all cases are terminated with one single break-statement at the end of the case. The only exceptions for this rules are empty fall-throughs that MUST be treated within the next case. These deliberate fall-throughs MUST be annotated.

  • Case blocks in switch statements MUST NOT use brackets.

  • Furthermore, switch statements MUST have a default case.

  • If the default case should never be executed, this MUST be treated as an error.

  • There MUST be an empty line between break and the next case directive.

Listing 2.31 Correct implementation of switch-case statement.
 1extern void ABC_SwitchFunction(uint8_t var) {
 2    switch (var) {
 3        case 0:        /* 4 space indent */
 4            /* code */ /* 4 space indent */
 5            break;
 6
 7        case 1:
 8            /* code */ /* 4 space indent */
 9            break;
10
11        case 2:
12            /* code */ /* 4 space indent */
13            break;
14
15        case 3: /* Empty fall-through allowed as case 3 and 4 require the same treatment */
16        case 4:
17            /* case 3 and case 4 trigger the same response */
18            /* code */
19            break;
20
21        default:                  /* LCOV_EXCL_LINE */
22            FAS_ASSERT(FAS_TRAP); /* LCOV_EXCL_LINE */
23            break;                /* LCOV_EXCL_LINE */
24    }
25}

2.2.28. loop Statements (C:028)

loop rules

  • Parentheses MUST be used for all loops, at all times. This is valid for single-statement loops.

  • Empty loop bodies MUST use an empty pair of brackets and explain why they are empty.

Listing 2.32 Correct usage of spaces and parentheses in loop statements.
 1static void ABC_ForLoop(uint8_t kSomeNumber) {
 2    for (uint8_t i = 0u; i < kSomeNumber; ++i) {
 3        /* code */
 4    }
 5}
 6
 7static void ABC_While(uint8_t condition) {
 8    while (condition) {
 9        /* This should never happen, since ... */
10    }
11}

There are three defines that are typically looped over: the number of strings (BS_NR_OF_STRINGS), the number of modules (BS_NR_OF_MODULES_PER_STRING) and the number of batteries per module (BS_NR_OF_CELL_BLOCKS_PER_MODULE).

These loops MUST follow the pattern as shown in Table 2.15 and Listing 2.33.

Table 2.15 Special counter variables in for loops

Define

Counter variable

BS_NR_OF_STRINGS

s

BS_NR_OF_MODULES_PER_STRING

m

BS_NR_OF_CELL_BLOCKS_PER_MODULE

cb

BS_NR_OF_TEMP_SENSORS_PER_MODULE

ts

Listing 2.33 Looping over BS_NR_OF_STRINGS, BS_NR_OF_MODULES_PER_STRING and BS_NR_OF_CELL_BLOCKS_PER_MODULE
 1/**
 2 * @file    c-028-battery-defines.c
 3 * @author  foxBMS Team
 4 * @date    2021-06-04 (date of creation)
 5 * @updated 2024-08-08 (date of last update)
 6 * @version v1.7.0
 7 * @ingroup GUIDELINES
 8 * @prefix  ABC
 9 *
10 * @brief   Example code to show the application of the C coding guidelines
11 * @details This code implements an example for C:028
12 */
13
14/*========== Includes =======================================================*/
15
16#include "battery_system_cfg.h"
17
18#include <stdint.h>
19
20/*========== Macros and Definitions =========================================*/
21
22/*========== Static Constant and Variable Definitions =======================*/
23
24/*========== Extern Constant and Variable Definitions =======================*/
25
26/*========== Static Function Prototypes =====================================*/
27
28static void C28_BatteriesLoop(void);
29
30/*========== Static Function Implementations ================================*/
31static void C28_BatteriesLoop(void) {
32    for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
33        /* string related code */
34        for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
35            /* module related code */
36            for (uint8_t cb = 0u; cb < BS_NR_OF_CELL_BLOCKS_PER_MODULE; cb++) {
37                /* cell related code */
38            }
39        }
40    }
41}
42
43/*========== Extern Function Implementations ================================*/
44
45/*========== Externalized Static Function Implementations (Unit Test) =======*/
46#ifdef UNITY_UNIT_TEST
47#endif

2.2.29. C Comment style (C:029)

Comment Style

  • Only ANSI-C comments MUST be used (/* */).

  • Comments MUST NOT be nested.

2.2.30. General note and common mistakes (C:030)

For both, camel Case and Pascal Case, the general rules of the English language apply. This means that the correct version for a variable about the cell voltage is abc_cellVoltage (not abc_cellvoltage).

2.2.31. C Formatting (C:031)

Formatting

  • All code MUST be formatted according to the rules in this guidelines document.

  • Formatting SHOULD be done automatically by a tool.

2.2.32. State machines (C:032)

If a driver (or similar) requires to be implemented in a state machine there are some hints found in How to Write State Machines.

2.2.33. Unit Testing Framework Directives (C:033)

If a driver (or similar) requires to be implemented in a state machine there are some hints found in How to Write State Machines.

2.2.34. File Templates

These file templates below show how these rules are correctly applied. They SHOULD be used as basis for new files.

2.2.34.1. C Header Files

Listing 2.34 File template for C header files
 1/**
 2 *
 3 * @copyright &copy; 2010 - 2024, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
 4 * All rights reserved.
 5 *
 6 * SPDX-License-Identifier: BSD-3-Clause
 7 *
 8 * Redistribution and use in source and binary forms, with or without
 9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice, this
12 *    list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 *    contributors may be used to endorse or promote products derived from
20 *    this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * We kindly request you to use one or more of the following phrases to refer to
34 * foxBMS in your hardware, software, documentation or advertising materials:
35 *
36 * - "This product uses parts of foxBMS&reg;"
37 * - "This product includes parts of foxBMS&reg;"
38 * - "This product is derived from foxBMS&reg;"
39 *
40 */
41
42/**
43 * @file    c.h
44 * @author  foxBMS Team
45 * @date    2019-08-27 (date of creation)
46 * @updated 2024-08-08 (date of last update)
47 * @version v1.7.0
48 * @ingroup SOME_GROUP
49 * @prefix  ABC
50 *
51 * @brief   Header file of some software
52 * @details Some detailed explanation
53 */
54
55#ifndef FOXBMS__C_H_
56#define FOXBMS__C_H_
57
58/*========== Includes =======================================================*/
59
60/*========== Macros and Definitions =========================================*/
61
62/*========== Extern Constant and Variable Declarations ======================*/
63
64/*========== Extern Function Prototypes =====================================*/
65
66/*========== Externalized Static Functions Prototypes (Unit Test) ===========*/
67#ifdef UNITY_UNIT_TEST
68#endif
69
70#endif /* FOXBMS__C_H_ */

2.2.34.2. C Source Files

Listing 2.35 File template for C source files
 1/**
 2 *
 3 * @copyright &copy; 2010 - 2024, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
 4 * All rights reserved.
 5 *
 6 * SPDX-License-Identifier: BSD-3-Clause
 7 *
 8 * Redistribution and use in source and binary forms, with or without
 9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice, this
12 *    list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 *    contributors may be used to endorse or promote products derived from
20 *    this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * We kindly request you to use one or more of the following phrases to refer to
34 * foxBMS in your hardware, software, documentation or advertising materials:
35 *
36 * - "This product uses parts of foxBMS&reg;"
37 * - "This product includes parts of foxBMS&reg;"
38 * - "This product is derived from foxBMS&reg;"
39 *
40 */
41
42/**
43 * @file    c.c
44 * @author  foxBMS Team
45 * @date    2019-08-27 (date of creation)
46 * @updated 2024-08-08 (date of last update)
47 * @version v1.7.0
48 * @ingroup SOME_GROUP
49 * @prefix  ABC
50 *
51 * @brief   Implementation of some software
52 * @details Some detailed explanation
53 */
54
55/*========== Includes =======================================================*/
56#include "c.h"
57
58/*========== Macros and Definitions =========================================*/
59
60/*========== Static Constant and Variable Definitions =======================*/
61
62/*========== Extern Constant and Variable Definitions =======================*/
63
64/*========== Static Function Prototypes =====================================*/
65
66/*========== Static Function Implementations ================================*/
67
68/*========== Extern Function Implementations ================================*/
69
70/*========== Externalized Static Function Implementations (Unit Test) =======*/
71#ifdef UNITY_UNIT_TEST
72#endif

2.2.34.3. C Test Header Files

Listing 2.36 File template for C test header files
 1/**
 2 *
 3 * @copyright &copy; 2010 - 2024, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
 4 * All rights reserved.
 5 *
 6 * SPDX-License-Identifier: BSD-3-Clause
 7 *
 8 * Redistribution and use in source and binary forms, with or without
 9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice, this
12 *    list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 *    contributors may be used to endorse or promote products derived from
20 *    this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * We kindly request you to use one or more of the following phrases to refer to
34 * foxBMS in your hardware, software, documentation or advertising materials:
35 *
36 * - "This product uses parts of foxBMS&reg;"
37 * - "This product includes parts of foxBMS&reg;"
38 * - "This product is derived from foxBMS&reg;"
39 *
40 */
41
42/**
43 * @file    test_c.h
44 * @author  foxBMS Team
45 * @date    2020-08-10 (date of creation)
46 * @updated 2024-08-08 (date of last update)
47 * @version v1.7.0
48 * @ingroup UNIT_TEST_IMPLEMENTATION
49 * @prefix  TEST
50 *
51 * @brief   Test header of the some module
52 * @details TODO
53 */
54
55#ifndef FOXBMS__TEST_C_H_
56#define FOXBMS__TEST_C_H_
57
58/*========== Includes =======================================================*/
59
60/*========== Unit Testing Framework Directives ==============================*/
61
62/*========== Macros and Definitions =========================================*/
63
64#endif /* FOXBMS__TEST_C_H_ */

2.2.34.4. C Test Source Files

Listing 2.37 File template for C test source files
 1/**
 2 *
 3 * @copyright &copy; 2010 - 2024, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
 4 * All rights reserved.
 5 *
 6 * SPDX-License-Identifier: BSD-3-Clause
 7 *
 8 * Redistribution and use in source and binary forms, with or without
 9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice, this
12 *    list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *
18 * 3. Neither the name of the copyright holder nor the names of its
19 *    contributors may be used to endorse or promote products derived from
20 *    this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * We kindly request you to use one or more of the following phrases to refer to
34 * foxBMS in your hardware, software, documentation or advertising materials:
35 *
36 * - "This product uses parts of foxBMS&reg;"
37 * - "This product includes parts of foxBMS&reg;"
38 * - "This product is derived from foxBMS&reg;"
39 *
40 */
41
42/**
43 * @file    test_c.c
44 * @author  foxBMS Team
45 * @date    2020-08-10 (date of creation)
46 * @updated 2024-08-08 (date of last update)
47 * @version v1.7.0
48 * @ingroup UNIT_TEST_IMPLEMENTATION
49 * @prefix  TEST
50 *
51 * @brief   Test of some module
52 *
53 */
54
55/*========== Includes =======================================================*/
56#include "unity.h"
57
58/*========== Unit Testing Framework Directives ==============================*/
59TEST_SOURCE_FILE("c.c")
60
61/*========== Definitions and Implementations for Unit Test ==================*/
62
63/*========== Setup and Teardown =============================================*/
64void setUp(void) {
65}
66
67void tearDown(void) {
68}
69
70/*========== Test Cases =====================================================*/