• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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