1# Kernel Coding Specification 2 3 4This kernel coding specification is developed based on the general programming specifications in the industry. It defines the programming styles for kernel developers to follow. 5 6## Principle 7 8Overall principle: 9 10- Clear: The code should be easy to understand, maintain, and rebuilt. Avoid obscure syntax. 11- Simple: Use short names and compact functions. 12- Efficient: Improve program efficiency by using algorithms, compiler optimization options, or hardware resources. 13- Concise: The code is reasonable and consistent. 14 15Comply with this specification in most cases. When third-party open-source code needs to modified or a large number of open-source code APIs are used, follow the specifications applied to the third-party open-source code. Flexibly use this specification based on general principles. 16 17## Directory Structure 18 19You are advised to divide directories by function module and then define the header file directory and source file directory for each module. 20 21Unless otherwise specified, use lowercase letters separated by underscores \(\_\) for directory names and file names. 22 23## **Naming** 24 25The CamelCase style is recommended. The rules are as follows: 26 27<a name="table881274918408"></a> 28<table><thead align="left"><tr id="row1886484994019"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.1"><p id="p6864184954016"><a name="p6864184954016"></a><a name="p6864184954016"></a>Type</p> 29</th> 30<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.2"><p id="p486416495404"><a name="p486416495404"></a><a name="p486416495404"></a>Naming Style</p> 31</th> 32<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.3"><p id="p18864549124011"><a name="p18864549124011"></a><a name="p18864549124011"></a>Format</p> 33</th> 34</tr> 35</thead> 36<tbody><tr id="row486494913409"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p2864184916403"><a name="p2864184916403"></a><a name="p2864184916403"></a>Function, struct, enumeration, union, and typedef</p> 37</td> 38<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p18864154944015"><a name="p18864154944015"></a><a name="p18864154944015"></a>Upper camel case, or upper camel case prefixed with the module name</p> 39</td> 40<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p10864249124015"><a name="p10864249124015"></a><a name="p10864249124015"></a>AaaBbb</p> 41<p id="p1886444919403"><a name="p1886444919403"></a><a name="p1886444919403"></a>XXX_AaaBbb</p> 42</td> 43</tr> 44<tr id="row198643495409"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p18864174964013"><a name="p18864174964013"></a><a name="p18864174964013"></a>Local variables, function parameters, macro parameters, structure fields, and union members</p> 45</td> 46<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p12864204924018"><a name="p12864204924018"></a><a name="p12864204924018"></a>Lower camel case</p> 47</td> 48<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p8864549124012"><a name="p8864549124012"></a><a name="p8864549124012"></a>aaaBBB</p> 49</td> 50</tr> 51<tr id="row15864184913405"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p786484914014"><a name="p786484914014"></a><a name="p786484914014"></a>Global variables</p> 52</td> 53<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1786544914400"><a name="p1786544914400"></a><a name="p1786544914400"></a>Lower camel case prefixed with g_</p> 54</td> 55<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1986594994013"><a name="p1986594994013"></a><a name="p1986594994013"></a>g_aaaBBB</p> 56</td> 57</tr> 58<tr id="row48651849104017"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p8865104914407"><a name="p8865104914407"></a><a name="p8865104914407"></a>Macros (excluding function-like macros), enumerated values, goto tags</p> 59</td> 60<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p186574954011"><a name="p186574954011"></a><a name="p186574954011"></a>All uppercase letters separated with underscores (_)</p> 61</td> 62<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p188653494401"><a name="p188653494401"></a><a name="p188653494401"></a>AAA_BBB</p> 63</td> 64</tr> 65<tr id="row1286516495402"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p108651749114012"><a name="p108651749114012"></a><a name="p108651749114012"></a>Function-like macros</p> 66</td> 67<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1586534910405"><a name="p1586534910405"></a><a name="p1586534910405"></a>Uppercase letters separated with underscores (_), upper camel case, or upper camel case prefixed with the module name</p> 68</td> 69<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1186544904010"><a name="p1186544904010"></a><a name="p1186544904010"></a>AAA_BBB</p> 70<p id="p18865174918402"><a name="p18865174918402"></a><a name="p18865174918402"></a>AaaBbb</p> 71<p id="p13865174910407"><a name="p13865174910407"></a><a name="p13865174910407"></a>XXX_AaaBbb</p> 72</td> 73</tr> 74<tr id="row6865154974017"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p6865114944011"><a name="p6865114944011"></a><a name="p6865114944011"></a>Header file names</p> 75</td> 76<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p16865134944010"><a name="p16865134944010"></a><a name="p16865134944010"></a>Starts with an underscore (_) and ends with H. The middle part is the file name in all caps and is separated by underscores (_).</p> 77</td> 78<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1986520493408"><a name="p1986520493408"></a><a name="p1986520493408"></a>_AAA_H</p> 79</td> 80</tr> 81</tbody> 82</table> 83 84The **LOS\_**_ModuleFunc_ format is recommended for external APIs of the kernel. Preposition the object if there is any. Example: 85 86``` 87LOS_TaskCreate 88LOS_MuxLock 89``` 90 91The APIs between internal modules in the kernel directory are in the **Os**_ModuleFunc_ format. For example: 92 93``` 94OsTaskScan 95OsMuxInit 96``` 97 98## Comments 99 100Generally, clear software architecture and appropriate symbol naming improve code readability. 101 102Comments are added to make the source code easier for humans to understand. Therefore, add comments only when necessary, from the perspective of the readers. 103 104Comments must be concise, clear, and unambiguous. The information must be complete and not redundant. 105 106Comments must be added to the file header. It is recommended that the comments include the copyright description, file function description, author, creation date, and precautions. 107 108Use a consistent style for comments. The use of /\* and \*/ as block comment delimiters is recommended. There must be a space between the comment characters and the comment. Comment single-line and multi-line comments are as follows: 109 110``` 111/* Single-line comment */ 112// Single-line comment 113/* 114 * Multi-line comment 115 * Second line 116 */ 117// Multi-line comment 118// Another line 119``` 120 121Place the code comment above or to the right of the code. 122 123Leave no blank line between the code and the comment, and indent the comment the same way as the code. 124 125Leave at least one space between the code and the comment on the right. 126 127You are advised to align multiple consecutive comments on the right. For example: 128 129``` 130#define CONST_A 100 /* Const A */ 131#define CONST_B 2000 /* Const B */ 132``` 133 134## **Format** 135 136Indent code of each level with four spaces rather than tabs \('\\t'\) for a better readability. 137 138While wrapping a line, the left brace of the function starts a new line and takes a single line. Other left braces are placed at the end of the line along with the statement. The right brace occupies one line unless followed by the remaining part of the same statement, for example, while in the do statement, else/else if in the if statement, or a comma or semicolon. 139 140Write only one statement in one line. 141 142Example: 143 144``` 145struct MyType { // Add a comment here, and leave a space between the comment sign (//) and the comment. 146 ... 147}; // The right brace is followed by a semicolon (;). 148int Foo(int a) {// The left brace of the function is placed at the beginning of a line and occupies one line. 149 if (a > 0) { 150 Foo(); // There is only one statement in a line. 151 Bar(); 152 } else { // The right brace, else, and the subsequent left brace are in the same line. 153 ... 154 } // The right brace occupies one line exclusively. 155 ... 156} 157``` 158 159Avoid lines longer than 120 characters. When starting a new line, place the operator at the end of the line, indent the new line or align the lines of the same type, and place the operator indicating not end or connection sign at the end of the line. 160 161``` 162// Assume that the first line below does not fit on a single line. 163if (currentValue > MIN && // Good: Place the Boolean operator at the end of the new line. 164 currentValue < MAX) { // Good: Align with the two operands of the (&&) operator. 165 DoSomething(); 166 ... 167} 168flashPara.flashEndAddr = flashPara.flashBaseAddr + // Good: Place the plus sign at the end of the line. 169 flashPara.flashSize; // Good: Align the two operands. 170 171// Good: Place function parameters in one line. 172ReturnType result = FunctionName(paramName1, paramName2); 173ReturnType result = FunctionName(paramName1, 174 paramName2, 175 paramName3); // Good: Align with the preceding parameters. 176ReturnType result = FunctionName(paramName1, paramName2, 177 paramName3, paramName4, paramName5); // Good: Place the parameters in a new line, with an indentation of 4 spaces. 178ReturnType result = VeryVeryVeryLongFunctionName( // Start a new line because the first parameter does not fit on a single line. 179 paramName1, paramName2, paramName3); // Indent the new line 4 spaces. 180 181// Good: Place a group of data structures with strong correlation in a line for easy understanding. 182int result = DealWithStructLikeParams(left.x, left.y, // Indicates a group of related parameters. 183 right.x, right.y); // Indicates another group of related parameters. 184``` 185 186Use braces, that is, compound statements for **if**, **for**, **while**, and **do-while** statements. 187 188``` 189while (condition) {} // Good: Use braces even if the loop body is empty. 190while (condition) { 191 continue; // Good: continue indicates empty logic. Use braces. 192} 193``` 194 195Indent the **case** or **default** statement as follows compared with the **switch** statement: 196 197``` 198switch (var) { 199 case 0: // Good: Indent 200 DoSomething1(); // Good: indent 201 break; 202 case 1: { // Good: with braces 203 DoSomething2(); 204 break; 205 } 206 default: 207 break; 208} 209``` 210 211The pointer "\*" follows a variable or function name, for example: 212 213``` 214int *p1; // OK 215int* p2; // Bad: The pointer * follows a data type. 216int*p3; // Bad: There is no space on both sides of *. 217int * p4; // Bad: There is a space on both sides of *. 218struct Foo *CreateFoo(void); // OK: The pointer * follows a function name. 219Exception: 220char * const VERSION = "V100"; // OK: When there is the const modifier, a space is required on both sides of *. 221int Foo(const char * restrict p); // OK: When there is the restrict modifier, a space is required on both sides of *. 222sz = sizeof(int*); // OK: There is no variable on the right, and * follows the data type. 223``` 224 225## Macros 226 227If a function-like macro can be replaced by a function, use a function instead. Use inline functions for performance-critical scenarios. 228 229When defining a macro, use complete parentheses \(round brackets\). For example: 230 231``` 232#define SUM(a, b) ((a) + (b)) // Complies with this specification. 233#define SOME_CONST 100 // Good: No parentheses are required for a single number. 234#define ANOTHER_CONST (-1) // Good: Parentheses are required for a negative number. 235#define THE_CONST SOME_CONST // Good: No parentheses are required for a single identifier. 236``` 237 238Pay attention to the following: 239 240- Do not add parentheses for macro parameters used in \# or \#\# operations. 241- Do not add parentheses for macro parameters used in string concatenation. 242- If a macro parameter is used as a separate part in one side of an assignment operation\(including += and -=\), parentheses can be omitted. 243- If a macro parameter is used as a separate part in a comma expression, function, or macro call list, parentheses can be omitted. 244 245``` 246// Do not enclose x in parentheses. 247#define MAKE_STR(x) #x 248 249// Do not enclose obj in parentheses. 250#define HELLO_STR(obj) "Hello, " obj 251 252// Parentheses are required for a and b, but not for value. 253#define UPDATE_VALUE(value, a, b) (value = (a) + (b)) 254 255// Parentheses are required for a, but not for b. 256#define FOO(a, b) Bar((a) + 1, b) 257``` 258 259The statement used to implement the function-like macros that contain multiple statements must be placed in **do-while\(0\)**. 260 261Do not pass expressions with side effects, such as **a++**, to function-like macros as parameters. 262 263Exercise caution when using the statements such as **return**, **goto**, **continue**, and **break** in the function-like macro definition. 264 265Do not use preprocessor directives, such as **\#include**, **\#define**, and **\#ifdef**, in arguments for macro calling. Otherwise, undefined behavior may occur. 266 267Do not end macro definitions with a semicolon \(;\). 268 269## Header Files<a name="section158507231319"></a> 270 271A header file should have a single responsibility. 272 273Generally, each .c file should have a .h file \(the file name may not be the same\) to store the function declaration, macro definition, and type definition provided externally. If no external API is provided, the .h file can be skipped. 274 275Avoid circular dependency between header files. For example, **a.h** contains **b.h**, **b.h** contains **c.h**, and **c.h** contains **a.h**. 276 277Header files should be self-contained \(compile on their own\). 278 279Protect header files by **\#define**, **\#ifndef**, and **\#endif** to prevent repeated inclusion. Do not use **\#pragma once**. 280 281Do not reference external function APIs or variables in declaration mode. Use the APIs provided by other modules or files only by including header files. 282 283It is recommended that header files be included by stability in the following sequence: header file corresponding to the source code, C standard library, operating system library, platform library, project public library, and other dependencies. 284 285## Data Types 286 287You are advised to use the basic data types defined in **los\_compiler.h**. For example, define the 32-bit unsigned integer as **UINT32**. 288 289## Variables 290 291Avoid large stack allocations, such as large local arrays. 292 293Use global variables with caution. Do not use or reduce global variables if possible. 294 295Variables must be initialized before being used. 296 297Do not return the address of a local variable outside its scope. 298 299A variable that points to a resource handle or descriptor is assigned a new value immediately after the resource is released. If the scope of the variable ends immediately, no new value needs to be assigned. Variables that point to resource handles or descriptors include pointers, file descriptors, socket descriptors, and other variables that point to resources. 300 301## Assertions 302 303Assertions must be defined using macros and take effect only in the debugging version. 304 305Assertions should be considered as design constraints. Do not use assertions to detect errors that may occur during program running. Use error processing code to handle possible errors. 306 307Do not change the running environment in an assertion. 308 309An assertion is used to check only one error. 310 311## Functions 312 313The validity of data sent from a process to another process and data sent from an application to the kernel must be verified. The verification includes but is not limited to the following: 314 315- Data length 316- Data range 317- Data type and format 318- Input that contains only acceptable characters \(in a trustlist\) 319 320Do not use global variables, static local variables, or direct I/O operations in functions. If such operations are inevitable, encapsulate read and write operations. 321 322