This document is prepared to help developers about how to write the code. It contains different types of code language rules. These rules make writing, maintaining, reviewing the code easier. Also some rules increase portability, …
In most projects, we are using number of spaces instead of using the tab character(\t). Most cases 4 spaces could be use for tab key. This can be set from settings of most IDE’s.
The unary operators are written with no space between the operator and the operand.
!value
~bits
++i
j--
(CPU_INT32U)x
*ptr
&x
sizeof(x)
The binary operators (and the ternary operator) are written with at least on space between the operator and operands.
c1 = c2;
x + y
i += 2;
n > 0 ? n : -n
a < b
c >= 2
Expressions within parentheses are written with no space after the opening parenthesis and no space before the closing parenthesis.
x = (a + b) * c;
if(x < y)
{
return -1;
}
else if(x > y)
{
return 1;
}
else
{
return 0;
}
while(condition)
{
}
do
{
} while(condition);
for(int i = 0, j = argc; i < argc; i++, j--)
{
}
switch(number)
{
case RED:
return GREEN;
case GREEN:
return BLUE;
case BLUE:
return RED;
default:
return BLACK;
}
namespace examplenamespace {
class ExampleClass {
public:
ExampleClass(int arg1, char arg2, char* arg3);
~ExampleClass();
void public_func(char arg);
private:
char class_member;
void private_func(int arg);
};
}
In this section, there are some naming convention rules for C language.
These rules can be applied to:
Naming convention of functions is important because if there is a good naming for functions, it would be easy to read the code.
Public functions can be called from another files. So it is better to put some prefix before function name:
Example:
void network_stackMgmt(int code);
bool uartIO_txEnable(void);
Local functions can be called only from inside the file that the function is written. So there is no need to put a prefix before function name:
static void clearBuffer(void);
static bool getState(int index);
Naming convention of typedef structures and enumerations is important because if there is a good naming, it would be easy to read the code.
If there is a good naming for the structure definition, it would be easy to read the code.
struct s_deviceManagerRing {
uint8 link;
char mac[18];
};
If there is a good naming for the typedef structure definition, it would be easy to read the code.
typedef struct {
uint64_t mac;
char ipServer[48];
uint16_t portServer;
uint16_t portClient;
} ts_gsmNet;
İf there is a good naming for the enumeration definition, it would be easy to read the code.
enum e_deviceManagerStates {
E_DEVICE_MANAGER_INIT = 0,
E_DEVICE_MANAGER_START,
E_DEVICE_MANAGER_STOP,
};
If there is a good naming for the typedef enumeration definition, it would be easy to read the code.
typedef enum {
E_DIO_E_INPUT_1 = 0,
} te_dioInputs;
Naming convention of variables is important because if there is a good naming for variables, it would be easy to read the code.
Public variables can be used from another files. So it is important to have a prefix before the variable name like this:
char uartIO_respReady[6] = "READY";
char lon_respSet[6] = "SET\r\n";
Local variables can be used from only the file that they are written inside. So it is not important to have a prefix before the variable name.
static bool up;
static uint64_t local;
static uint8_t button;
It is better to have sections inside the file in every coding language. In this section there are some rules about file content.
File content should be separated with some comment blocks. So this way, it would be easy to find what we are looking for in the file content.
To get a documentation from the comments, Doxygen format is used for comments.
This section is prepared to give some information about doxygen comment blocks and how to write them.
Here is one example:
/**
* \brief Initializes the UART handle.
* \param config UART configuration string (ex. "COM1:115200,N,8,1")
* \return Returns a handle to the newly opened UART
*/
UART_HandleTypeDef *uartOpen(char *config)
{
...
}
Here is one example:
static uint8 mode[2]; /**< Uart mode * /
Here is one example:
/* UART configuration */
#define UARTIO_EVEN FALSE /**< Even parity */
#define UARTIO_PARITY FALSE /**< Parity enabled */
#define UARTIO_WORDLEN E_AHI_UART_WORD_LEN_8 /**< Word length */
#define UARTIO_ONESTOP TRUE /**< One stop bit */
A comment block must be placed at the beginning of each source code file (both code and header files) containing;
Here is one example comment block:
/**
* \file Filename
* \brief A brief description, one sentence, one line.
* \details A detailed description of the file scope, it can span over
* multiple lines, can be omitted.
* \remarks Additional remarks.
*/
Both source and header files must be divided by sections:
Even if the section is empty, it’s comment block must be added to the file:
/*----------------------------< Section Name >--------------------------*/
The INCLUDE FILES section should include all necessary header files.
/*------------------------------< Includes >-----------------------------*/
#include <iostream>
#include <thread>
The MACRO DEFINITIONS section should include all necessary macro defines.
/*--------------------------< Macro Definitions >-----------------------*/
#ifndef TRACE_APP
#define TRACE_APP TRUE
#endif
The LOCAL CONSTANTS section should include all necessary constant variables.
/*--------------------------< Constants >-------------------------------*/
const uint32 msecCount = 1800;
The LOCAL DATA TYPES section should include all necessary data type definitions.
/*----------------------------< Typedefs >-------------------------------*/
typedef struct
{
bool rts; /**< Current RTS setting */
bool cts; /**< Current CTS setting */
} ts_uart;
The LOCAL VARIABLES section should include all necessary local(static) variables.
/*---------------------------< Variables >------------------------------*/
static uint8 uart = APP_UART_0;
The LOCAL FUNCTION PROTOTYPES section should include all necessary local(static) function prototypes.
/*-------------------------< Prototypes >-----------------------------*/
static void delayMsec(uint32 period);
The PUBLIC FUNCTION section should include all necessary public function declarations.
/*---------------------------< Public Function >------------------------*/
void dio_outputInitialise(void)
{
...
}
The LOCAL FUNCTION section should include all necessary local(static) function declarations.
/*-------------------------< Private Function >--------------------------*/
static void initialiseApp(void)
{
...
}
Please refer to here to see abbreviations.