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