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