1# 小型系统STM32MP1芯片移植案例 2 3本文章基于意法半导体`STM32MP157`芯片的小熊派[BearPi-HM Micro开发板](https://gitee.com/openharmony/device_board_bearpi),进行小型带屏开发板的移植,实现了`ace_engine_lite`、`arkui_ui_lite`、`aafwk_lite`、`appexecfwk_lite`、`HDF`等部件基于`OpenHarmony LiteOS-A`内核的适配。移植架构上采用`Board`与`SoC`分离的方案。 4 5## 编译构建 6 7### 目录规划 8 9本方案的目录结构使用[Board和SoC解耦的设计思路](https://gitee.com/openharmony-sig/sig-content/blob/master/devboard/docs/board-soc-arch-design.md),并把芯片适配目录规划为: 10 11``` 12device 13├── board --- 单板厂商目录 14│ └── bearpi --- 单板厂商名字:小熊派 15│ └── bearpi_hm_micro --- 单板名:bearpi_hm_micro 16└── soc --- SoC厂商目录 17 └── common --- 存放公共HDF驱动 18 └── st --- SoC厂商名字:ST意法半导体 19 └── stm32mp1xx --- SoC Series名:stm32mp1xx系列芯片 20``` 21 22产品样例目录规划为: 23 24``` 25vendor 26└── bearpi --- 开发产品样例厂商目录,小熊派的产品样例 27 └── bearpi_hm_micro --- 产品名字:bearpi_hm_micro开发板 28``` 29 30### 预编译适配 31 32在进行移植之前,需要进行预编译适配。 33 34预编译适配主要使用`hb set`命令,设置整个项目的根目录、单板目录、产品目录、单板公司名等环境变量,为编译做准备。 35 36具体的预编译适配步骤如下: 37 381. 在`vendor/bearpi/bearpi_hm_micro`目录下新增`config.json`文件,用于描述这个产品样例所使用的单板、内核等信息,描述信息可参考如下内容: 39 40 ``` 41 { 42 "product_name": "bearpi_hm_micro", --- 用于hb set进行选择时,显示的产品名称 43 "version": "3.0", --- 构建系统的版本,1.0/2.0/3.0 44 "type": "small", --- 构建系统的类型,mini/small/standard 45 "ohos_version": "OpenHarmony 3.0", --- OpenHarmony系统版本 46 "device_company": "bearpi", --- 单板厂商名,用于编译时找到/device/board/bearpi目录 47 "board": "bearpi_hm_micro", --- 单板名,用于编译时找到/device/board/bearpi/bearpi_hm_micro目录 48 "kernel_type": "liteos_a", --- 内核类型,因为OpenHarmony支持多内核,一块单板可能适配了多个内核,所以需要指定某个内核进行编译 49 "kernel_version": "", --- 内核版本,一块单板可能适配了多个linux内核版本,所以需要指定某个具体的内核版本进行编译 50 "subsystems": [ ] --- 选择所需要编译构建的子系统 51 } 52 ``` 53 542. 在`device/board/bearpi/bearpi_hm_micro/liteos_a`目录下新增`config.gni`文件,用于描述这个产品样例所使用的单板、内核等信息,描述信息可参考如下内容: 55 56 ``` 57 # Kernel type, e.g. "linux", "liteos_a", "liteos_m". 58 kernel_type = "liteos_a" 59 60 # Kernel version. 61 kernel_version = "" 62 63 # Board CPU type, e.g. "cortex-a7", "riscv32". 64 board_cpu = "cortex-a7" 65 66 # Board arch, e.g. "armv7-a", "rv32imac". 67 board_arch = "" 68 69 # Toolchain name used for system compiling. 70 # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. 71 # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toolchain. 72 board_toolchain = "" 73 74 # The toolchain path installed, it's not mandatory if you have added toolchain path to your ~/.bashrc. 75 board_toolchain_path = "" 76 77 # Compiler prefix. 78 board_toolchain_prefix = "" 79 80 # Compiler type, "gcc" or "clang". 81 board_toolchain_type = "clang" 82 83 # Board related common compile flags. 84 board_cflags = [ 85 "-mfloat-abi=softfp", 86 "-mfpu=neon-vfpv4", 87 ] 88 board_cxx_flags = [ 89 "-mfloat-abi=softfp", 90 "-mfpu=neon-vfpv4", 91 ] 92 board_ld_flags = [] 93 94 # Board related headfiles search path. 95 board_include_dirs = [] 96 97 # Board adapter dir for OHOS components. 98 board_adapter_dir = "//device/board/bearpi/bearpi_hm_micro/hal" 99 100 # Sysroot path. 101 board_configed_sysroot = "" 102 103 # Board storage type, it used for file system generation. 104 storage_type = "emmc" 105 ``` 106 1073. 验证`hb set`配置是否正确,输入`hb set`能够显示如下图片表示配置正确。 108 109 执行`hb set`输入项目根目录,并且回车,`hb`命令会遍历所有`//vendor/<product_company>/<product_name>`目录下的`config.json`,给出可选产品编译选项,`config.json`的`product_name`用于显示产品名,`device_company`和`board`用于关联出`//device/board/<device_company>/<board>`目录,并且匹配`<any_dir_name>/config.gni`文件,如果能够匹配多个文件,表示该单板适配了多个内核,那么可以根据`config.json`的`kernel_type`和`kernel_version`来唯一匹配`config.gni`的`kernel_type`和`kernel_version`,即可确定了需要编译适配了哪个内核的单板。 110 111  112 113 选择好产品后,输入回车就会在根目录下自动生成ohos_config.json文件,这里会将要编译的产品信息列出。通过`hb env`也可以查看选择出来的预编译环境变量。 114 115  116 117 118 119## 内核移植 120 121内核移植需要完成`LiteOS-A Kconfig`适配、`gn`的编译构建和内核启动最小适配。 122 123详细移植步骤参考:[LiteOS-A内核移植](porting-smallchip-kernel-a.md) 124### Kconfig适配 1251. 在//device/board/bearpi/bearpi_hm_micro/liteos_a/drivers/Kconfig中添加芯片、产品名称、厂商名称相关配置。 126 ``` 127 source "../../device/soc/st/common/platform/Kconfig" 128 129 config PLATFORM 130 string 131 default "stm32mp157" if PLATFORM_STM32MP157 132 133 config PRODUCT_NAME 134 string "product name" 135 default "bearpi_hm_micro" if PRODUCT_BEARPI_HM_MICRO 136 137 config DEVICE_COMPANY 138 string "vendor name" 139 default "st" if PLATFORM_STM32MP157 140 141 config TEE_ENABLE 142 bool "Enable TEE" 143 default n 144 depends on PLATFORM_STM32MP157 145 help 146 Enable teeos in platform 147 ``` 1482. 在//device/soc/st/common/platform/Kconfig中添加驱动相关配置。 149 ``` 150 config DRIVERS_MMC 151 depends on DRIVERS 152 bool "Enable MMC" 153 default y 154 depends on DRIVERS && FS_VFS 155 help 156 Answer Y to enable LiteOS support MMC driver. 157 158 config DRIVERS_EMMC 159 depends on DRIVERS_MMC && PLATFORM_STM32MP157 160 bool "Enable MMC0 support eMMC type" 161 162 config DRIVERS_HI3881 163 bool "Enable Hi3881 Host driver" 164 default n 165 depends on DRIVERS_HDF_WIFI 166 help 167 Answer Y to enable Hi3881 Host driver. 168 config HW_RANDOM_ENABLE 169 depends on DRIVERS_RANDOM 170 bool "Select hw random" 171 default y 172 help 173 Answer Y to select hw random. 174 ``` 1753. 在//vendor/bearpi/bearpi_hm_micro/kernel_configs/debug_tee.config中使能相关配置。 176 ``` 177 ... 178 LOSCFG_PLATFORM="stm32mp157" 179 LOSCFG_PRODUCT_NAME="bearpi_hm_micro" 180 LOSCFG_DEVICE_COMPANY="st" 181 # LOSCFG_PLATFORM_HI3516DV300 is not set 182 # LOSCFG_PLATFORM_HI3518EV300 is not set 183 # LOSCFG_PLATFORM_QEMU_ARM_VIRT_CA7 is not set 184 LOSCFG_PLATFORM_STM32MP157=y 185 LOSCFG_PRODUCT_BEARPI_HM_MICRO=y 186 LOSCFG_BOARD_CONFIG_PATH="device/board/bearpi/bearpi_hm_micro/liteos_a/board" 187 LOSCFG_TEE_ENABLE=y 188 ... 189 ``` 190### gn编译适配 1911. 在//device/board/bearpi/bearpi_hm_micro/liteos_a中新建BUILD.gn,添加代码如下,此模块依赖board、drivers、hdf_config。 192 ``` 193 cmd = "if [ -f $product_path/hdf_config/BUILD.gn ]; then echo true; else echo false; fi" 194 HAVE_PRODUCT_CONFIG = 195 exec_script("//build/lite/run_shell_cmd.py", [ cmd ], "value") 196 197 group("liteos_a") { 198 deps = [ 199 "board", 200 "drivers", 201 ] 202 if (HAVE_PRODUCT_CONFIG) { 203 deps += [ "$product_path/hdf_config" ] 204 } else { 205 deps += [ "hdf_config" ] 206 } 207 } 208 209 config("public") { 210 configs = [ 211 "board:public", 212 "drivers:public", 213 ] 214 } 215 ``` 2162. 在//device/board/bearpi/bearpi_hm_micro/liteos_a/board中新建BUILD.gn,添加代码如下。将os_adapt.c内核启动相关代码编译进系统。 217 ``` 218 import("//kernel/liteos_a/liteos.gni") 219 220 module_name = "bsp_config" 221 222 kernel_module(module_name) { 223 sources = [] 224 if (defined(LOSCFG_PLATFORM_ADAPT)) { 225 sources += [ "os_adapt/os_adapt.c" ] 226 } 227 } 228 229 config("public") { 230 include_dirs = [ "." ] 231 include_dirs += [ "include" ] 232 include_dirs += [ "$LITEOSTOPDIR/drivers/block/disk/include" ] 233 include_dirs += 234 [ "$LITEOSTOPDIR/../../drivers/adapter/khdf/liteos/osal/include" ] 235 } 236 ``` 2373. 在//device/board/bearpi/bearpi_hm_micro/liteos_a/drivers中新建BUILD.gn,添加代码如下,将device/soc/st/common/platform路径下的HDF驱动编译进系统。 238 ``` 239 import("//drivers/adapter/khdf/liteos/hdf.gni") 240 241 group("drivers") { 242 public_deps = [ "//device/soc/st/common/platform:drivers" ] 243 } 244 245 config("public") { 246 configs = [ "//device/soc/st/common/platform:public" ] 247 } 248 249 ``` 2504. 在//vendor/bearpi/bearpi_hm_micro/hdf_config中新建BUILD.gn,添加代码如下,将HCS配置文件编译进系统。 251 ``` 252 module_switch = defined(LOSCFG_DRIVERS_HDF) && !defined(LOSCFG_DRIVERS_HDF_TEST) 253 module_name = "libhdf_config" 254 hdf_driver(module_name) { 255 hcs_sources = [ "hdf.hcs" ] 256 } 257 258 group("hdf_config") { 259 public_deps = [ ":$module_name" ] 260 deps = [ 261 "hdf_test", 262 "hdf_test/hcs_macro_test", 263 ] 264 } 265 ``` 266### 内核启动适配 2671. 在//device/board/bearpi/bearpi_hm_micro/liteos_a/board/os_adapt.c中添加以下内核启动相关代码,详细解释参考[LiteOS-A内核移植](porting-smallchip-kernel-a.md)。 268 ``` 269 ... 270 void SystemInit(void) 271 { 272 #ifdef LOSCFG_DRIVERS_RANDOM 273 dprintf("dev random init ...\n"); 274 Mp1xxRngInit(); 275 #endif 276 #ifdef LOSCFG_DRIVERS_MEM 277 dprintf("mem dev init ...\n"); 278 extern int mem_dev_register(void); 279 mem_dev_register(); 280 #endif 281 282 dprintf("Date:%s.\n", __DATE__); 283 dprintf("Time:%s.\n", __TIME__); 284 285 #ifdef LOSCFG_DRIVERS_HDF 286 dprintf("DeviceManagerStart start ...\n"); 287 if (DeviceManagerStart()) { 288 PRINT_ERR("No drivers need load by hdf manager!"); 289 } 290 dprintf("DeviceManagerStart end ...\n"); 291 #endif 292 net_init(); 293 294 #ifdef LOSCFG_PLATFORM_ROOTFS 295 dprintf("OsMountRootfs start ...\n"); 296 if (LOS_GetCmdLine()) { 297 dprintf("get cmdline error!\n"); 298 } 299 if (LOS_ParseBootargs()) { 300 dprintf("parse bootargs error!\n"); 301 } 302 if (OsMountRootfs()) { 303 dprintf("mount rootfs error!\n"); 304 } 305 dprintf("OsMountRootfs end ...\n"); 306 #endif 307 308 dprintf("Before PLATFORM_UART ...\n"); 309 310 #ifdef LOSCFG_DRIVERS_HDF_PLATFORM_UART 311 if (virtual_serial_init(TTY_DEVICE) != 0) { 312 PRINT_ERR("virtual_serial_init failed"); 313 } 314 if (system_console_init(SERIAL) != 0) { 315 PRINT_ERR("system_console_init failed\n"); 316 } 317 #endif 318 319 dprintf("After PLATFORM_UART ...\n"); 320 321 if (OsUserInitProcess()) { 322 PRINT_ERR("Create user init process failed!\n"); 323 return; 324 } 325 dprintf("cat log shell end\n"); 326 return; 327 } 328 ... 329 ``` 330 331 332## 板级系统移植 333 334### SoC芯片平台HDF驱动移植 335 336驱动适配相关文件放置在`device/soc/st/common/platform`中,所有的驱动都是通过`HDF`机制加载,本章节以GPIO驱动适配为例进行详细说明。 337 3381. 在`//device/soc/st/common/platform/gpio/BUILD.gn`文件中,描述了stm32mp1xx `gpio`驱动的编译适配。如下: 339 340 ``` 341 module_switch = defined(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO) --- 如果打开HDF的GPIO配置开关,才进行如下编译。 342 module_name = get_path_info(rebase_path("."), "name") 343 344 hdf_driver("hdf_gpio") { 345 sources = [ "stm32mp1_gpio.c" ] ---gpio驱动源文件。 346 include_dirs = [ ---依赖的.h路径。 347 "." , 348 "../stm32mp1xx_hal/STM32MP1xx_HAL_Driver/Inc", 349 ] 350 } 351 ``` 352 3532. 在`//device/soc/st/common/platform/gpio/stm32mp1_gpio.c`文件中,描述了stm32mp1xx `gpio`驱动的源码适配。 354首先,按照`OpenHarmony`的`HDF`驱动框架加载驱动基本适配框架,如下: 355 356 ``` 357 struct HdfDriverEntry g_GpioDriverEntry = { 358 .moduleVersion = 1, 359 .moduleName = "HDF_PLATFORM_GPIO", 360 .Bind = GpioDriverBind, 361 .Init = GpioDriverInit, 362 .Release = GpioDriverRelease, 363 }; 364 HDF_INIT(g_GpioDriverEntry); --- 通过HDF_INIT 加载GPIO驱动。 365 ``` 3663. 在//device/soc/st/stm32mp1xx/sdk_liteos/hdf_config/gpio中添加gpio硬件描述信息文件gpio_config.hcs,在该文件中添加驱动私有配置信息。 367 ``` 368 root { 369 platform { 370 gpio_config { 371 controller_0x50002000 { 372 match_attr = "st_stm32mp1_gpio"; 373 groupNum = 11; 374 bitNum = 16; 375 gpioRegBase = 0x50002000; 376 gpioRegStep = 0x1000; 377 irqRegBase = 0x5000D000; 378 irqRegStep = 0x400; 379 } 380 } 381 } 382 } 383 ``` 3844. 配置产品加载驱动,产品的所有设备信息被定义在源码文件//vendor/bearpi/bearpi_hm_micro/hdf_config/device_info/device_info.hcs中。 385 386 平台驱动请添加到platform的host中。 387 388 >  **说明:** 389 > moduleName要与驱动文件中定义的相同,deviceMatchAttr要与驱动私有配置信息文件gpio_config.hcs中定义match_attr的相同。 390 391 392 ``` 393 root { 394 ... 395 platform :: host { 396 device_gpio :: device { 397 device0 :: deviceNode { 398 policy = 2; 399 priority = 10; 400 permission = 0644; 401 moduleName = "HDF_PLATFORM_GPIO_MANAGER"; 402 serviceName = "HDF_PLATFORM_GPIO_MANAGER"; 403 } 404 device1 :: deviceNode { 405 policy = 0; 406 priority = 10; 407 permission = 0644; 408 moduleName = "HDF_PLATFORM_GPIO"; 409 serviceName = "HDF_PLATFORM_GPIO"; 410 deviceMatchAttr = "st_stm32mp1_gpio"; 411 } 412 } 413 } 414 } 415 ``` 4165. 完善驱动代码,gpio_config.hcs的配置信息会在GpioDriverInit中加载。 417 ``` 418 static int32_t GpioDriverInit(struct HdfDeviceObject *device) 419 { 420 421 int32_t ret; 422 struct Mp1xxGpioCntlr *stm32gpio = &g_Mp1xxGpioCntlr; 423 424 dprintf("%s: Enter", __func__); 425 if (device == NULL || device->property == NULL) { 426 HDF_LOGE("%s: device or property NULL!", __func__); 427 return HDF_ERR_INVALID_OBJECT; 428 } 429 //获取属性数据。 430 ret = Mp1xxGpioReadDrs(stm32gpio, device->property); 431 if (ret != HDF_SUCCESS) { 432 HDF_LOGE("%s: get gpio device resource fail:%d", __func__, ret); 433 return ret; 434 } 435 ... 436 } 437 ``` 438 439### OpenHarmony子系统适配 440 441`OpenHarmony`子系统适配只需要在`config.json`中增加对应子系统和部件,这样编译系统会将该部件纳入编译目标中。 442 443#### 启动恢复子系统适配 444 445启动恢复子系统需要适配`bootstrap_lite`、`syspara_lite`、`appspawn_lite`、`init`四个部件。请在`vendor/bearpi/bearpi_hm_micro/config.json`中新增对应的配置选项。 446 447``` 448 { 449 "subsystem": "startup", 450 "components": [ 451 { "component": "syspara_lite", "features":[] }, 452 { "component": "bootstrap_lite", "features":[] }, 453 { "component": "appspawn_lite", "features":[] }, 454 { "component": "init", "features":[] } 455 ] 456 }, 457``` 458系统启动时会根据//vendor/bearpi/bearpi_hm_micro/init_configs中的启动配置来启动系统。 459 460 461#### DFX子系统适配 462 463进行`DFX`子系统适配需要添加`hilog_featured_lite`、`hidumper_lite`部件,直接在`config.json`文件配置即可。 464 465``` 466 { 467 "subsystem": "hiviewdfx", 468 "components": [ 469 { "component": "hilog_featured_lite", "features":[] }, 470 { "component": "hidumper_lite", "features":[] } 471 ] 472 }, 473``` 474 475#### 系统服务管理子系统适配 476 477进行系统服务管理子系统适配需要添加`samgr_lite`、`safwk_lite`、`dmsfwk_lite`三个部件,直接在`config.json`配置即可。 478 479``` 480 { 481 "subsystem": "distributed_schedule", 482 "components": [ 483 { "component": "samgr_lite", "features":[] }, 484 { "component": "safwk_lite", "features":[] }, 485 { "component": "dmsfwk_lite", "features":[] } 486 ] 487 }, 488``` 489 490#### 安全子系统适配 491 492进行安全子系统适配需要添加`permission_lite`、`appverify`、`device_auth`、`huks`四个部件,直接在`config.json`配置即可。 493 494``` 495 { 496 "subsystem": "security", 497 "components": [ 498 { "component": "permission_lite", "features":[] }, 499 { "component": "appverify", "features":[] }, 500 { "component": "device_auth", "features":[] }, 501 { "component": "huks", "features": 502 [ 503 "huks_config_file = \"hks_config_small.h\"" 504 ] 505 } 506 ] 507 }, 508``` 509 510 511#### 公共基础库子系统适配 512 513进行公共基础库子系统适配需要添加`kv_store`、`os_dump`两个部件,直接在`config.json`配置即可。 514 515``` 516 { 517 "subsystem": "utils", 518 "components": [ 519 { "component": "kv_store", "features":[] }, 520 { "component": "os_dump", "features":[] } 521 ] 522 }, 523``` 524 525#### 图形子系统适配 526 527进行图形子系统适配需要添加`graphic_utils`部件,直接在`config.json`配置即可。 528 529``` 530 { 531 "subsystem": "graphic", 532 "components": [ 533 { "component": "graphic_utils", 534 "features": [ "enable_ohos_graphic_utils_product_config = true" 535 ] 536 }, 537 { "component": "graphic_hals", "features":[] }, 538 { "component": "ui", "features":[ "enable_graphic_font = true","enable_video_component=false"] }, 539 { "component": "surface", "features":[] }, 540 { "component": "wms", "features":[] } 541 ] 542 }, 543``` 544 545`graphic`配置文件见 `//vendor/bearpi/bearpi_hm_micro/graphic_config/product_graphic_lite_config.h`。 546 547 548#### ArkUI开发框架子系统适配 549 550进行ArkUI开发框架子系统适配需要添加`ace_engine_lite`部件,直接在`config.json`配置即可。 551 552``` 553 { 554 "subsystem": "arkui", 555 "components": [ 556 { 557 "component": "ace_engine_lite", 558 "features": [ 559 "ace_engine_lite_feature_product_config = true" 560 ] 561 } 562 ] 563 }, 564``` 565`ace_engine_lite`部件配置文件见 `//vendor/bearpi/bearpi_hm_micro/ace_lite_config/product_acelite_config.h`。 566 567#### 元能力子系统适配 568 569进行元能力子系统适配需要添加`aafwk_lite`部件,直接在`config.json`配置即可。 570 571``` 572 { 573 "subsystem": "aafwk", 574 "components": [ 575 { 576 "component": "aafwk_lite", 577 "features": [ 578 "ability_lite_enable_ohos_appexecfwk_feature_ability = true" --- 支持FA特性,即包含图形能力。 579 ] 580 } 581 ] 582 }, 583``` 584 585 586#### 包管理子系统适配 587 588进行包管理子系统适配需要添加`appexecfwk_lite`部件,直接在`config.json`配置即可。 589 590``` 591 { 592 "subsystem": "appexecfwk", 593 "components": [ 594 { 595 "component": "appexecfwk_lite" 596 } 597 ] 598 }, 599```