1# Development Guidelines<a name="EN-US_TOPIC_0000001182409801"></a> 2 3- [Available APIs](#section158501652121514) 4- [How to Develop](#section5241132917523) 5- [Development Example](#section8708112313531) 6 7## Available APIs<a name="section158501652121514"></a> 8 9**Table 1** Functions 10 11<a name="table18293928155615"></a> 12<table><thead align="left"><tr id="row129362875613"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p19444103765618"><a name="p19444103765618"></a><a name="p19444103765618"></a>Category</p> 13</th> 14<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p944473716569"><a name="p944473716569"></a><a name="p944473716569"></a>API</p> 15</th> 16<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p144445378565"><a name="p144445378565"></a><a name="p144445378565"></a>Description</p> 17</th> 18</tr> 19</thead> 20<tbody><tr id="row16964173231"><td class="cellrowborder" rowspan="4" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p106040172412"><a name="p106040172412"></a><a name="p106040172412"></a>Dynamic loading</p> 21</td> 22<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p136961178237"><a name="p136961178237"></a><a name="p136961178237"></a>LOS_DynlinkInit</p> 23</td> 24<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p3697131710237"><a name="p3697131710237"></a><a name="p3697131710237"></a>Initializes the dynamic linker linked list and mutex.</p> 25</td> 26</tr> 27<tr id="row18697201714231"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p66971817102319"><a name="p66971817102319"></a><a name="p66971817102319"></a>LOS_SoLoad</p> 28</td> 29<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1569711715233"><a name="p1569711715233"></a><a name="p1569711715233"></a>Loads the shared library in a specified path.</p> 30</td> 31</tr> 32<tr id="row18697117132313"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1697161732312"><a name="p1697161732312"></a><a name="p1697161732312"></a>LOS_FindSym</p> 33</td> 34<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p5697917132313"><a name="p5697917132313"></a><a name="p5697917132313"></a>Searches for the specified symbol based on the shared library handle.</p> 35</td> 36</tr> 37<tr id="row1925202662319"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p7925526112315"><a name="p7925526112315"></a><a name="p7925526112315"></a>LOS_SoUnload</p> 38</td> 39<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p492520269233"><a name="p492520269233"></a><a name="p492520269233"></a>Unloads the shared library handle.</p> 40</td> 41</tr> 42</tbody> 43</table> 44 45## How to Develop<a name="section5241132917523"></a> 46 471. Use the arm-none-eabi-gcc cross compiler to compile the shared library and build a FAT or LittleFS image, and burn the image to the flash memory. 482. In the **target\_config.h** file, set **LOSCFG\_DYNLINK** to **1** to enable the dynamic loading module. 493. Call **LOS\_SoLoad** to load the shared library in the specified path. 504. Call **LOS\_FindSym** to search for the specified symbol and obtain the symbol address. 515. Call **LOS\_SoUnload** to unload the handle of the specified shared library. 52 53> **NOTE:** 54>1. For details about the compilation options required for compiling the shared library using the cross compiler, see the ELF specifications. 55>2. Before creating a file system image, you need to adapt the FAT or LittleFS to the specific board. 56>3. The shared library does not depend on the libc library in the compiler and does not support C++. 57>4. The shared library depends only on the APIs provided by the kernel and cannot depend on other shared libraries. 58 59## Development Example<a name="section8708112313531"></a> 60 61The following uses the Arm Cortex-M4 board as an example. 62 631. Sample Code and Compilation of the Shared Library 64 65 The sample code is used to test the calling of global symbols and calling of the kernel APIs **malloc**, **free**, and **memset**. 66 67 ``` 68 #include <stdlib.h> 69 #include <string.h> 70 71 int g_param = 10; 72 73 int callee(int a, int b) 74 { 75 char *addr = malloc(g_param); 76 if (addr == NULL) { 77 return 0; 78 } 79 80 memset(addr, '1', g_param); 81 82 free(addr); 83 return a + b + g_param; 84 } 85 86 int caller(int a, int b) 87 { 88 return callee(a, b); 89 } 90 ``` 91 92 ``` 93 $ arm-none-eabi-gcc -fPIC -shared -mcpu=cortex-m4 -nostdlib -nostartfiles -z max-page-size=4 -o test.so test.c 94 ``` 95 962. Export the malloc, free, and memset symbols used in the shared library. Compile the following code into a .c file and use it for OS compilation. 97 98 ``` 99 #include "stdlib.h" 100 #include "string.h" 101 102 SYM_EXPORT(malloc); 103 SYM_EXPORT(free); 104 SYM_EXPORT(memset); 105 ``` 106 1073. Determine the kernel compilation environment and add the following statement to the linking script of the compiler to ensure that the symbol table information is output to the specified section during compilation and linking. 108 109 Add the following statement to the **.icf** linking script of the IAR compiler: 110 111 ``` 112 keep {section .TABLE.START}; 113 keep {section .sym.*}; 114 keep {section .table.end}; 115 define block SYMBOL_TABLE with fixed order 116 { 117 section .TABLE.START, 118 section .sym.*, 119 section .table.end 120 }; 121 place in ROM_region {readonly, block SYMBOL_TABLE}; 122 ``` 123 124 Add the following statement to the **.ld** linking script of the GCC compiler: 125 126 ``` 127 __sym_table_start = .; 128 KEEP(*( SORT (.sym.*))); 129 __sym_table_end = .; 130 ``` 131 1324. Load, link, execute, and unload the shared library. 133 134 The sample code is used to test whether the functions of the **LOS\_SoLoad**, **LOS\_FindSym**, and **LOS\_SoUnload** can be implemented normally and whether the symbols located by using **LOS\_FindSym** can be properly called. 135 136 ``` 137 #include "los_dynlink.h" 138 139 VOID DynlinkTest(VOID) 140 { 141 VOID *handle = NULL; 142 INT32 (*func)(INT32, INT32) = NULL; 143 CHAR *symbolName = "caller"; 144 CHAR *dsoName = "/lib/test.so"; 145 INT32 ret; 146 147 handle = (VOID *)LOS_SoLoad(dsoName, NULL); 148 if (handle == NULL) { 149 printf("Failed to load so\n"); 150 return; 151 } 152 153 func = (INT32 (*)(INT32, INT32))LOS_FindSym(handle, symbolName); 154 if (func == NULL) { 155 printf("Failed to find symbol\n"); 156 LOS_SoUnload(handle); 157 return; 158 } 159 160 ret = func(1, 1); 161 if (ret != 12) { 162 printf("Failed to execute function\n"); 163 LOS_SoUnload(handle); 164 return; 165 } 166 167 ret = LOS_SoUnload(handle); 168 if (ret != 0) { 169 printf("Failed to unload so\n"); 170 } 171 172 173 printf("Success!\n"); 174 } 175 ``` 176 1775. Verification 178 179 ``` 180 Success! 181 ``` 182 183 184> **NOTE:** 185>In this example, the file system path is **/lib/test.so**. 186>You can create a task and call **DynlinkTest** in the task to perform the test. 187 188