1Coding Rules 2============ 3 4To maintain consistency within the SCP/MCP software source code and to reduce 5the risk of bugs, a series of rules and guidelines have been created; these form 6the project's coding rules. 7 8General Considerations 9---------------------- 10The software follows the ISO/IEC 9899:2011 standard (C11). This is enforced 11through the use of compilation flags and all warnings being considered as 12errors. Compilation flags are also used to avoid constructs usually considered 13questionable, and that are easy to avoid. 14 15For robustness and reliability reasons, dynamic memory allocation is allocate- 16only and must be done through the facilities provided by the firmware framework. 17The intent is for memory allocations to be done during the pre-runtime phase or 18early in the runtime phase based on configuration data or hardware detection. 19Allocated memory cannot be freed or reallocated. 20 21Static Analysis 22--------------- 23This project uses `cppcheck` to do a static analysis of the codebase for 24possible programmer error and other sources of bugs. This analysis occurs as a 25part of the standard continuous integration flow on pull requests. If the 26analyser identifies potential issues, the patch will be automatically rejected. 27 28To invoke `cppcheck` manually, use: 29 30``` bash 31cppcheck --xml \ 32 --enable=all \ 33 --force \ 34 --suppressions-list="${WORKDIR}/tools/cppcheck_suppress_list.txt" \ 35 --includes-file="${WORKDIR}/framework/include/" \ 36 -I "${WORKDIR}/CMSIS" \ 37 -i cmsis \ 38 -U__CSMC__ \ 39 ${WORKDIR} 40``` 41 42The CMSIS submodule is not checked. Errors are printed in XML format on the 43error output. 44 45Certain checks have been manually suppressed. Checks are generally only 46disabled if they have been triaged as false positives. The list of suppressed 47checks can be found [here](../tools/cppcheck_suppress_list.txt). 48 49## Static analysis using `cmake` 50 51When this project is built using `cmake`, `cppcheck` is performed automatically 52for the current build using the list of suppressed checks mentioned in the 53previous section. 54`cppcheck` can be run standalone with the current build configuration using 55the following commands: 56 57``` bash 58cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ 59 -B ${BUILD_DIR} ... <cmake configuation extra parameters> 60 61cmake --build ${BUILD_DIR} -- -n 62 63cppcheck --xml \ 64 --enable=all \ 65 --force \ 66 --suppressions-list="${WORKDIR}/tools/cppcheck_suppress_list.txt" \ 67 --project="${BUILD_DIR}/compile_commands.json" 68``` 69 70MISRAC-2012 71----------- 72The SCP-firmware is attempting to achieve compliance with MISRAC-2012. 73 74In order to provide a reference, Juno platform is taken as a first platform to 75attempt alignment with the guidance. At the same time, a MISRAC-2012 checker 76is currently being run upon PR submissions. 77 78To date, *all* violations of the **Mandatory Rules** have been **resolved**: 79 80* Rule 9.1, 81* Rule 12.5 82* Rule 13.6 83* Rules 17.3, 17.4, 17.6, 84* Rule 19.1, 85* Rules 21.13, 21.17, 21.18, 21.19, 21.20, 86* Rules 22.2, 22.4, 22.5, 22.6 87 88Other *Required Directives* have also had *all* their violations **resolved**: 89 90* Directive 1.1 91* Directive 2.1 92* Directive 3.1 93* Directives 4.1, 4.3, 4.7, 4.11, 4.14 94 95Other *Required Rules* have also had *all* their violations **resolved**: 96 97* Rules 1.1, 1.3 98* Rule 3.2 99* Rule 4.1 100* Rules 5.2, 5.3, 5.4, 5.5, 5.6, 5.7 101* Rules 6.1, 6.2 102* Rules 7.1, 7.3, 7.4 103* Rules 8.1, 8.8, 8.10, 8.12 104* Rules 9.2, 9.4 105* Rules 10.1, 10.2, 10.3 106* Rules 11.2, 11.7, 11.9 107* Rules 13.1, 13.2, 13.5 108* Rules 14.1, 15.2, 15.3, 15.6 109* Rules 16.2, 16.5, 16.7 110* Rules 17.2, 17.7 111* Rules 18.1, 18.6 112* Rules 20.2, 20.3, 20.4, 20.6, 20.8, 20.11, 20.13, 20.14 113* Rules 21.4, 21.5, 21.7, 21.8, 21.9, 21.10, 21.11, 21.14, 21.16 114* Rules 22.3, 22.7, 22.8, 22.9, 22.10 115 116The list of *Required Rules and Directives* that are currently being 117**deviated** from can be seen below: 118 119* Directives 4.10, 4.12 120* Rule 2.1 121* Rule 3.1 122* Rules 8.2, 8.4, 8.5, 8.6, 8.14 123* Rules 10.7, 10.8 124* Rules 11.1, 11.3, 11.6, 11.8 125* Rule 12.2 126* Rules 14.2, 14.3 127* Rules 16.1, 16.3, 16.4, 16.6 128* Rules 17.1, 17.7 129* Rules 18.2, 18.3, 18.7, 18.8 130* Rule 20.12 131* Rules 21.1, 21.2, 21.3, 21.6, 21.15 132 133*Advisory rules* are currently **not considered/treated**. 134 135Please note that new patches will have to be compliant with the current status 136of resolved rules/directives. 137 138C Standard Library 139------------------ 140When developing a module, only the following headers of the C standard library 141are allowed to be included: 142`<limits.h>`, `<stdarg.h>`, `<stdbool.h>`, `<stddef.h>`, `<stdint.h>`, 143`<stdio.h>`, `<stdlib.h>`, `<string.h>` and `<inttypes.h>`. 144 145Concerning the library functions defined in `<stdio.h>`, only `snprintf()` may 146be used. 147 148Concerning the library functions defined in `<stdlib.h>`, only `bsearch()`, 149`qsort()`, `abs()` and `rand()` may be used. 150 151Concerning the library functions defined in `<string.h>`, `strcat()` and 152`strcpy()` cannot be used. Use `strncat()` and `strncpy()` instead. 153 154If not already defined by another standard library header, include `<stddef.h>` 155and not `<stdlib.h>` to define `size_t`. 156 157Additionally, the framework wraps the following standard library header files: 158`<stdalign.h>`, `<stdnoreturn.h>`, `<assert.h>` and `<errno.h>`. These header 159files must not be directly included in module code, as extended alternatives are 160provided by the framework. 161 162Header Files 163------------ 164The contents of a header file should be wrapped in an 'include guard' to prevent 165accidental multiple inclusion of a single header. The definition name should be 166the upper-case file name followed by "_H". An example for fwk_mm.h follows: 167 168```c 169#ifndef FWK_MM_H 170#define FWK_MM_H 171 172(...) 173 174#endif /* FWK_MM_H */ 175``` 176 177The closing endif statement should be followed directly by a single-line comment 178which replicates the full guard name. In long files this helps to clarify what 179is being closed. 180 181Space between definition inside the header file should be a single line only. 182 183If a unit (header or C file) requires a header, it must include that header 184instead of relying on an indirect inclusion from one of the headers it already 185includes. 186 187Types 188----- 189Import `<stdint.h>` (part of the C Standard Library) for exact-width integer 190types (`uint8_t`, `uint16_t`, etc). These types can be used wherever the width 191of an integer needs to be specified explicitly. 192 193Use `uintptr_t` to handle addresses as integers. 194 195Import `<stdbool.h>` (also part of the C Standard Library) whenever a "boolean" 196type is needed. 197 198Avoid defining custom types with the "typedef" keyword where possible. 199Structures (struct) and enumerators (enum) should be declared and used with 200their respective keyword identifiers. If custom types are used then they must 201have the suffix "_t" appended to their type name where it is defined. This makes 202it easier to recognize types that have been defined using "typedef" when they 203appear in the code. 204 205When using sizeof() pass the variable name as the parameter to be evaluated, and 206not its type. This prevents issues arising if the type of the variable changes 207but the sizeof() parameter is not updated. 208 209```c 210size_t size; 211unsigned int counter; 212 213/* Preferred over sizeof(int) */ 214size = sizeof(counter); 215``` 216 217Use the `const` type qualifier as appropriate to specify values that cannot be 218modified. Quick reminder: 219 220- `const xyz_t object`, `object` is an object of type xyz_t which value cannot 221be modified. 222- `const xyz_t *ptr` or `xyz_t const *ptr`, `ptr` is a pointer to a constant 223object of type xyz_t. The value of the object cannot be modified, the value of 224the pointer can be modified. 225- `xyz_t * const ptr`, `ptr` is a constant pointer to an object of type xyz_t. 226The value of the object can be modified, the value of the pointer cannot be 227modified. 228- `const xyz_t * const ptr` or `xyz_t const * const ptr`, `ptr` is a constant 229pointer to a constant object of type xyz_t. The value of the object and the 230pointer cannot be modified. 231 232https://cdecl.org may help if in doubt. 233 234Static storage qualifier 235------------------------ 236Declare functions and variables private to a C file as static. 237 238Operator Precedence 239------------------- 240Do not rely on the implicit precedence and associativity of C operators. Use 241parenthesis to make precedence and associativity explicit: 242 243```c 244if ((a == 'a') || (x == 'x')) { 245 do_something(); 246} 247``` 248 249Parenthesis around a unary operator and its operand may be omitted: 250 251```c 252if (!a || &a) { 253 do_something(); 254} 255``` 256 257Macros and Constants 258-------------------- 259Logical groupings of constants should be defined as enumerations, with a common 260prefix, so that they can be used as parameter types. To find out the number of 261items in an "enum", make the last entry to be \<prefix\>_COUNT. 262 263```c 264enum command_id { 265 COMMAND_ID_VERSION, 266 COMMAND_ID_PING, 267 COMMAND_ID_EXIT, 268 /* Do not add entries after this line */ 269 COMMAND_ID_COUNT 270}; 271 272void process_cmd(enum command_id id) 273{ 274 (...) 275} 276``` 277 278Prefer inline functions instead of macros. 279 280Initialization 281-------------- 282When local variables require being initialized to 0, please use their respective 283type related initializer value: 284- 0 (zero) for integers 285- 0.0 for float/double 286- \0 for chars 287- NULL for pointers 288- false for booleans (stdbool.h) 289 290Array and structure initialization should use designated initializers. These 291allow elements to be initialized using array indexes or structure field names 292and without a fixed ordering. 293 294Array initialization example: 295```c 296uint32_t clock_frequencies[3] = { 297 [2] = 800, 298 [0] = 675 299}; 300``` 301 302Structure initialization example: 303```c 304struct clock clock_cpu = { 305 .name = "CPU", 306 .frequency = 800, 307}; 308``` 309 310Integers 311-------- 312To mitigate the risk of integer wrap-around, conversion or truncation errors: 313 314- represent integer values that should never be negative with the `unsigned` 315type that you expect to hold all possible values. 316 317- represent integer values that may be negative with the `signed` type that you 318expect to hold all possible values. 319 320- when taking untrusted integer input, ensure you check them against the lower 321and upper bound of the integer type you store them in. 322 323Device Register Definitions 324--------------------------- 325The format for structures representing memory-mapped device registers is 326standardized. 327 328- The file containing the device structure must include `<stdint.h>` to gain 329access to the uintxx_t and UINTxx_C definitions. 330- The file containing the device structure must include `<fwk_macros.h>` to 331gain access to the FWK_R, FWK_W and FWK_RW macros. 332- All non-reserved structure fields must be prefixed with one of the above 333macros, defining the read/write access level. 334- Avoid C structure bit-fields when representing hardware registers - how 335bit-fields are represented in memory is implementation-defined. 336- Bit definitions should be declared via UINTxx_C macros. 337- Bit definitions must be prefixed by the register name it relates to. If bit 338definitions apply to multiple registers, then the name must be as common as 339possible and a comment must explicit show which registers it applies to. 340- The structure name for the programmer's view must follow the pattern "struct 341<device_name>_reg { ...registers... };" 342 343```c 344#include <stdint.h> 345#include <fwk_macros.h> 346 347struct devicename_reg { 348 /* Readable and writable register */ 349 FWK_RW uint32_t CONFIG; 350 uint32_t RESERVED1; 351 352 /* Write-only register */ 353 FWK_W uint32_t IRQ_CLEAR; 354 355 /* Read-only register */ 356 FWK_R uint32_t IRQ_STATUS; 357 uint32_t RESERVED2[0x40]; 358}; 359 360/* Register bit definitions */ 361#define CONFIG_ENABLE UINT32_C(0x00000001) 362#define CONFIG_SLEEP UINT32_C(0x00000002) 363 364#define IRQ_STATUS_ALERT UINT32_C(0x00000001) 365``` 366 367__Note:__ A template file can be found in doc/template/device.h 368