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