• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Mini System STM32F407 SoC Porting Case
2
3This document describes how to port the OpenHarmony LiteOS-M mini system on the Talkweb [Niobe407](https://gitee.com/openharmony-sig/device_board_talkweb) development board based on the `STM32F407IGT6` chip, to provide development board solutions for transportation and industrial fields. The porting architecture uses the `Board` and `SoC` separation solution and the `Newlib C` library of the `arm gcc` toolchain to implement adaptation of subsystems and components such as `lwip`, `littlefs`, and `hdf`. The matching application sample code is developed to support graphical configuration of compilation options through KConfig.
4
5## Preparing for Adaptation
6
7- Download the graphic tool [stm32cubemx](https://www.st.com/en/development-tools/stm32cubemx.html).
8- Prepare the Ubuntu 20.04 system environment and install the [arm-none-eabi-gcc](https://gitee.com/openharmony/device_board_talkweb/blob/master/niobe407/docs/software/%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%E4%B8%8E%E5%9B%BA%E4%BB%B6%E7%BC%96%E8%AF%91.md#6%E5%AE%89%E8%A3%85%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91%E5%B7%A5%E5%85%B7%E9%93%BE) cross compilation toolchain.
9### Generating an Available Project
10
11Generate the Makefile project of the `STM32F407IGT6` chip by using the STM32CubeMX tool. You are advised to complete configurations as follows:
12
13- Retain the default system settings.
14- Set **SYSCLK** to 168 MHz in the clock configuration, to maximize the chip performance.
15- Configure USART1 as the debugging serial port, to generate debugging information during adaptation.
16- Set **Toolchain/IDE** to **Makefile** in STM32CubeMX configurations.
17
18The generated project directory is as follows:
19
20```
21├── Core
22│   ├── Inc
23│   │    ├── main.h
24│   │    ├── stm32f4xx_hal_conf.h
25│   │    └── stm32f4xx_it.h
26│   └── Src
27│        ├── main.c                --- Main function
28│        ├── stm32f4xx_hal_msp.c   --- Weak function configuration file in the HAL library
29│        ├── stm32f4xx_it.c        --- Interrupt callback function file
30│        └── system_stm32f4xx.c    --- System
31├── Drivers
32│   ├── CMSIS                      --- CMSIS API
33│   └── STM32F4xx_HAL_Driver       --- HAL library driver
34├── Makefile                       --- Makefile compilation
35├── STM32F407IGTx_FLASH.ld         --- Link file
36├── startup_stm32f407xx.s          --- Startup file
37└── stm32f407_output.ioc           --- STM32CubeMX project file
38```
39
40### Verifying the Generated Project
41
42Copy the generated project to Ubuntu, go to the project directory, and run the **make** command to compile the project. Ensure that the compilation is successful.
43
44```
45arm-none-eabi-gcc build/main.o build/stm32f4xx_it.o build/stm32f4xx_hal_msp.o build/stm32f4xx_hal_tim.o build/stm32f4xx_hal_tim_ex.o build/stm32f4xx_hal_uart.o build/stm32f4xx_hal_rcc.o build/stm32f4xx_hal_rcc_ex.o build/stm32f4xx_hal_flash.o build/stm32f4xx_hal_flash_ex.o build/stm32f4xx_hal_flash_ramfunc.o build/stm32f4xx_hal_gpio.o build/stm32f4xx_hal_dma_ex.o build/stm32f4xx_hal_dma.o build/stm32f4xx_hal_pwr.o build/stm32f4xx_hal_pwr_ex.o build/stm32f4xx_hal_cortex.o build/stm32f4xx_hal.o build/stm32f4xx_hal_exti.o build/system_stm32f4xx.o build/startup_stm32f407xx.o -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -specs=nano.specs -TSTM32F407IGTx_FLASH.ld  -lc -lm -lnosys  -Wl,-Map=build/stm32f407_output.map,--cref -Wl,--gc-sections -o build/stm32f407_output.elf
46arm-none-eabi-size build/stm32f407_output.elf
47   text    data     bss     dec     hex filename
48   5000      20    1636    6656    1a00 build/stm32f407_output.elf
49arm-none-eabi-objcopy -O ihex build/stm32f407_output.elf build/stm32f407_output.hex
50arm-none-eabi-objcopy -O binary -S build/stm32f407_output.elf build/stm32f407_output.bin
51```
52
53After the compilation is complete, a .bin file is generated. To ensure that the program can run successfully on the development board, you need to initialize the serial port in the main function and output a string through the serial port. If the following information is generated during running, the development board is started successfully:
54```
55printf("hello world!!\r\n");
56```
57
58To generate logs using the **printf** function to the serial port, override the **_write** function. The sample code is as follows:
59
60```c
61#include <stdio.h>
62
63int _write(int fd, char *ptr, int len)
64{
65      return HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, 0xFFFF);
66}
67```
68Recompile the code and burn it to the development board for verification.
69
70## Compilation and Building
71### Directory Planning
72
73The chip adaptation directory is planned as follows:
74
75```
76device
77├── board                                --- Board vendor directory
78│   └── talkweb                          --- Board vendor: Talkweb
79│       └── niobe407                     --- Board name, which is the same as the product name
80└── soc									 --- SoC vendor directory
81    └── st                               --- SoC vendor
82        └── stm32f4xx					 --- SoC series: STM32F4xx, including SoC code
83```
84
85The planned product demo directory is as follows:
86
87```
88vendor
89└── talkweb							     --- Vendor of the product sample
90    └── niobe407         			     --- Product name: niobe407
91```
92
93Obtain the [OpenHarmony source code](../get-code/sourcecode-acquire.md) and create directories as planned.
94
95### Precompilation Adaptation
96
97This part describes adaptation using the `hb set` command to set environment variables such as the root directory, board directory, product directory, and board vendor, for subsequent adaptation compilation.
98
99To be specific:
100
1011. Add the `config.json` file to the `vendor/talkweb/niobe407` directory to describe the board and kernel information used by the product sample. The sample code is as follows:
102
103```
104{
105  "product_name": "niobe407",           --- Product name displayed when using the **hb set** command.
106  "type": "mini",                       --- System type, which can be mini, small, or standard.
107  "version": "3.0",                     --- Version of the system, which can be 1.0, 2.0, or 3.0.
108  "device_company": "talkweb",          --- Board vendor name, which is used to find the **/device/board/talkweb** directory during compilation.
109  "board": "niobe407",                  --- Board name, which is used to find the **/device/board/talkweb/niobe407** directory during compilation.
110  "kernel_type": "liteos_m",            --- Kernel type. The OpenHarmony supports multiple kernels, and one board may adapt multiple kernels. Therefore, you need to specify a kernel for compilation.
111  "kernel_version": "3.0.0",            --- Kernel version. One board may adapt multiple Linux kernel versions. Therefore, you need to specify a kernel version for compilation.
112  "subsystems": [ ]                     --- Subsystem to be built.
113}
114```
115
1162. Create the `board` directory under `//device/board/talkweb/niobe407` and add the `config.gni` file to the created directory to describe the compilation configuration information of the product.
117
118```
119# Kernel type, e.g. "linux", "liteos_a", "liteos_m".
120kernel_type = "liteos_m"                --- Kernel type, which corresponds to **kernel_type** in **config.json**.
121
122# Kernel version.
123kernel_version = "3.0.0"                --- Kernel version, which corresponds to **kernel_version** in **config.json**.
124```
125
1263. Check whether the `hb set` configuration is correct. If the following information is displayed after you enter `hb set`, the configuration is correct.
127
128 ![hb set](figures/niobe407_hb_set.png)
129
1304. Run the `hb env` command to view the selected precompilation environment variables.
131
132 ![hb env](figures/niobe407_hb_env.png)
133
1345. Introduction to **hb**
135
136   `hb` is a Python script tool provided by OpenHarmony to facilitate code building and compilation. The source code of `hb` is stored in the `//build/lite` repository directory. When the `hb set` command is executed, the script traverses `config.json` in the `//vendor/<product_company>/<product_name>` directory and provides product compilation options. In the **config.json** file, `product_name` indicates the product name, and `device_company` and `board` are used to associate the `//device/board/<device_company>/<board>` directory and match the `<any_dir_name>/config.gni` file in the directory. The `<any_dir_name>` directory name can be any name, however, you are advised to name it as the adapted kernel name (for example, **liteos_m**, **liteos_a**, or **linux**). If multiple `config.gni` files are matched, the **hb** command matches the `kernel_type` and `kernel_version` fields with the fields in the `config.json` file in `vendor/<device_company>` to determine the `config.gni` file to be compiled.
137
138So far, the precompilation adaptation is complete. However, the project cannot be compiled by running `hb build`. You need to prepare for the subsequent `LiteOS-M` kernel porting.
139
140## Kernel Porting
141
142Kernel porting requires `LiteOS-M Kconfig` adaptation, `gn` compilation and building, and minimum kernel startup adaptation.
143
144### Kconfig File Adaptation
145
1461. Create the **kernel_configs** directory in `//vendor/talkweb/niobe407` and create an empty file named **debug.config**.
147
1482. Open the `//kernel/liteos_m/Kconfig` file. Multiple Kconfig files in `//device/board` and `//device/soc` have been imported using the **orsource** command. You need to create and modify these files later.
149
150```
151orsource "../../device/board/*/Kconfig.liteos_m.shields"
152orsource "../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.defconfig.boards"
153orsource "../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.boards"
154orsource "../../device/soc/*/Kconfig.liteos_m.defconfig"
155orsource "../../device/soc/*/Kconfig.liteos_m.series"
156orsource "../../device/soc/*/Kconfig.liteos_m.soc"
157```
158
1593. Create the Kconfig files in `//device/board/talkweb` by referring to the following directory structure:
160
161```
162.
163├── Kconfig.liteos_m.boards
164├── Kconfig.liteos_m.defconfig.boards
165├── Kconfig.liteos_m.shields
166└── niobe407
167    ├── Kconfig.liteos_m.board                --- Board configuration items
168    ├── Kconfig.liteos_m.defconfig.board      --- Default board configuration items
169    └── liteos_m
170        └── config.gni
171```
172
1734. Modify the `Kconfig` files.
174
175   - Add the following information to the `//device/board/talkweb/Kconfig.liteos_m.boards` file:
176
177     ```
178     if SOC_STM32F407
179            orsource "niobe407/Kconfig.liteos_m.board"    --- Load the definition of the specified board directory based on SoC definitions.
180     endif
181     ```
182
183   - Add the following information to the `//device/board/talkweb/Kconfig.liteos_m.defconfig.boards` file:
184
185     ```
186     orsource "*/Kconfig.liteos_m.defconfig.board"
187     ```
188
189   - Add the following information to the `//device/board/talkweb/Kconfig.liteos_m.defconfig.boards` file:
190
191     ```
192     orsource "shields/Kconfig.liteos_m.shields"
193     ```
194
195   - Add the following information to the `//device/board/talkweb/niobe407/Kconfig.liteos_m.board` file:
196
197     ```
198     menuconfig BOARD_NIOBE407
199         bool "select board niobe407"
200         depends on SOC_STM32F407	 --- niobe407 uses the SoC of STM32F407. Only when the SoC is selected, the configuration items of niobe407 are available and can be selected.
201     ```
202
203   - Add the following information to the `//device/board/talkweb/niobe407/Kconfig.liteos_m.defconfig.board` file:
204
205     ```
206     if BOARD_NIOBE407
207         							 --- Used to add the default configuration of BOARD_NIOBE407.
208     endif #BOARD_NIOBE407
209     ```
210
2115. Create Kconfig files in the `//device/soc/st` directory by referring to the following directory structure, and copy the **Drivers** directory in the project generated by `STM32CubeMX` to the `stm32f4xx/sdk` directory.
212
213   ```
214   .
215   ├── Kconfig.liteos_m.defconfig
216   ├── Kconfig.liteos_m.series
217   ├── Kconfig.liteos_m.soc
218   └── stm32f4xx
219       ├── Kconfig.liteos_m.defconfig.series
220       ├── Kconfig.liteos_m.defconfig.stm32f4xx
221       ├── Kconfig.liteos_m.series
222       ├── Kconfig.liteos_m.soc
223       └── sdk
224           └── Drivers
225               ├── CMSIS
226               └── STM32F4xx_HAL_Driver
227   ```
228
2296. Modify the Kconfig files.
230
231   - Add the following information to the `//device/soc/st/Kconfig.liteos_m.defconfig` file:
232
233     ```
234     rsource "*/Kconfig.liteos_m.defconfig.series"
235     ```
236
237   - Add the following information to the `//device/soc/st/Kconfig.liteos_m.series` file:
238
239     ```
240     rsource "*/Kconfig.liteos_m.series"
241     ```
242
243   - Add the following information to the `//device/soc/st/Kconfig.liteos_m.soc` file:
244
245     ```
246     config SOC_COMPANY_STMICROELECTRONICS
247         bool
248     if SOC_COMPANY_STMICROELECTRONICS
249     config SOC_COMPANY
250         default "st"
251     rsource "*/Kconfig.liteos_m.soc"
252     endif # SOC_COMPANY_STMICROELECTRONICS
253     ```
254
255   - Add the following information to the `//device/soc/st/stm32f4xx/Kconfig.liteos_m.defconfig.series` file:
256
257     ```
258     if SOC_SERIES_STM32F4xx
259     rsource "Kconfig.liteos_m.defconfig.stm32f4xx"
260     config SOC_SERIES
261         string
262         default "stm32f4xx"
263     endif
264     ```
265
266   - Add the following information to the `//device/soc/st/stm32f4xx/Kconfig.liteos_m.defconfig.stm32f4xx` file:
267
268     ```
269     config SOC
270         string
271         default "stm32f4xx"
272         depends on SOC_STM32F4xx
273     ```
274
275   - Add the following information to the `//device/soc/st/stm32f4xx/Kconfig.liteos_m.series` file:
276
277     ```
278     config SOC_SERIES_STM32F4xx
279         bool "STMicroelectronics STM32F4xx series"
280         select ARCH_ARM
281         select SOC_COMPANY_STMICROELECTRONICS
282         select CPU_CORTEX_M4
283         help
284             Enable support for STMicroelectronics STM32F4xx series
285     ```
286
287   - Add the following information to the `//device/soc/st/stm32f4xx/Kconfig.liteos_m.soc` file:
288
289     ```
290     choice
291         prompt "STMicroelectronics STM32F4xx series SoC"
292         depends on SOC_SERIES_STM32F4xx
293     config SOC_STM32F407
294         bool "SoC STM32F407"
295     endchoice
296     ```
297
2987. Run the `make menuconfig` command in the `kernel/liteos_m` directory to select `SoC Series`.
299
300    ![board make menuconfig](figures/niobe407_menuconfig.png)
301
302   The result is automatically saved in `$(PRODUCT_PATH)/kernel_configs/debug.config`. The saved result will be exported when you run the `make menuconfig` command next time.
303
304### BUILD.gn File Adaptation
305
306To quickly get familiar with **gn** compilation and adaptation, you are advised to read [LiteOS-M Kernel BUILD.gn Compilation Guide](https://gitee.com/caoruihong/kernel_liteos_m/wikis/LiteOS-M%E5%86%85%E6%A0%B8BUILD.gn%E7%BC%96%E5%86%99%E6%8C%87%E5%8D%97).
307
308**(Note that no tab is allowed in the BUILD.gn file. All tabs are replaced with spaces.)**
309
3101. In `kernel/liteos_m/BUILD.gn`, see that the compilation entries of `Board` and `SoC` are specified through `deps`.
311
312   ```
313   deps += [ "//device/board/$device_company" ]            --- Corresponds to **//device/board/talkweb**.
314   deps += [ "//device/soc/$LOSCFG_SOC_COMPANY" ]          --- Corresponds to **//device/soc/st**.
315   ```
316
3172. Add the following information to the `//device/board/talkweb/BUILD.gn` file:
318
319   ```
320   if (ohos_kernel_type == "liteos_m") {
321       import("//kernel/liteos_m/liteos.gni")
322       module_name = get_path_info(rebase_path("."), "name")
323       module_group(module_name) {
324          modules = [ "niobe407" ]
325       }
326   }
327   ```
328
3293. Create a **BUILD.gn** file in the **niobe407** directory. To facilitate management, use the directory name as the module name.
330
331   ```
332   import("//kernel/liteos_m/liteos.gni")
333   module_name = get_path_info(rebase_path("."), "name")
334   module_group(module_name) {
335       modules = [
336       	"liteos_m",
337       ]
338   }
339   ```
340
3414. Copy the files in the **Core** directory of the sample project generated by STM32CubeMX, `startup_stm32f407xx.s`, and `STM32F407IGTx_FLASH.ld` link file to the `//device/board/talkweb/niobe407/liteos_m/` directory, create `BUILD.gn` in the directory, and add the following content:
342
343   ```
344   import("//kernel/liteos_m/liteos.gni")
345   module_name = get_path_info(rebase_path("."), "name")
346   kernel_module(module_name) {
347       sources = [
348           "startup_stm32f407xx.s",
349           "Src/main.c",
350           "Src/stm32f4xx_hal_msp.c",
351           "Src/stm32f4xx_it.c",
352           "Src/system_stm32f4xx.c",
353       ]
354       include_dirs = [
355           "Inc",
356       ]
357   }
358
359   config("public") {
360       ldflags = [
361           "-Wl,-T" + rebase_path("STM32F407IGTx_FLASH.ld"),
362           "-Wl,-u_printf_float",
363       ]
364       libs = [
365           "c",
366           "m",
367           "nosys",
368       ]
369   }
370   ```
371
3725. Configure `(Top) → Compat → Choose libc implementation` in **make menuconfig** and select `newlibc`.
373
3746. The **\_write** function has the same name as the kernel file operation function. As a result, the compilation fails. Use another method to adapt the **printf** function. In this example, the **_write** function is deleted from the **main.c** file, and the **printf** function is used to perform the serial port printing test as follows:
375
376   ```
377   uint8_t test[]={"hello niobe407!!\r\n"};
378   int len = strlen(test);
379   HAL_UART_Transmit(&huart1, (uint8_t *)test, len, 0xFFFF);
380   ```
381
3827. The same is true for `//device/soc/st/BUILD.gn`. The file is included layer by layer based on the directory structure. The file to be compiled and compilation parameters are specified in `//device/soc/st/stm32f4xx/sdk/BUILD.gn` using the `kernel_module` template. The following is an example:
383
384   ```
385   import("//kernel/liteos_m/liteos.gni")
386   module_name = "stm32f4xx_sdk"
387   kernel_module(module_name) {
388     asmflags = board_asmflags
389     sources = [
390       "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c",
391       "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c",
392       "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c",
393       "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c",
394       "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c",
395       "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c",
396       "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c",
397       "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c",
398       "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c",
399     ]
400   }
401   #Specify the global header file search path.
402   config("public") {
403       include_dirs = [
404           "Drivers/STM32F4xx_HAL_Driver/Inc",
405           "Drivers/CMSIS/Device/ST/STM32F4xx/Include",
406       ]
407   }
408   ```
409
410### config.gni File Adaptation
411
412In the precompilation phase, the **config.gni** file is created in the `//device/board/talkweb/niobe407/liteos_m` directory. The **config.gni** file is the header file of the GN script and can be regarded as the global configuration file for project building. The file contains important information such as the CPU model, cross compilation toolchain, global compilation, and link parameters.
413
414```
415# Kernel type, e.g. "linux", "liteos_a", "liteos_m".
416kernel_type = "liteos_m"
417
418# Kernel version.
419kernel_version = "3.0.0"
420
421# Board CPU type, e.g. "cortex-a7", "riscv32".
422board_cpu = "cortex-m4"
423
424# Board arch, e.g.  "armv7-a", "rv32imac".
425board_arch = ""
426
427# Toolchain name used for system compiling.
428# E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang,  riscv32-unknown-elf.
429# Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toolchain.
430board_toolchain = "arm-none-eabi-gcc"
431
432use_board_toolchain = true
433
434# The toolchain path installed, it's not mandatory if you have added toolchain path to your ~/.bashrc.
435board_toolchain_path = ""
436
437# Compiler prefix.
438board_toolchain_prefix = "arm-none-eabi-"
439
440# Compiler type, "gcc" or "clang".
441board_toolchain_type = "gcc"
442
443#Debug compiler optimization level options
444board_opt_flags = [
445    "-mcpu=cortex-m4",
446    "-mthumb",
447    "-mfpu=fpv4-sp-d16",
448    "-mfloat-abi=hard",
449]
450
451# Board related common compile flags.
452board_cflags = [
453    "-Og",
454    "-Wall",
455    "-fdata-sections",
456    "-ffunction-sections",
457    "-DSTM32F407xx",
458]
459board_cflags += board_opt_flags
460
461board_asmflags = [
462    "-Og",
463    "-Wall",
464    "-fdata-sections",
465    "-ffunction-sections",
466]
467board_asmflags += board_opt_flags
468
469board_cxx_flags = board_cflags
470
471board_ld_flags = board_opt_flags
472
473# Board related headfiles search path.
474board_include_dirs = [ "//utils/native/lite/include" ]
475
476# Board adapter dir for OHOS components.
477board_adapter_dir = ""
478```
479
480The settings of parameters such as **board_opt_flags**, **board_cflags**, and **board_asmflags** are defined as follows. You can extract the parameters from the `Makefile` file in the project generated by STM32CubeMX by referring to the following:
481```
482**board_opt_flags**: compiler-related options, such as the chip architecture, floating-point type, and compilation debugging optimization level.
483**board_asmflags**: assembly compilation options, corresponding to the **ASFLAGS** variable in **Makefile**.
484**board_cflags**: C code compilation options, corresponding to the **CFLAGS** variable in **Makefile**.
485**board_cxx_flags**: C++ code compilation options, corresponding to the **CXXFLAGS** variable in **Makefile**.
486**board_ld_flags**: link options, corresponding to the **LDFLAGS** variable in **Makefile**.
487```
488
489### Kernel Subsystem Adaptation
490
491Add the kernel subsystem and related configurations to the `//vendor/talkweb/niobe407/config.json` file as follows:
492
493```
494{
495    "product_name": "niobe407",
496    "type": "mini",
497    "version": "3.0",
498    "device_company": "talkweb",
499    "board": "niobe407",
500    "kernel_type": "liteos_m",
501    "kernel_version": "3.0.0",
502    "subsystems": [
503        {
504            "subsystem": "kernel",
505            "components": [
506                {
507                    "component": "liteos_m"
508                }
509            ]
510        }
511    ],
512    "product_adapter_dir": "",
513    "third_party_dir": "//third_party"
514}
515```
516
517### config.gni File Adaptation
518
519The `//kernel/liteos_m/kernel/include/los_config.h` file contains a header file named **target_config.h**. If this header file does not exist, a compilation error occurs.
520
521This header file is used to define macros related to the SoC. You can create an empty header file and determine the macros to be defined based on the compilation error message. It has been verified that the kernel can be compiled successfully after the `LOSCFG_BASE_CORE_TICK_RESPONSE_MAX` macro is defined and the `stm32f4xx.h` header file is included for Cortex-M4 core adaptation.
522
523If you do not know how to configure, see the `//device/qemu/arm_mps2_an386/liteos_m/board/target_config.h` configuration in the VM QEMU example.
524
525```
526#ifndef _TARGET_CONFIG_H
527#define _TARGET_CONFIG_H
528
529#define LOSCFG_BASE_CORE_TICK_RESPONSE_MAX                  0xFFFFFFUL
530#include "stm32f4xx.h"			// Contains a large number of macro definitions of the STM32f4.
531
532#endif
533```
534
535The macro definition `LOSCFG_BASE_CORE_TICK_RESPONSE_MAX` is the configuration in the `//device/qemu/arm_mps2_an386/liteos_m/board/target_config.h` file, and `//device/qemu/arm_mps2_an386` is the VM project of `cortex-m4`. These can be used as references.
536
537### Kernel Startup Adaptation
538
539The kernel subsystem is compiled successfully, and the **OHOS_Image.bin** file is generated in the **out** directory. Burn the generated **OHOS_Image.bin** file to the development board to check whether the board can start and run properly. If the correct information output by the serial port in the main function can be printed, start kernel startup adaptation.
540
5411. Allocate memory for **liteos_m** and adapt the memory allocation function.
542
543   In the `//kernel/liteos_m/kernel/src/mm/los_memory.c` file, the `OsMemSystemInit` function initializes the memory through LOS_MemInit. Several key macros need to be specified. Add them to `target_config.h`.
544
545   ```
546   extern unsigned int __los_heap_addr_start__;
547   extern unsigned int __los_heap_addr_end__;
548   #define LOSCFG_SYS_EXTERNAL_HEAP 1
549   #define LOSCFG_SYS_HEAP_ADDR ((void *)&__los_heap_addr_start__)
550   #define LOSCFG_SYS_HEAP_SIZE (((unsigned long)&__los_heap_addr_end__) - ((unsigned long)&__los_heap_addr_start__))
551   ```
552
553   The `__los_heap_addr_start__` and `__los_heap_addr_end__` variables are defined in the `STM32F407IGTx_FLASH.ld` link file. Change the content in the braces of **_user_heap_stack** to the following:
554
555   ```
556   ._user_heap_stack :
557   {
558       . = ALIGN(0x40);
559       __los_heap_addr_start__ = .;
560       __los_heap_addr_end__ = ORIGIN(RAM) + LENGTH(RAM);
561   } >RAM
562   ```
563
564   In addition, adapt the memory allocation function. The memory allocation functions such as **_malloc_r** have been implemented in the kernel, so you need to replace the memory allocation function in the standard library with that in the kernel. Modify the **board_ld_flags** variable in `//device/board/talkweb/niobe407/liteos_m/config.gni` as follows:
565
566   ```
567   board_ld_flags = [
568       "-Wl,--wrap=_calloc_r",
569       "-Wl,--wrap=_malloc_r",
570       "-Wl,--wrap=_realloc_r",
571       "-Wl,--wrap=_reallocf_r",
572       "-Wl,--wrap=_free_r",
573       "-Wl,--wrap=_memalign_r",
574       "-Wl,--wrap=_malloc_usable_size_r",
575   ]
576   board_ld_flags += board_opt_flags
577   ```
578
5792. printf Function Adaptation
580
581   To facilitate subsequent debugging, the **printf** function needs to be adapted first. Only simple adaptation is performed here. For details, see the source code of other development boards.
582
583   Create the **dprintf.c** file in the same directory as **main.c**. The file content is as follows:
584
585   ```
586   #include <stdarg.h>
587   #include "los_interrupt.h"
588   #include <stdio.h>
589
590   extern UART_HandleTypeDef huart1;
591
592   INT32 UartPutc(INT32 ch, VOID *file)
593   {
594       char RL = '\r';
595       if (ch =='\n') {
596           HAL_UART_Transmit(&huart1, &RL, 1, 0xFFFF);
597       }
598       return HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
599   }
600
601   static void dputs(char const *s, int (*pFputc)(int n, FILE *cookie), void *cookie)
602   {
603       unsigned int intSave;
604
605       intSave = LOS_IntLock();
606       while (*s) {
607           pFputc(*s++, cookie);
608       }
609       LOS_IntRestore(intSave);
610   }
611
612   int printf(char const  *fmt, ...)
613   {
614       char buf[1024] = { 0 };
615       va_list ap;
616       va_start(ap, fmt);
617       int len = vsnprintf_s(buf, sizeof(buf), 1024 - 1, fmt, ap);
618       va_end(ap);
619       if (len > 0) {
620           dputs(buf, UartPutc, 0);
621       } else {
622           dputs("printf error!\n", UartPutc, 0);
623       }
624       return len;
625   }
626   ```
627
628   Add the **dprintf.c** file to the **BUILD.gn** script for compilation.
629
630   ```
631   kernel_module(module_name) {
632       sources = [
633           "startup_stm32f407xx.s",
634       ]
635
636       sources += [
637           "Src/main.c",
638           "Src/dprintf.c",
639           "Src/stm32f4xx_hal_msp.c",
640           "Src/stm32f4xx_it.c",
641           "Src/system_stm32f4xx.c",
642       ]
643   }
644   ```
645
646   After the serial port is initialized, use the **printf** function to generate information and test whether the adaptation is successful.
647
6483. Call **LOS_KernelInit** to initialize the kernel and enter task scheduling.
649
650   After the serial port is initialized in the main function, call `LOS_KernelInit` for kernel initialization, create a task instance, and start task scheduling.
651
652   ```
653   #include "los_task.h"
654
655   UINT32 ret;
656   ret = LOS_KernelInit();  // Initialize the kernel.
657   if (ret == LOS_OK) {
658       TaskSample();  // Sample task function, in which a thread task is created.
659       LOS_Start();   // Start task scheduling. Program execution is blocked here, and the kernel takes over the scheduling.
660   }
661   ```
662
663   The content of the `TaskSample()` function is as follows:
664
665   ```
666   VOID TaskSampleEntry2(VOID)
667   {
668       while (1) {
669           printf("TaskSampleEntry2 running...\n");
670           (VOID)LOS_TaskDelay(2000); /* 2000 millisecond */
671       }
672   }
673
674   VOID TaskSampleEntry1(VOID)
675   {
676       while (1) {
677           printf("TaskSampleEntry1 running...\n");
678           (VOID)LOS_TaskDelay(2000); /* 2000 millisecond */
679       }
680   }
681   VOID TaskSample(VOID)
682   {
683       UINT32 uwRet;
684       UINT32 taskID1;
685       UINT32 taskID2;
686       TSK_INIT_PARAM_S stTask = {0};
687
688       stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry1;
689       stTask.uwStackSize = 0x1000;
690       stTask.pcName = "TaskSampleEntry1";
691       stTask.usTaskPrio = 6; /* Os task priority is 6 */
692       uwRet = LOS_TaskCreate(&taskID1, &stTask);
693       if (uwRet != LOS_OK) {
694           printf("Task1 create failed\n");
695       }
696
697       stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry2;
698       stTask.uwStackSize = 0x1000;
699       stTask.pcName = "TaskSampleEntry2";
700       stTask.usTaskPrio = 7; /* Os task priority is 7 */
701       uwRet = LOS_TaskCreate(&taskID2, &stTask);
702       if (uwRet != LOS_OK) {
703           printf("Task2 create failed\n");
704       }
705   }
706   ```
707
708After the kernel startup is adapted, you can view the following information generated by serial port debugging:
709
710 ![niobe407_boot](figures/niobe407_boot.png)
711
712In the future, detailed adaptation verification needs to be performed on the entire basic kernel.
713
714### Basic Kernel Function Adaptation
715
716The adaptation items of basic kernel functions include [interrupt management](../kernel/kernel-mini-basic-interrupt.md), [task management](../kernel/kernel-mini-basic-task.md), [memory management](../kernel/kernel-mini-basic-memory.md), [kernel communication mechanism] (../kernel/kernel-mini-basic-ipc-event.md), [time management](../kernel/kernel-mini-basic-time.md), and [software timer](../kernel/kernel-mini-basic-soft.md). You can verify basic kernel functions by referring to the programming samples in the links. If any problem is found during the verification, perform specific adaptation.
717
718According to the information generation interval in the previous section, the delay time of the `LOS_TaskDelay` function is inaccurate. You can define the following macros in `target_config.h` to adapt the kernel clock:
719
720  ```
721  #define OS_SYS_CLOCK                                        168000000
722  #define LOSCFG_BASE_CORE_TICK_PER_SECOND                    (1000UL)
723  ```
724Most adaptation methods of other basic kernel functions are based on the macro definition in `target_config.h`. You need to explore the adaptation methods based on the source code in `//kernel/liteos_m`.
725
726## Porting and Adaptation of LittleFS
727
728 The `Niobe407` development board is connected to an external 16 MB SPI flash. The Niobe407 performs LittleFS adaptation based on the SPI flash.
729
730The kernel has adapted LittleFS. You only need to enable the configuration in Kconfig files and adapt the following LittleFS APIs:
731
732```
733  int32_t LittlefsRead(const struct lfs_config *cfg, lfs_block_t block,
734                          lfs_off_t off, void *buffer, lfs_size_t size)
735  {
736      W25x_BufferRead(buffer, cfg->context + cfg->block_size * block + off, size);
737      return LFS_ERR_OK;
738  }
739
740  int32_t LittlefsProg(const struct lfs_config *cfg, lfs_block_t block,
741                          lfs_off_t off, const void *buffer, lfs_size_t size)
742  {
743      W25x_BufferWrite((uint8_t *)buffer,cfg->context + cfg->block_size * block + off,size);
744      return LFS_ERR_OK;
745  }
746
747  int32_t LittlefsErase(const struct lfs_config *cfg, lfs_block_t block)
748  {
749     W25x_SectorErase(cfg->context + cfg->block_size * block);
750     return LFS_ERR_OK;
751  }
752
753  int32_t LittlefsSync(const struct lfs_config *cfg)
754  {
755      return LFS_ERR_OK;
756  }
757```
758
759Functions such as `W25x_BufferRead` are APIs for SPI flash reading and writing. The implementation varies according to the SPI flash model. For details about the implementation of the SPI flash operation of Niobe407, please refer to `//device/board/talkweb/niobe407/liteos_m/drivers/spi_flash/src/w25qxx.c`.
760
761The SPI uses the HDF, and LittleFS depends on the SPI driver. To facilitate the configuration of the file system, you can add the LittleFS configuration to the .hcs file. For details, please refer to the `//device/board/talkweb/niobe407/liteos_m/hdf_config/hdf_littlefs.hcs` file.
762
763```
764misc {
765        littlefs_config {
766            match_attr = "littlefs_config";
767            mount_points = ["/talkweb"];
768            partitions = [0x800000];
769            block_size = [4096];
770            block_count = [256];
771        }
772}
773```
774
775## Board-Level Driver Porting
776
777Driver adaptation files are stored in `//drivers/adapter/platform`, including `gpio`, `i2c`, `pwm`, `spi`, `uart`, and `watchdog` drivers. These files are loaded using the `HDF` mechanism. This section uses `pwm` as an example.
778
779### PWM Driver Adaptation
780In the Hardware Driver Foundation (HDF), the PWM module uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device.
781
782- API Description
783
784  ```
785  1. pwm open initialization function: DevHandle PwmOpen(uint32_t num);
786      Parameters:
787          **num**: PWM device ID.
788          **return**: PWM device handle if the operation is successful; **NULL** otherwise.
789  2. pwm close deinitialization function: void PwmClose(DevHandle handle);
790      Parameters:
791          **handle**: PWM device handle.
792          **return**: none
793  3. PWM device parameter set function: int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config);
794      Parameters:
795          **handle**: PWM device handle.
796          ***config**: parameter pointer.
797          **return**: **0** if the setting is successful; negative number otherwise.
798  ```
799
800- PWM HDF HCS Configuration File Parsing
801
802  The `device_info.hcs` file is stored in `//device/board/talkweb/niobe407/liteos_m/hdf_config/device_info.hcs`. The following example shows how to use the TIM2, TIM3, and TIM7 timers to output PWM signals:
803
804    ```
805    device_pwm1 :: device {
806        pwm1 :: deviceNode {
807            policy = 2;
808            priority = 100;
809            moduleName = "ST_HDF_PLATFORM_PWM";
810            serviceName = "HDF_PLATFORM_PWM_1";
811            deviceMatchAttr = "config_pwm1";
812        }
813    }
814    device_pwm2 :: device {
815        pwm2 :: deviceNode {
816            policy = 2;
817            priority = 100;
818            moduleName = "ST_HDF_PLATFORM_PWM";
819            serviceName = "HDF_PLATFORM_PWM_2";
820            deviceMatchAttr = "config_pwm2";
821        }
822    }
823    device_pwm7 :: device {
824        pwm7 :: deviceNode {
825            policy = 2;
826            priority = 100;
827            moduleName = "ST_HDF_PLATFORM_PWM";
828            serviceName = "HDF_PLATFORM_PWM_7";
829            deviceMatchAttr = "config_pwm7";
830        }
831    }
832    ```
833
834  The `hdf.hcs` file is stored in `//device/board/talkweb/niobe407/liteos_m/hdf_config/hdf.hcs`. You can configure the following information about the TIM timer in this file:
835
836    ```
837    --- Note: The frequency of tim2-tim7 and tim12-tim14 is 84 MHz, and that of TIM1 and TIM8 to TIM11 is 168 MHz. tim6 and tim7 cannot output PWM signals.
838    --- tim1 to tim5 and tim8 have four channels, tim9 and tim12 have two channels, and tim10, tim11, tim13, and tim14 have only one channel.
839
840    pwm_config {
841        pwm1_config {
842            match_attr = "config_pwm1";
843            pwmTim = 1; 		--- timer ID. It means tim2. (0: tim1, 1: tim2, ... tim6 and tim7 are unavailable.)
844            pwmCh = 3; 			--- Number of channels. (0: ch1, 1: ch2, 2: ch3, 3: ch4)
845            prescaler = 4199; 	--- prescaler. For example, if the tim2 frequency is 84 MHz, 20 kHz (84 MHz/(4199 + 1)) is used as the reference.
846        }
847        pwm2_config {
848            match_attr = "config_pwm2";
849            pwmTim = 2;
850            pwmCh = 0;
851            prescaler = 8399;
852        }
853        pwm3_config {
854            match_attr = "config_pwm7";
855            pwmTim = 7;
856            pwmCh = 0;
857            prescaler = 8399;
858        }
859    }
860    ```
861
862For details about the `hdf pwm` adaptation code, see **//drivers/adapter/platform/pwm/pwm_stm32f4xx.c**.
863
864For details about the `hdf pwm` usage example, see **//device/board/talkweb/niobe407/applications/206_hdf_pwm**.
865
866## Subsystem Adaptation
867
868The `OpenHarmony` subsystem adaptation consists of two parts:
869
870- Add the related subsystem and component to `config.json`, so that they can be included in compilation by the compilation system.
871- Perform hardware adaptation or optional software function adaptation for the `HAL` layer API of the component.
872
873### lwIP Adaptation
874
875The `LiteOS-M kernel` can use the Kconfig configuration to enable the lwIP to participate in compilation and specify the `lwip` compilation adaptation directory in the `kernel` component. The sample code is as follows:
876
877```
878{
879	"subsystem": "kernel",
880	"components": [
881		{
882            "component": "liteos_m",
883            "features": [
884                "ohos_kernel_liteos_m_lwip_path = \"//device/board/talkweb/niobe407/liteos_m/lwip_adapter\"" --- Specify the adaptation path.
885			]
886		}
887	]
888}
889```
890
891In the specified compilation adaptation directory, intrude and modify the header file configuration of the lwIP third-party library in `#include_next "lwip/lwipopts.h"` mode. The detailed adaptation procedure for wired Ethernet lwIP adaptation will be supplemented later.
892
893### Startup Subsystem Adaptation
894
895For the startup subsystem, adapt the `bootstrap_lite` and `syspara_lite` components. Add the corresponding configuration items to the `//vendor/talkweb/niobe407/config.json` file, as shown below:
896
897```
898{
899      "subsystem": "startup",
900      "components": [
901        {
902          "component": "bootstrap_lite",
903          "features": []
904        },
905        {
906          "component": "syspara_lite",
907          "features": []
908        }
909      ]
910}
911```
912
913When adapting the `bootstrap_lite` component, manually add the following information to the link file `//device/board/talkweb/niobe407/liteos_m/STM32F407IGTx_FLASH.ld`:
914
915```
916__zinitcall_bsp_start = .;
917KEEP (*(.zinitcall.bsp0.init))
918KEEP (*(.zinitcall.bsp1.init))
919KEEP (*(.zinitcall.bsp2.init))
920KEEP (*(.zinitcall.bsp3.init))
921KEEP (*(.zinitcall.bsp4.init))
922__zinitcall_bsp_end = .;
923__zinitcall_device_start = .;
924KEEP (*(.zinitcall.device0.init))
925KEEP (*(.zinitcall.device1.init))
926KEEP (*(.zinitcall.device2.init))
927KEEP (*(.zinitcall.device3.init))
928KEEP (*(.zinitcall.device4.init))
929__zinitcall_device_end = .;
930__zinitcall_core_start = .;
931KEEP (*(.zinitcall.core0.init))
932KEEP (*(.zinitcall.core1.init))
933KEEP (*(.zinitcall.core2.init))
934KEEP (*(.zinitcall.core3.init))
935KEEP (*(.zinitcall.core4.init))
936__zinitcall_core_end = .;
937__zinitcall_sys_service_start = .;
938KEEP (*(.zinitcall.sys.service0.init))
939KEEP (*(.zinitcall.sys.service1.init))
940KEEP (*(.zinitcall.sys.service2.init))
941KEEP (*(.zinitcall.sys.service3.init))
942KEEP (*(.zinitcall.sys.service4.init))
943__zinitcall_sys_service_end = .;
944__zinitcall_sys_feature_start = .;
945KEEP (*(.zinitcall.sys.feature0.init))
946KEEP (*(.zinitcall.sys.feature1.init))
947KEEP (*(.zinitcall.sys.feature2.init))
948KEEP (*(.zinitcall.sys.feature3.init))
949KEEP (*(.zinitcall.sys.feature4.init))
950__zinitcall_sys_feature_end = .;
951__zinitcall_run_start = .;
952KEEP (*(.zinitcall.run0.init))
953KEEP (*(.zinitcall.run1.init))
954KEEP (*(.zinitcall.run2.init))
955KEEP (*(.zinitcall.run3.init))
956KEEP (*(.zinitcall.run4.init))
957__zinitcall_run_end = .;
958__zinitcall_app_service_start = .;
959KEEP (*(.zinitcall.app.service0.init))
960KEEP (*(.zinitcall.app.service1.init))
961KEEP (*(.zinitcall.app.service2.init))
962KEEP (*(.zinitcall.app.service3.init))
963KEEP (*(.zinitcall.app.service4.init))
964__zinitcall_app_service_end = .;
965__zinitcall_app_feature_start = .;
966KEEP (*(.zinitcall.app.feature0.init))
967KEEP (*(.zinitcall.app.feature1.init))
968KEEP (*(.zinitcall.app.feature2.init))
969KEEP (*(.zinitcall.app.feature3.init))
970KEEP (*(.zinitcall.app.feature4.init))
971__zinitcall_app_feature_end = .;
972__zinitcall_test_start = .;
973KEEP (*(.zinitcall.test0.init))
974KEEP (*(.zinitcall.test1.init))
975KEEP (*(.zinitcall.test2.init))
976KEEP (*(.zinitcall.test3.init))
977KEEP (*(.zinitcall.test4.init))
978__zinitcall_test_end = .;
979__zinitcall_exit_start = .;
980KEEP (*(.zinitcall.exit0.init))
981KEEP (*(.zinitcall.exit1.init))
982KEEP (*(.zinitcall.exit2.init))
983KEEP (*(.zinitcall.exit3.init))
984KEEP (*(.zinitcall.exit4.init))
985__zinitcall_exit_end = .;
986```
987
988Adding 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`. The following table lists the automatic initialization macros of main services.
989
990| API                | Description                            |
991| ---------------------- | -------------------------------- |
992| SYS_SERVICE_INIT(func) | Entry for initializing and starting a core system service.|
993| SYS_FEATURE_INIT(func) | Entry for initializing and starting a core system feature.|
994| APP_SERVICE_INIT(func) | Entry for initializing and starting an application-layer service.  |
995| APP_FEATURE_INIT(func) | Entry for initializing and starting an application-layer feature.  |
996
997
998
999The **lib** file compiled using the loaded components needs to be manually add to the forcible link.
1000
1001If the `bootstrap_lite` component is configured in the `//vendor/talkweb/niobe407/config.json` file:
1002
1003```
1004    {
1005      "subsystem": "startup",
1006      "components": [
1007        {
1008          "component": "bootstrap_lite"
1009        },
1010        ...
1011      ]
1012    },
1013```
1014
1015​	The `bootstrap_lite` component will compile 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`. Since the `Init` function does not support explicit call, you need to forcibly link it to the final image. The sample code is as follows:
1016
1017```
1018static void Init(void)
1019{
1020    static Bootstrap bootstrap;
1021    bootstrap.GetName = GetName;
1022    bootstrap.Initialize = Initialize;
1023    bootstrap.MessageHandle = MessageHandle;
1024    bootstrap.GetTaskConfig = GetTaskConfig;
1025    bootstrap.flag = FALSE;
1026    SAMGR_GetInstance()->RegisterService((Service *)&bootstrap);
1027}
1028SYS_SERVICE_INIT(Init);   --- Forcible link to the generated lib file is required if **SYS_INIT** is used for startup.
1029```
1030
1031​	The `//base/startup/bootstrap_lite/services/source/BUILD.gn` file describes how to generate `libbootstrap.a` in `//out/niobe407/niobe407/libs` as follows:
1032
1033```
1034static_library("bootstrap") {
1035  sources = [
1036    "bootstrap_service.c",
1037    "system_init.c",
1038  ]
1039  ...
1040```
1041
1042When the `syspara_lite` component is adapted, system parameters will be written into the file for persistent storage. In the mini system, file operation APIs include `POSIX` and `HalFiles`.
1043
1044For access to the file system in the kernel, use the `POSIX` API, which means you need to add `enable_ohos_startup_syspara_lite_use_posix_file_api = true` to the `features` field.
1045
1046If you are using the `HalFiles` API, no modification is required.
1047### DFX Subsystem Adaptation
1048
1049To adapt the `DFX` subsystem, you need to add the `hilog_lite` and `hievent_lite` components to the `config.json` file.
1050
1051```
1052{
1053    "subsystem": "hiviewdfx",
1054    "components": [
1055        {
1056            "component": "hilog_lite",
1057            "features": []
1058        },
1059        {
1060            "component": "hievent_lite",
1061            "features": []
1062        }
1063    ]
1064}
1065```
1066
1067After the configuration is complete, you need to register the log output implementation function and add it for compilation.
1068
1069```
1070bool HilogProc_Impl(const HiLogContent *hilogContent, uint32_t len)
1071{
1072    char tempOutStr[LOG_FMT_MAX_LEN];
1073    tempOutStr[0] = 0,tempOutStr[1] = 0;
1074    if (LogContentFmt(tempOutStr, sizeof(tempOutStr), hilogContent) > 0) {
1075        printf(tempOutStr);
1076    }
1077    return true;
1078}
1079
1080HiviewRegisterHilogProc(HilogProc_Impl);
1081```
1082
1083### System Service Management Subsystem Adaptation
1084
1085To adapt the system service management subsystem, you need to add the `samgr_lite` component to the `config.json` file.
1086
1087```
1088{
1089      "subsystem": "systemabilitymgr",
1090      "components": [
1091        {
1092          "component": "samgr_lite",
1093          "features": []
1094        }
1095      ]
1096}
1097```
1098
1099In the mini system, the default size of the shared task stack configured for the `samgr_lite` is `2048`. During adaptation, you can use `config_ohos_systemabilitymgr_samgr_lite_shared_task_size` in features to reset the size of the shared task stack.
1100
1101```
1102"config_ohos_systemabilitymgr_samgr_lite_shared_task_size = 4096"
1103```
1104
1105### Security Subsystem Adaptation
1106
1107To adapt the security subsystem, you need to add the `huks` component to the `config.json` file.
1108
1109```
1110{
1111      "subsystem": "security",
1112      "components": [
1113        {
1114          "component": "huks",
1115          "features": [
1116            "huks_use_lite_storage = true",
1117            "huks_use_hardware_root_key = true",
1118            "huks_config_file = \"hks_config_lite.h\"",
1119            "huks_key_store_path = \"storage\""
1120          ]
1121        }
1122      ]
1123}
1124```
1125
1126During `huks` adaptation, the `huks_key_store_path` configuration item specifies the path for storing the key, and `huks_config_file` indicates the name of the configuration header file.
1127
1128### Utils Subsystem Adaptation
1129
1130To adapt the utils subsystem, you need to add the `kv_store`, `file`, and `os_dump` components to the `config.json` file.
1131
1132```
1133{
1134      "subsystem": "utils",
1135      "components": [
1136        {
1137          "component": "file",
1138          "features": []
1139        },
1140        {
1141          "component": "kv_store",
1142          "features": [
1143            "enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = false"
1144          ]
1145        },
1146        {
1147          "component": "os_dump",
1148          "features": []
1149        }
1150      ]
1151},
1152```
1153
1154Similar 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`. The `POSIX` API is used for access to the file system in the kernel, 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.
1155
1156### HDF Subsystem Adaptation
1157
1158Similar to startup subsystem adaptation, you need to manually add the following information to the link file `//device/board/talkweb/niobe407/liteos_m/STM32F407IGTx_FLASH.ld`:
1159
1160```
1161_hdf_drivers_start = .;
1162KEEP(*(.hdf.driver))
1163_hdf_drivers_end = .;
1164```
1165
1166After the kernel is initialized, call the **DeviceManagerStart** function. After the execution is complete, the HDF API can be called to control peripherals.
1167
1168```
1169#include "devmgr_service_start.h" --- Note that this header file must be included.
1170
1171#ifdef LOSCFG_DRIVERS_HDF
1172    DeviceManagerStart();
1173#endif
1174```
1175
1176The `devmgr_service_start.h` header file is stored in `//drivers/framework/core/common/include/manager`. To ensure that the header file can be found during compilation, add it to **include_dirs**.
1177
1178### Adaptation of the XTS Compatibility Test Subsystem
1179
1180#### Product Compatibility Specifications
1181
1182For details about the product compatibility specifications, see [Introduction to Product Compatibility](https://gitee.com/openharmony-sig/compatibility/tree/master).
1183
1184#### Adding an XTS Subsystem
1185
1186For details about the `XTS` test reference, see [XTS Reference](../device-test/xts.md). To adapt the `XTS` subsystem, you need to add the `xts_acts` and `xts_tools` components to the `config.json` file. The configuration is as follows:
1187
1188    {
1189          "subsystem": "xts",
1190          "components": [
1191            {
1192              "component": "xts_acts",
1193              "features": []
1194            },
1195            {
1196              "component": "xts_tools",
1197              "features": []
1198            }
1199          ]
1200    }
1201
1202You can specify the following attributes in the features array of the **xts_acts** component:
1203
1204- `config_ohos_xts_acts_utils_lite_kv_store_data_path`: name of the root directory of the mounted file system.
1205- `enable_ohos_test_xts_acts_use_thirdparty_lwip`: If the source code in the `thirdparty/lwip` directory is used for compilation, set this parameter to `true`. Otherwise, set this parameter to `false`.
1206
1207#### Compiling the XTS
1208
1209After the **config.json** file is configured, `hb build` does not compile the XTS. The XTS is compiled only when the debug version is compiled. In addition, the suite static library to be tested needs to be forcibly linked.
1210
1211Add the following content to the **BUILD.gn** script that contains `kernel_module` in `//device/board/talkweb/liteos_m`:
1212
1213```
1214config("public") {
1215	if (build_xts) {
1216        lib_dirs = [ "$root_out_dir/libs" ]
1217        ldflags += [
1218        "-Wl,--whole-archive",     --- After whole-archive is enabled, functions and variables of the static library can be output to the dynamic library.
1219        "-lbootstrap",
1220        "-lbroadcast",
1221        "-lhctest",
1222
1223        #Utils
1224        # "-lmodule_ActsUtilsFileTest",
1225        # "-lmodule_ActsKvStoreTest",
1226
1227        #DFX
1228        "-lmodule_ActsDfxFuncTest",
1229        "-lmodule_ActsHieventLiteTest",
1230
1231        #Startup
1232        # "-lmodule_ActsBootstrapTest",
1233        # "-lmodule_ActsParameterTest",
1234
1235        #Distributed scheduling
1236        # "-lmodule_ActsSamgrTest",
1237
1238        "-Wl,--no-whole-archive",  --- Disable the whole-archive feature.
1239        ]
1240	}
1241}
1242```
1243
1244The memory of the Niobe407 board is limited. Therefore, the XTS test needs to be performed by suite. Run the following compilation command to generate the firmware that contains the XTS test:
1245
1246```
1247hb build -f -b debug --gn-args build_xts=true
1248```
1249
1250In addition, you need to modify the `//vendor/talkweb/niobe407/hals/utils/sys_param/hal_sys_param.c` file to correctly define these character strings.
1251
1252```
1253static const char OHOS_DEVICE_TYPE[] = {"Evaluation Board"};
1254static const char OHOS_DISPLAY_VERSION[] = {"OpenHarmony 3.1"};
1255static const char OHOS_MANUFACTURE[] = {"Talkweb"};
1256static const char OHOS_BRAND[] = {"Talkweb"};
1257static const char OHOS_MARKET_NAME[] = {"Niobe"};
1258static const char OHOS_PRODUCT_SERIES[] = {"Niobe"};
1259static const char OHOS_PRODUCT_MODEL[] = {"Niobe407"};
1260static const char OHOS_SOFTWARE_MODEL[] = {"1.0.0"};
1261static const char OHOS_HARDWARE_MODEL[] = {"2.0.0"};
1262static const char OHOS_HARDWARE_PROFILE[] = {"RAM:192K,ROM:1M,ETH:true"};
1263static const char OHOS_BOOTLOADER_VERSION[] = {"twboot-v2022.03"};
1264static const char OHOS_ABI_LIST[] = {"armm4_hard_fpv4-sp-d16-liteos"};
1265static const char OHOS_SERIAL[] = {"1234567890"};  // provided by OEM.
1266```
1267
1268#### Verifying the XTS
1269
1270After the compilation is complete, burn the firmware to the board. After the XTS is executed, information such as `xx Tests xx Failures xx Ignored` is displayed. The following uses the Utils test as an example:
1271
1272```
1273../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:590:testKvStoreClearCache002:PASS
1274../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:625:testKvStoreCacheSize001:PASS
1275../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:653:testKvStoreCacheSize002:PASS
1276../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:681:testKvStoreCacheSize003:PASS
1277../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:709:testKvStoreMaxSize001:PASS
1278../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:737:testKvStoreMaxSize002:PASS
1279../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:765:testKvStoreMaxSize003:PASS
1280../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:793:testKvStoreMaxSize004:PASS
1281+-------------------------------------------+
1282
1283-----------------------
128432 Tests 0 Failures 0 Ignored
1285OK
1286All the test suites finished!
1287```
1288