• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# IoT Solution - Chipsea CST85 Chip Porting Case
2
3This document describes how to port the OpenHarmony LiteOS-M mini system on the cst85_wblink development board based on the Chipsea CST85 chip. In this document, Wi-Fi connection and XTS test samples are developed, and the adaptation of components such as wifi_lite, lwIP, startup, Utils, XTS, and HDF is implemented based on the OpenHarmony LiteOS-M kernel. The porting architecture uses the Board and SoC separation solution and the Newlib C library as the toolchain. The LiteOS-M kernel is compiled in gn+Kconfig graphical configuration mode.
4
5## Compilation and Building Adaptation
6
7### Directory Planning
8
9This solution designs the directory structure using the [board and SoC decoupling idea](https://gitee.com/openharmony-sig/sig-content/blob/master/devboard/docs/board-soc-arch-design.md).
10
11```
12device
13├── board                                --- Board vendor directory.
14│   └── chipsea                          --- Board vendor name Chipsea.
15│       └── cst85_wblink                 --- Board name cst85_wblink.
16└── soc                                  --- SoC vendor directory.
17    └── chipsea                          --- SoC vendor name Chipsea.
18        └── cst85                        --- SoC series name CST85.
19```
20
21The planned product demo directory is as follows:
22
23```
24vendor
25└── chipsea                              --- Vendor of the product demo, which is Chipsea here.
26    ├── iotlink_demo                     --- Product name: Wi-Fi sample.
27    └── xts_demo                         --- Product name: XTS test sample.
28```
29
30### Product Definition
31The vendor/chipsea/iotlink_demo describes the kernel, board, and subsystem information used by the product. The kernel, board model, and board vendor are required by the precompilation command and must be planned in advance. The information entered here corresponds to the planned directory. Example:
32```
33{
34  "product_name": "iotlink_demo",        --- Product name.
35  "version": "3.0",                         --- OS version: 3.0
36  "device_company": "chipsea",           --- Board vendor: Chipsea
37  "board": "cst85_wblink",               --- Board name: cst85_wblink
38  "kernel_type": "liteos_m",                --- Kernel type: liteos_m
39  "kernel_version": "3.0.0",                --- Kernel version: 3.0.0
40  "subsystems": []                          --- Subsystems
41}
42```
43
44### Board Configuration
45In the directory associated with the product definition, for example, **/device/board/chipsea/cst85_wblink**, you need to place the **config.gni** file in the **liteos_m** directory. This configuration file describes the board information, including the CPU, toolchain, kernel, and compile_flags. Example:
46```
47# Kernel type
48kernel_type = "liteos_m"
49
50# Kernel version
51kernel_version = "3.0.0"
52
53# Board CPU type
54board_cpu = "cortex-m4"
55
56# Toolchain: arm-none-eabi
57board_toolchain = "arm-none-eabi"
58
59# Path of the toolchain. You can use the system path '''' or customize the path.
60board_toolchain_path = ""
61
62# Compilation parameters about the board
63board_cflags = []
64
65# Link parameters about the board
66board_ld_flags = []
67
68# Header files about the board
69board_include_dirs = []
70
71# Board adapter dir for OHOS components.
72board_adapter_dir = "${ohos_root_path}device/soc/chipsea"
73```
74
75### Precompilation
76After the product directory, product definition, and board configuration are correctly configured, enter the precompilation command **hb set** in the root directory of the project. Then you can find the related product in the displayed list.
77
78![ohos_config.json](figures/cst85_hb_set.png)
79
80After you select a product and press **Enter**, a `ohos_config.json` file will be generated in the root directory. The file will list the product information to be compiled.
81
82```
83{
84  "root_path": "/home/openharmony",
85  "board": "cst85_wblink",
86  "kernel": "liteos_m",
87  "product": "iotlink_demo",
88  "product_path": "/home/openharmony/vendor/chipsea/iotlink_demo",
89  "device_path": "/home/openharmony/device/board/chipsea/cst85_wblink/liteos_m",
90  "device_company": "chipsea",
91  "os_level": "mini",
92  "version": "3.0",
93  "patch_cache": null,
94  "product_json": "/home/openharmony/vendor/chipsea/iotlink_demo/config.json",
95  "target_cpu": null,
96  "target_os": null,
97  "out_path": "/home/openharmony/out/cst85_wblink/iotlink_demo"
98}
99```
100
101
102## Kernel Porting
103
104### Kconfig Adaptation
105
106During the compilation of **//kernel/liteos_m**, you need to use the `Kconfig` file for configurations in the corresponding board and SoC directories. Let's see the related configurations in the board and SoC directories.
107
108The following uses `//device/board/chipsea` as an example for the `Kconfig` in the board directory:
109```
110device/board/chipsea
111├── cst85_wblink                                 --- Board configuration directory **cst85_wblink**.
112│   ├── Kconfig.liteos_m.board                   --- Board configuration options.
113│   ├── Kconfig.liteos_m.defconfig.board         --- Default board configuration items.
114│   └── liteos_m
115│       └── config.gni                           --- Board configuration file.
116├── Kconfig.liteos_m.boards                      --- Board configurations of the board vendor.
117└── Kconfig.liteos_m.defconfig.boards            --- Board configurations of the board vendor.
118```
119
120In `cst85_wblink/Kconfig.liteos_m.board`, configure that **BOARD_CST85_WBLINK** can be selected only when **SOC_CST85F01** is selected.
121```
122config BOARD_CST85_WBLINK
123    bool "select board cst85_wblink"
124    depends on SOC_CST85F01
125```
126
127The following uses `//device/soc/chipsea` as an example for the `Kconfig` in the SoC directory:
128
129```
130device/soc/chipsea/
131├── cst85                                        --- CST85 series.
132│   ├── Kconfig.liteos_m.defconfig.cst85f01      --- Default CST85F01 SoC configuration.
133│   ├── Kconfig.liteos_m.defconfig.series        --- Default configuration of the CST85 series.
134│   ├── Kconfig.liteos_m.series                  --- Configuration of the CST85 series.
135│   └── Kconfig.liteos_m.soc                     --- CST85 SoC configuration.
136├── Kconfig.liteos_m.defconfig                   --- Default SoC configuration.
137├── Kconfig.liteos_m.series                      --- Series configuration.
138└── Kconfig.liteos_m.soc                         --- SoC configuration.
139```
140
141The `cst85/Kconfig.liteos_m.series` configuration is as follows:
142
143```
144config SOC_SERIES_CST85
145    bool "Chipsea CST85 Series"
146    select ARM
147    select SOC_COMPANY_CHIPSEA
148    select CPU_CORTEX_M4
149    help
150        Enable support for Chipsea CST85 series
151```
152
153**SOC_CST85F01** can be selected in **cst85/Kconfig.liteos_m.soc** only when **SOC_SERIES_CST85** is selected.
154
155```
156choice
157    prompt "Chipsea CST85 series SoC"
158    depends on SOC_SERIES_CST85
159
160config SOC_CST85F01
161    bool "SoC CST85F01"
162
163endchoice
164```
165
166To compile **BOARD_CST85_WBLINK**, select **SOC_COMPANY_CHIPSEA**, **SOC_SERIES_CST85** and **SOC_CST85F01**. You can run the `make menuconfig` command in `kernel/liteos_m` for configurations.
167
168![cst85_kconfig.json](figures/cst85_kconfig.png)
169
170The configured file is saved to `//vendor/chipsea/iotlink_demo/kernel_configs/debug.config` by default. You can also directly configure **debug.config**.
171
172```
173LOSCFG_SOC_SERIES_CST85=y
174LOSCFG_KERNEL_BACKTRACE=y
175LOSCFG_KERNEL_CPUP=y
176LOSCFG_PLATFORM_EXC=y
177```
178
179### Modular Compilation
180
181The compilation of `Board` and `SoC` adopts the modular compilation method, starting from **kernel/liteos_m/BUILD.gn** and increasing by level. The adaptation process of this solution is as follows:
182
1831. Create the **BUILD.gn** file in `//device/board/chipsea` and add the following content to the file:
184
185   ```
186   if (ohos_kernel_type == "liteos_m") {
187     import("//kernel/liteos_m/liteos.gni")
188     module_name = get_path_info(rebase_path("."), "name")
189     module_group(module_name) {
190       modules = [
191         "cst85_wblink"
192       ]
193     }
194   }
195   ```
196
197   In the preceding **BUILD.gn** file, **cst85_wblink** is the module name organized by directory level.
198
1992. Create the **BUILD.gn** file in `//device/soc/chipsea` in the same way and add the following content to the file by directory level:
200
201   ```
202   if (ohos_kernel_type == "liteos_m") {
203     import("//kernel/liteos_m/liteos.gni")
204     module_name = get_path_info(rebase_path("."), "name")
205     module_group(module_name) {
206       modules = [
207         "cst85",
208         "hals",
209       ]
210     }
211   }
212   ```
213
2143. In the `//device/soc/chipsea` module at each level, add the **BUILD.gn** file and compile the module. The following uses `//device/soc/chipsea/cst85/liteos_m/sdk/bsp/arch/BUILD.gn` as an example:
215
216   ```
217   import("//kernel/liteos_m/liteos.gni")
218   module_name = "sdk_bsp_arch"
219
220   kernel_module(module_name) {
221     sources = [
222       "boot/armgcc_4_8/boot_startup.S",
223       "boot/armgcc_4_8/exception.S",
224       "boot/fault_handler.c",
225
226       "cmsis/cmsis_nvic.c",
227
228       "ll/ll.c",
229
230       "main/arch_main.c",
231     ]
232
233     include_dirs = [
234       "boot",
235       "boot/armgcc_4_8",
236     ]
237
238     deps = [
239       "//base/startup/bootstrap_lite/services/source:bootstrap",
240     ]
241   }
242
243   config("public") {
244     include_dirs = [
245       ".",
246       "boot",
247       "compiler",
248       "cmsis",
249       "ll",
250     ]
251   }
252   ```
253
254   To organize links and some compilation options, set the following parameters in **config("public")**:
255
256   ```
257   config("public") {
258     include_dirs = []                       --- Common header file.
259     ldflags = []                            --- Link parameters, including the Id file.
260     libs = []                               --- Link library.
261     defines = []                            --- Definitions.
262   }
263   ```
264
265   ![](../public_sys-resources/icon-note.gif) **NOTE**
266   It is recommended that common parameter options and header files not be repeatedly filled in each component.
267
268### Kernel Startup Adaptation
269
270The kernel startup adaptation file is stored in `//device/soc/chipsea/cst85/liteos_m/sdk/modules/rtos/src/rtos.c`.
271
272The general idea of kernel startup adaptation is as follows:
273
2741. Use `OsVectorInit();` to initialize the interrupt vector and initialize the interrupt processing function.
2752. Use `osKernelInitialize` to initialize the kernel.
2763. Create a thread for OS component platform initialization using `OHOS_SystemInit`.
2774. Use `DeviceManagerStart()` for HDF initialization.
2785. The kernel starts to schedule the `LOS_Start` thread.
279
280This section describes step 3 in detail. Other steps are used to call kernel functions and are not described here.
281
282Initialize necessary actions before **OHOS_SystemInit** is started in step 3, as shown below:
283
284```
285...
286    LOS_KernelInit();
287    DeviceManagerStart();
288    OHOS_SystemInit();
289    LOS_Start();
290
291....
292```
293
294### Interrupt Adaptation
295To ensure the normal running of LiteOS-M, two interrupt service routines must be redirected to the ISRs specified by LiteOS-M: HalPendSV and OsTickerHandler. This depends on whether LiteOS-M takes over the interrupt vector table when LiteOS-M is adapted.
296```
297/**
298 * @ingroup los_config
299 * Configuration item for using system defined vector base address and interrupt handlers.
300 * If LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT is set to 0, vector base address will not be
301 * modified by system. In arm, it should be noted that PendSV_Handler and SysTick_Handler should
302 * be redefined to HalPendSV and OsTickHandler respectably in this case, because system depends on
303 * these interrupt handlers to run normally. What's more, LOS_HwiCreate will not register handler.
304 */
305#ifndef LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT
306#define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT                 1
307#endif
308```
309
310#### Whether the OS Takes Over Interrupt Vectors
311You can configure the **target_config.h** file to determine whether to take over LiteOS. The options are: **1**: yes; **0**: no.
312```
313#define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT                 0
314```
315
316
317If this parameter is set to **1**, LiteOS changes **SCB->VTOR** to **g_hwiForm**. Therefore, the ArchHwiCreate API of the LITEOS needs to be called to configure the original ISRs of the SoC to the new interrupt vector table **g_hwiForm** during startup, and the interrupt service routines of PendSV and SysTicke are redirected to HalPendSV and OsTickerHandler. Otherwise, the original ISRs of the SoC do not respond.
318
319If this parameter is set to **0**, the original interrupt vector table of the SoC is used. For CST85F01, the interrupt vector table is **__vectors_start___** (**NVIC_Vectors_Init** copies the content of **__isr_vector** to this table). To adapt LiteOS, you must redirect the interrupt service routines of PendSV and SysTick to HalPendSV and OsTickHandler. Otherwise, the system cannot run.
320
321In this example, LiteOS is not allowed to take over interrupt processing. Therefore, you need to redirect the interrupt service routines of PendSV and SysTick to HalPendSV and OsTickHandler during startup.
322```
323#ifdef CFG_LITEOS
324static void OsVectorInit(void)
325{
326    NVIC_SetVector(PendSV_IRQn, (uint32_t)HalPendSV);
327    NVIC_SetVector(SysTick_IRQn, (uint32_t)OsTickHandler);
328}
329#endif
330```
331
332#### Interrupt Vector Table Address Alignment
333As described in the documents related to Cortex-M, the minimum address of the interrupt vector table is 32-byte aligned, that is, 0x80.
334For example, if 21 more interrupts are required, a total of 37 interrupts are required because there are already 16 system interrupts. One 0x80 is insufficient for 37\*4 entries, and two 0x80s, that is, 0x100, are required.
335
336In CST85F01 adaptation, the maximum number of interrupt vectors is 128 (defined in **target_config.h**).
337```
338#define LOSCFG_PLATFORM_HWI_LIMIT                           128
339```
340Here, 128 interrupts and system interrupts are required, that is, a total of 144 (128 + 16) interrupts, and 144\*4 entries are required. These entries need to be covered by four 0x80s, that is, 0x200 alignment. Otherwise, the system restarts.
341Therefore, the interrupt alignment needs to be overridden to 0x200.
342```
343#ifndef LOSCFG_ARCH_HWI_VECTOR_ALIGN
344#define LOSCFG_ARCH_HWI_VECTOR_ALIGN                         0x200
345#endif
346```
347
348### LittleFS Adaptation
349
350In the XTS test, the syspara test involves the read and write of files in the KV storage. Therefore, a file system needs to be adapted to store the KV to a certain position in the flash memory. Therefore, the LittleFS is adapted.
351
352During the adaptation, an adaptation API needs to be added to `device/soc/chipsea/cst85/liteos_m/components/drivers/littlefs`.
353
354```
355  #define LFS_DEFAULT_START_ADDR 0x081E3000 ---LittleFS start address
356  #define LFS_DEFAULT_BLOCK_SIZE 4096 --- Block size
357  #define LFS_DEFAULT_BLOCK_COUNT 25        ---Number of blocks
358
359```
360
361Finally, the LittleFS API of the kernel is implemented in `device/soc/chipsea/cst85/liteos_m/components/drivers/littlefs/hal_vfs.c`.
362
363```
364int32_t hal_vfs_init(void)
365{
366    VfsOps = malloc(sizeof(struct lfs_manager));
367    if (VfsOps == NULL) {
368        printf("+++ hal_vfs_init: NO memory!!\n");
369        return -1;
370    } else {
371        memset(VfsOps, 0, sizeof(struct lfs_manager));
372    }
373
374    VfsOps->LfsOps.read = lfs_block_read; // Flash read API
375    VfsOps->LfsOps.prog = lfs_block_write; // Flash write API
376    VfsOps->LfsOps.erase = lfs_block_erase; // Flash erase API
377    VfsOps->LfsOps.sync = lfs_block_sync;
378    VfsOps->LfsOps.read_size = 256;
379    VfsOps->LfsOps.prog_size = 256;
380    VfsOps->LfsOps.cache_size = 256;
381    VfsOps->LfsOps.lookahead_size = 16;
382    VfsOps->LfsOps.block_cycles = 500;
383    VfsOps->start_addr = LFS_DEFAULT_START_ADDR;
384    VfsOps->LfsOps.block_size = LFS_DEFAULT_BLOCK_SIZE;
385    VfsOps->LfsOps.block_count = LFS_DEFAULT_BLOCK_COUNT;
386
387    SetDefaultMountPath(0,"/data");
388    if (LOS_FsMount(NULL, "/data", "littlefs", 0, VfsOps) != FS_SUCCESS) {
389        printf("+++ hal_vfs_init: Mount littlefs failed!\n");
390        free(VfsOps);
391        return -1;
392    }
393
394    if (LOS_Mkdir("/data", 0777) != 0 ) {
395        printf("+++ hal_vfs_init: Make dir failed!\n");
396    }
397
398    flash_user_data_addr_length_set(LFS_DEFAULT_START_ADDR,
399            LFS_DEFAULT_BLOCK_SIZE * LFS_DEFAULT_BLOCK_COUNT);
400
401    printf("+++ hal_vfs_init: Mount littlefs success!\n");
402    return 0;
403}
404
405```
406
407
408
409### C Library Adaptation
410
411In a mini system, the C library adaptation is complex. For details about the design idea, see [LiteOS-M Kernel Supports Smooth Switching Between musl and newlib](https://gitee.com/arvinzzz/ohos_kernel_design_specification/blob/master/liteos_m/%E6%94%AF%E6%8C%81newlib/%E5%86%85%E6%A0%B8%E9%80%82%E9%85%8Dnewlib%E6%96%B9%E6%A1%88%E6%80%9D%E8%B7%AF.md). The built-in `newlib` C library is used for system porting. Select **LOSCFG_LIBC_NEWLIB=y** in `vendor/chipsea/iotlink_demo/kernel_configs/debug.config`.
412
413
414### printf Adaptation
415
416To easily use standard functions in the C library to output information, implement adaptation to output the standard function information to the hardware (serial port). Therefore, the printf function is adapted.
417
418Add the `wrap` link option of the printf function to `//device/board/chipsea/cst85_wblink/liteos_m/config.gni`.
419
420```
421board_ld_flags += [
422     "-Wl,--wrap=printf",
423]
424```
425
426Implement *_wrap* printf in `device/soc/chipsea/cst85/liteos_m/sdk/bsp/wrapper/lite_sys.c`.
427
428
429### HDF Adaptation of GPIO
430To easily use the HDF to use GPIO functions, adapt the HDF for the GPIO.
431
4321. The chip driver adaptation file is stored in the `//drivers/adapter/platform` directory. Add the **gpio_chipsea.c** and **gpio_chipsea.h** files to the **gpio** directory, and add compilation conditions of the new driver file to **BUILD.gn**.
433
434   ```
435   if (defined(LOSCFG_SOC_COMPANY_CHIPSEA)) {
436    sources += [ "gpio_chipsea.c" ]
437   }
438   ```
439
4402. Describe the driver description file in **gpio_chipsea.c** as follows:
441
442   ```
443   struct HdfDriverEntry g_gpioDriverEntry = {
444       .moduleVersion = 1,
445       .moduleName = "HDF_PLATFORM_GPIO",
446       .Bind = GpioDriverBind,
447       .Init = GpioDriverInit,
448       .Release = GpioDriverRelease,
449   };
450
451   HDF_INIT(g_gpioDriverEntry);
452   ```
453
4543. Add the GPIO hardware description file **gpio.hcs** to **cst85/liteos_m/components/hdf_config/device_info.hcs**. The mapped gpio0 controls the programmable LED on the card. The hcs file content is as follows:
455
456   ```
457   root {
458       platform :: host {
459            hostName = "platform_host";
460            priority = 50;
461            device_gpio :: device {
462                gpio0 :: deviceNode {
463                    policy = 0;
464                    priority = 100;
465                    moduleName = "HDF_PLATFORM_GPIO";
466                    serviceName = "HDF_PLATFORM_GPIO";
467                    deviceMatchAttr = "gpio_config";
468            }
469       }
470   }
471   ```
472
473
474## OpenHarmony Subsystem Adaptation
475
476### Communication Subsystem
477
478In the communication subsystem, the wifi_lite component needs to be enabled and adapt related APIs.
479
480The configuration items of the wifi_lite component are as follows:
481
482```
483"subsystem": "communication",
484"components": [
485  { "component": "wifi_lite", "features":[] }
486  ]
487```
488
489The implementation related to Wi-Fi is under `//device/soc/chipsea/hals/communication/wifi_lite/wifiservice/wifi_device.c`.
490
491```
492......
493WifiErrorCode Scan(void)
494{
495    WIFI_STATE_INVALID_CHECK(WIFI_INACTIVE);
496
497    int testNum = MEMP_NUM_NETCONN;
498    dbg("testNum %d\r\n", testNum);
499    ChipseaWifiMsg msg = {
500        .eventId = WIFI_START_SCAN,
501        .payLoad = 0,
502    };
503
504    if (WifiCreateLock() != WIFI_SUCCESS) {
505        return ERROR_WIFI_NOT_AVAILABLE;
506    }
507    if (rtos_queue_write(g_wifiData.wifiQueue, &msg, 1, false) != 0) {
508        dbg("wifiDevice:rtos_queue_write err\r\n");
509        WifiUnlock();
510        return ERROR_WIFI_NOT_AVAILABLE;
511    }
512    WifiUnlock();
513    return WIFI_SUCCESS;
514}
515
516......
517int GetSignalLevel(int rssi, int band)
518{
519    if (band == HOTSPOT_BAND_TYPE_2G) {
520        if (rssi >= RSSI_LEVEL_4_2_G)
521            return RSSI_LEVEL_4;
522        if (rssi >= RSSI_LEVEL_3_2_G)
523            return RSSI_LEVEL_3;
524        if (rssi >= RSSI_LEVEL_2_2_G)
525            return RSSI_LEVEL_2;
526        if (rssi >= RSSI_LEVEL_1_2_G)
527            return RSSI_LEVEL_1;
528    }
529
530    if (band == HOTSPOT_BAND_TYPE_5G) {
531        if (rssi >= RSSI_LEVEL_4_5_G)
532            return RSSI_LEVEL_4;
533        if (rssi >= RSSI_LEVEL_3_5_G)
534            return RSSI_LEVEL_3;
535        if (rssi >= RSSI_LEVEL_2_5_G)
536            return RSSI_LEVEL_2;
537        if (rssi >= RSSI_LEVEL_1_5_G)
538            return RSSI_LEVEL_1;
539    }
540    return ERROR_WIFI_INVALID_ARGS;
541}
542
543```
544
545### Kernel Subsystem
546
547For the kernel subsystem, you need to configure the lwIP component closely related to Wi-Fi, use the third-party lwIP component of the community, and specify the directory for adapting the third-party lwIP and Wi-Fi systems.
548
549By default, `lwip` is configured in the `LiteOS-M kernel` directory. Therefore, the compilation function is available. You can specify the `lwip` compilation directory in the `kernel` component. The sample code is as follows:
550
551```
552    {
553      "subsystem": "kernel",
554      "components": [
555        {
556          "component": "liteos_m",
557          "features": [
558             "ohos_kernel_liteos_m_lwip_path = \"//device/soc/chipsea/cst85/liteos_m/sdk/modules/lwip-2.1\""
559		 --- Specify that adaptation is performed in the chip vendor directory.
560          ]
561        }
562      ]
563    },
564```
565
566The `//device/soc/chipsea/cst85/liteos_m/sdk/modules/lwip-2.1/BUILD.gn` file describes the compilation of `lwip` as follows:
567
568```
569import("//kernel/liteos_m/liteos.gni")
570import("$LITEOSTHIRDPARTY/lwip/lwip.gni")
571import("$LITEOSTOPDIR/components/net/lwip-2.1/lwip_porting.gni")
572
573module_switch = defined(LOSCFG_NET_LWIP_SACK)
574module_name = "lwip"
575kernel_module(module_name) {
576  sources = LWIP_PORTING_FILES + LWIPNOAPPSFILES -
577            [ "$LWIPDIR/api/sockets.c" ] + [ "porting/src/ethernetif.c" ]		 --- Add the **ethernetif.c** file for Ethernet network adapter initialization and adaptation.
578  defines = [ "LITEOS_LWIP=1" ]
579  defines += [ "CHECKSUM_BY_HARDWARE=1" ]
580}
581
582config("public") {
583  defines = [ "_BSD_SOURCE=1" ]
584  include_dirs =
585      [ "porting/include" ] + LWIP_PORTING_INCLUDE_DIRS + LWIP_INCLUDE_DIRS
586}
587
588```
589
590In the `//device/soc/chipsea/cst85/liteos_m/sdk/modules/lwip-2.1/porting/include/lwip/lwipopts.h` file, the original `lwip` configuration items remain unchanged, the DSoftBus depends on these configuration items, and a hardware adaptation configuration item is added as follows:
591
592```
593#ifndef _PORTING_LWIPOPTS_H_
594#define _PORTING_LWIPOPTS_H_
595
596#include_next "lwip/lwipopts.h"				 --- Original configuration items remain unchanged.
597
598#define LWIP_NETIF_STATUS_CALLBACK      1
599#define LWIP_CHECKSUM_ON_COPY           0
600#define CHECKSUM_GEN_UDP                0	 --- New hardware adaptation item.
601
602#endif /* _PORTING_LWIPOPTS_H_ */
603
604```
605
606In the `//device/soc/chipsea/cst85/liteos_m/sdk/modules/lwip-2.1/porting/net_al.c` file, the adaptation to the initialization of the `Ethernet` network adapter is described as follows:
607
608```
609static err_t net_if_init(struct netif *net_if)
610{
611    err_t status = ERR_OK;
612    struct fhost_vif_tag *vif = (struct fhost_vif_tag *)net_if->state;
613
614    #if LWIP_NETIF_HOSTNAME
615    {
616        /* Initialize interface hostname */
617        net_if->hostname = "CsWlan";
618    }
619    #endif /* LWIP_NETIF_HOSTNAME */
620
621    net_if->name[ 0 ] = 'w';
622    net_if->name[ 1 ] = 'l';
623
624    net_if->output = etharp_output;
625    net_if->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP;
626    net_if->hwaddr_len = ETHARP_HWADDR_LEN;
627    net_if->mtu = LLC_ETHER_MTU;
628    net_if->linkoutput = net_if_output;
629    memcpy(net_if->hwaddr, &vif->mac_addr, ETHARP_HWADDR_LEN);
630
631    return status;
632}
633
634```
635
636### Startup Subsystem
637
638To run application frameworks such as XTS or APP_FEATURE_INIT, the bootstrap_lite and syspara_lite components of the startup subsystem are adapted.
639
640Add the corresponding configuration items to the `vendor/chipsea/wblink_demo/config.json` file:
641
642```
643{
644  "subsystem": "startup",
645  "components": [
646	{
647	  "component": "bootstrap_lite"		 --- bootstrap_lite component
648	},
649	{
650	  "component": "syspara_lite",		 --- syspara_lite component
651	  "features": [
652		"enable_ohos_startup_syspara_lite_use_posix_file_api = true"
653	  ]
654	}
655  ]
656},
657```
658
659When adapting the **bootstrap_lite** component, you need to manually add the following content to the link script file `//device/soc/chipsea/cst85/liteos_m/sdk/bsp/out/cst85f01/cst85f01.ld`:
660
661```
662       __zinitcall_bsp_start = .;
663      KEEP (*(.zinitcall.bsp0.init))
664      KEEP (*(.zinitcall.bsp1.init))
665      KEEP (*(.zinitcall.bsp2.init))
666      KEEP (*(.zinitcall.bsp3.init))
667      KEEP (*(.zinitcall.bsp4.init))
668      __zinitcall_bsp_end = .;
669      __zinitcall_device_start = .;
670      KEEP (*(.zinitcall.device0.init))
671      KEEP (*(.zinitcall.device1.init))
672      KEEP (*(.zinitcall.device2.init))
673      KEEP (*(.zinitcall.device3.init))
674      KEEP (*(.zinitcall.device4.init))
675      __zinitcall_device_end = .;
676      __zinitcall_core_start = .;
677      KEEP (*(.zinitcall.core0.init))
678      KEEP (*(.zinitcall.core1.init))
679      KEEP (*(.zinitcall.core2.init))
680      KEEP (*(.zinitcall.core3.init))
681      KEEP (*(.zinitcall.core4.init))
682      __zinitcall_core_end = .;
683      __zinitcall_sys_service_start = .;
684      KEEP (*(.zinitcall.sys.service0.init))
685      KEEP (*(.zinitcall.sys.service1.init))
686      KEEP (*(.zinitcall.sys.service2.init))
687      KEEP (*(.zinitcall.sys.service3.init))
688      KEEP (*(.zinitcall.sys.service4.init))
689      __zinitcall_sys_service_end = .;
690      __zinitcall_sys_feature_start = .;
691      KEEP (*(.zinitcall.sys.feature0.init))
692      KEEP (*(.zinitcall.sys.feature1.init))
693      KEEP (*(.zinitcall.sys.feature2.init))
694      KEEP (*(.zinitcall.sys.feature3.init))
695      KEEP (*(.zinitcall.sys.feature4.init))
696      __zinitcall_sys_feature_end = .;
697      __zinitcall_run_start = .;
698      KEEP (*(.zinitcall.run0.init))
699      KEEP (*(.zinitcall.run1.init))
700      KEEP (*(.zinitcall.run2.init))
701      KEEP (*(.zinitcall.run3.init))
702      KEEP (*(.zinitcall.run4.init))
703      __zinitcall_run_end = .;
704      __zinitcall_app_service_start = .;
705      KEEP (*(.zinitcall.app.service0.init))
706      KEEP (*(.zinitcall.app.service1.init))
707      KEEP (*(.zinitcall.app.service2.init))
708      KEEP (*(.zinitcall.app.service3.init))
709      KEEP (*(.zinitcall.app.service4.init))
710      __zinitcall_app_service_end = .;
711      __zinitcall_app_feature_start = .;
712      KEEP (*(.zinitcall.app.feature0.init))
713      KEEP (*(.zinitcall.app.feature1.init))
714      KEEP (*(.zinitcall.app.feature2.init))
715      KEEP (*(.zinitcall.app.feature3.init))
716      KEEP (*(.zinitcall.app.feature4.init))
717      __zinitcall_app_feature_end = .;
718      __zinitcall_test_start = .;
719      KEEP (*(.zinitcall.test0.init))
720      KEEP (*(.zinitcall.test1.init))
721      KEEP (*(.zinitcall.test2.init))
722      KEEP (*(.zinitcall.test3.init))
723      KEEP (*(.zinitcall.test4.init))
724      __zinitcall_test_end = .;
725      __zinitcall_exit_start = .;
726      KEEP (*(.zinitcall.exit0.init))
727      KEEP (*(.zinitcall.exit1.init))
728      KEEP (*(.zinitcall.exit2.init))
729      KEEP (*(.zinitcall.exit3.init))
730      KEEP (*(.zinitcall.exit4.init))
731      __zinitcall_exit_end = .;
732```
733
734Adding the preceding content is because external APIs provided by `bootstrap_init` will be saved to the link segment. For details, see `//utils/native/lite/include/ohos_init.h`.
735
736The following table lists the automatic initialization macros of bootstrap.
737
738| API                | Description                            |
739| ---------------------- | -------------------------------- |
740| SYS_SERVICE_INIT(func) | Entry for initializing and starting a core system service.|
741| SYS_FEATURE_INIT(func) | Entry for initializing and starting a core system feature.|
742| APP_SERVICE_INIT(func) | Entry for initializing and starting an application-layer service.  |
743| APP_FEATURE_INIT(func) | Entry for initializing and starting an application-layer feature.  |
744
745The **lib** file compiled using the loaded components needs to be manually add to the forcible link.
746
747​If the `bootstrap_lite` component is configured in `vendor/chipsea/wblink_demo/config.json`:
748
749```
750    {
751      "subsystem": "startup",
752      "components": [
753        {
754          "component": "bootstrap_lite"
755        },
756        ...
757      ]
758    },
759```
760
761​The `bootstrap_lite` component compiles the `//base/startup/bootstrap_lite/services/source/bootstrap_service.c` file. In this file, `SYS_SERVICE_INIT` is used to inject the `Init` function symbol to `__zinitcall_sys_service_start` and `__zinitcall_sys_service_end`.
762```
763static void Init(void)
764{
765    static Bootstrap bootstrap;
766    bootstrap.GetName = GetName;
767    bootstrap.Initialize = Initialize;
768    bootstrap.MessageHandle = MessageHandle;
769    bootstrap.GetTaskConfig = GetTaskConfig;
770    bootstrap.flag = FALSE;
771    SAMGR_GetInstance()->RegisterService((Service *)&bootstrap);
772}
773SYS_SERVICE_INIT(Init);   --- Forcible link to the generated lib file is required if **SYS_INIT** is used for startup.
774```
775
776In the `//base/startup/bootstrap_lite/services/source/BUILD.gn` file, add the file to the compilation sources.
777
778```
779static_library("bootstrap") {
780  sources = [
781    "bootstrap_service.c",
782    "system_init.c",
783  ]
784  ....
785```
786
787Since the `Init` function does not support explicit calls, you need to forcibly link it to the final image. Configure **ld_flags** in the `device/board/chipsea/cst85_wblink/config.gni` file as follows:
788
789```
790   board_ld_flags += [
791    "-Wl,--whole-archive",
792    "-lexample",
793    "-lhiview_lite",
794    "-lhilog_lite",
795    "-lhievent_lite",
796    "-lbroadcast",
797    "-lbootstrap",
798    "-Wl,--no-whole-archive",
799  ]
800
801```
802
803### Utils Subsystem
804
805To adapt the `utils` subsystem, you need to add the `kv_store`, `js_builtin`, `timer_task`, and `kal_timer` components to the `config.json` file.
806
807```
808{
809  "subsystem": "utils",
810  "components": [
811	{
812	  "component": "kv_store",
813	  "features": [
814		"enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true"
815	  ]
816	},
817
818  ]
819},
820```
821
822Similar to the adaptation of the `syspara_lite` component, when the `kv_store` component is adapted, the key-value pair is written to the file. In the mini system, file operation APIs include `POSIX` and `HalFiles`. For access to the file system in the kernel, use the `POSIX` API, which means you need to add `enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true` to the `features` field. If you are using the `HalFiles` API, no modification is required.
823
824
825### XTS Subsystem
826
827For the adaptation to the XTS subsystem, for example, `//vendor/chipsea/xts_demo/config.json`, you need to add the following component options:
828
829```
830"subsystem": "xts",
831"components": [
832  { "component": "xts_acts", "features":
833    [
834	  "config_ohos_xts_acts_utils_lite_kv_store_data_path = \"/data\"",
835      "enable_ohos_test_xts_acts_use_thirdparty_lwip = true"
836    ]
837  },
838  { "component": "xts_tools", "features":[] }
839]
840```
841The XTS lib needs to be forcibly linked in `device/board/chipsea/cst85_wblink/liteos_m/config.gni`.
842
843```
844 board_ld_flags += [
845    "-Wl,--whole-archive",
846     "-lhctest",
847     "-lmodule_ActsParameterTest",
848     "-lmodule_ActsBootstrapTest",
849     "-lmodule_ActsDfxFuncTest",
850     "-lmodule_ActsKvStoreTest",
851     "-lmodule_ActsSamgrTest",
852     "-lmodule_ActsWifiServiceTest",
853     "-lmodule_ActsDsoftbusMgrTest",
854 ]
855```
856