浅析OpenHarmony内核SoC层级的移植适配流程

发布者:火星最新更新时间:2024-06-24 来源: elecfans关键字:移植 手机看文章 扫描二维码
随时随地手机看文章

OpenHarmony 系统移植最核心的步骤是内核的移植,内核的稳定是一切子系统稳定的基础,上一篇我们讲述了内核启动原理,以及 vendor、board 的开发配置,本文将介绍 SoC 层级的移植适配流程。


SoC 适配

SoC 配置芯片层级编译依赖库,包括 CMSIS、HAL(硬件抽象层)等,这里包含操作总线、串口时钟、寄存等库函数。

①创建对应的文件目录结构

目录名称按照芯片厂家、芯片型号来创建,比如 st 公司下的 stm32f4xx 系列芯片。

b74ccf9e-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

配置文件内容如下:


device/soc/st/stm32f4xx/Kconfig.liteos_m.defconfig.series

if SOC_SERIES_STM32F4xx

rsource 'Kconfig.liteos_m.defconfig.stm32f4xx'

config SOC_SERIES

string

default 'stm32f4xx'

endif

device/soc/st/stm32f4xx/Kconfig.liteos_m.defconfig.stm32f4xx

config SOC

string

default 'stm32f4xx'

depends on SOC_STM32F4xx

device/soc/st/stm32f4xx/Kconfig.liteos_m.series

config SOC_SERIES_STM32F4xx

bool 'STMicroelectronics STM32F4xx series'

select ARCH_ARM

select SOC_COMPANY_STMICROELECTRONICS

select CPU_CORTEX_M4

help

Enable support for STMicroelectronics STM32F4xx series

device/soc/st/stm32f4xx/Kconfig.liteos_m.soc

choice

prompt 'STMicroelectronics STM32F4xx series SoC'

depends on SOC_SERIES_STM32F4xx

config SOC_STM32F407

bool 'SoC STM32F407'

Endchoice

device/soc/st/Kconfig.liteos_m.defconfig

rsource '*/Kconfig.liteos_m.defconfig.series'

device/soc/st/Kconfig.liteos_m.defconfig

rsource '*/Kconfig.liteos_m.series'

device/soc/st/Kconfig.liteos_m.soc

config SOC_COMPANY_STMICROELECTRONICS

bool

if SOC_COMPANY_STMICROELECTRONICS

config SOC_COMPANY

default 'st'

rsource '*/Kconfig.liteos_m.soc'

endif # SOC_COMPANY_STMICROELECTRONICS

device/soc/st/BUILD.gn

if (ohos_kernel_type == 'liteos_m') {

import('//kernel/liteos_m/liteos.gni')

module_name = get_path_info(rebase_path('.'), 'name')

module_group(module_name) {

modules = [ 'stm32f4xx' ]

}

}

device/soc/st/stm32f4xx/BUILD.gn

if (ohos_kernel_type == 'liteos_m') {

import('//kernel/liteos_m/liteos.gni')

module_name = get_path_info(rebase_path('.'), 'name')

module_group(module_name) {

modules = [ 'liteos_m', 'sdk' ]

}

}


②移植 HAL 库函数等文件

对于 STM32F407 我们可以使用官方的 STM32CubeMX 生成对应的标准的 hal 库函数文件。

选择 ACCESS TO MCU SELECTOR:

b767b656-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

勾选 Arm Cortex-M4→STM32F4→STM32F407ZGTx:

b7796a04-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

填写工程名称,选择工程保存路径,选择 Makefile 作为编译工具,点击 GENERATE CODE 生成工程代码

b7d566b0-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

使用 vscode 打开目录,我们得到如下工程:

b7faf3e4-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

回顾一下之前讲过的系统启动的流程:

HAL 初始化

系统时钟初始化

系统初始化

系统启动

接下来我们将 HAL 库函数文件及芯片头文件迁移到 OH 代码中,文件路径如下:

b80d729e-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

将 Drivers 中的 CMSIS、STM32F4xx_HAL_Driver 复制到 /device/soc/st/stm32f4xx/sdk/Drivers 中。

b84883ac-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

③修改系统编译配置文件


使用 OH 的 gn 以及 config 文件配置系统编译流程以及包依赖关系,涉及到的配置文件如下:


 


device/board/alientek/explorer/liteos_m/config.gni# Kernel 

type, e.g. 'linux', 'liteos_a', 'liteos_m'.kernel_type = 'liteos_m'# Kernel version.kernel_version = '3.0.0'# Board CPU 

type, e.g. 'cortex-a7', 'riscv32'.board_cpu = 'cortex-m4'# Board arch, e.g. 'armv7-a', 'rv32imac'.board_arch = ''# Toolchain name used 

for system compiling.# E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf.# Note: The default toolchain is 'ohos-clang'. 

It's not mandatory if you use the default toolchain.board_toolchain = 'arm-none-eabi-gcc'use_board_toolchain = true# The toolchain path installed, it's 

not mandatory 

if you have added toolchain 

path to your ~/.bashrc.board_toolchain_path = ''#

 Compiler prefix.board_toolchain_prefix = 'arm-none-eabi-'# Compiler 

type, 'gcc' 

or 'clang'.board_toolchain_type = 'gcc'

#Debug compiler optimization level optionsboard_opt_flags = ['-mcpu=cortex-m4','-mthumb','-mfpu=fpv4-sp-d16','-mfloat-abi=hard',]# 

Board related common compile flags.board_cflags = ['-Og','-Wall','-fdata-sections','-ffunction-sections','-DSTM32F407xx','-DHAL_UART_MODULE_ENABLED']

board_cflags += board_opt_flagsboard_asmflags = ['-Og','-Wall','-fdata-sections','-ffunction-sections',]

board_asmflags += board_opt_flagsboard_cxx_flags = board_cflagsboard_ld_flags = ['-T${ohos_root_path}device/board/alientek/explorer/liteos_m/STM32F407ZGTx_FLASH.ld']

board_ld_flags += board_opt_flags# Board related headfiles search 

path.board_include_dirs = [ '//utils/native/lite/include' ]# Board adapter dir 

for OHOS components.board_adapter_dir = ''这里的核心工作就是将原有的Makefile编译文件翻译成OH的

config.gni,可以看到有很多的编译参数以及宏变量定义。

修改编译依赖文件BUILD.gndevice/board/alientek/explorer/liteos_m/BUILD.gnimport('//kernel/liteos_m/liteos.gni')

module_name = get_path_info(rebase_path('.'), 'name')

kernel_module(module_name) 

{sources = ['startup_stm32f407xx.s','Src/main.c','Src/delay.c','Src/led.c','Src/sys.c','Src/usart.c','Src/stm32f4xx_hal_msp.c','

Src/stm32f4xx_it.c','Src/system_stm32f4xx.c',

]include_dirs = [ 'Inc',]}# '-Wl,-T' + rebase_path('STM32F407ZGTx_FLASH.ld'),

config('public') {ldflags = ['-Wl,-u_printf_float']libs = ['c','m','nosys',]}

device/soc/st/stm32f4xx/sdk/BUILD.gnimport('//kernel/liteos_m/liteos.gni')

module_name = 'stm32f4xx_sdk'kernel_module(module_name) 

{asmflags = board_asmflagssources = ['Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c','

Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c','Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c','

Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c','

Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c','

Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c','Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c','

Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c','Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c',]

include_dirs = ['//device/board/alientek/explorer/liteos_m/Inc']}#指定全局头文件搜索路径

config('public') {include_dirs = ['Drivers/STM32F4xx_HAL_Driver/Inc','Drivers/CMSIS/Device/ST/STM32F4xx/Include',]}

④改造 main 函数,拉起系统内核


我们对 device/board/alientek/explorer/liteos_m/Src/main.c 文件进行如下编辑:


int main(void)

{

HAL_Init();                         /* 初始化HAL库 */

sys_stm32_clock_init(336, 8, 2, 7); /* 初始化时钟频率168Mhz */

delay_init(168);                    /* 延时初始化 */

printf('hal、系统始终初始化完毕,开始启动系统...

');

RunTask();

}

void RunTask()

{

unsigned int ret;

ret = LOS_KernelInit();  // 初始化LiteOS系统

if (ret != LOS_OK)

{

printf('Liteos kernel init failed! ERROR: 0x%x

', ret);

}

else

{

LOS_Start(); // 启动系统

}

...

}


  编译与烧录

使用 hb 工具进行编译,hb set 选择编译目标,hb build -f 执行编译。

b87a80aa-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

日志输出 explorer build success 表示编译成功。 编译过程中可能会遇到缺少某些结构体或者函数的定义,需要细心排查,注意宏定义是否打开。 STM32F407 开发板支持串口和 ST-LINK 烧录方式,但 OH 编译出来的是 bin 文件,bin 无法直接通过串口烧录。

需要用到 ST-LINK 工具进行烧录,烧录时需要指定 flash,开始地址:0x08000000,大小:0x100000。

b89ddd8e-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

开始烧录:

b8d43e4c-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

点亮开发板:

b8f033ea-f7fb-11ed-90ce-dac502259ad0.png?imageView2/2/w/550

总结

本文主要讲述了 OpenHarmony 内核的 SoC 代码移植。因为 STM32F407 的架构和基础 SDK 都是官方开源的,所以移植工作也较为容易。 但在实际工作中如果遇到未开源的芯片,那么需要模组或芯片厂商提供技术支持才可完成移植工作。 到这里瘦设备 OH 适配的最核心工作已完成,希望能对热爱 OpenHarmony 的小伙伴有所帮助。  


关键字:移植 引用地址:浅析OpenHarmony内核SoC层级的移植适配流程

上一篇:将KEIL软件中数组数据导出的简单方法
下一篇:CH9434嵌入式Linux与安卓系统驱动移植和使用教程

推荐阅读最新更新时间:2026-02-21 11:54

OpenHarmony瘦设备内核移植实战(一)
背景 在各行各业存在很多不同的智能设备,每个设备都使用芯片去实现不同的业务场景需求。本文将以常用的STM32F407ZG芯片为例,介绍OpenHarmony瘦设备内核移植方法,希望能对热爱OpenHarmony的开发小伙伴有所帮助。 认识芯片架构、Soc、开发板 芯片架构是指芯片的内部器件构造以及对应的指令集,比如PC使用的英特尔i7或者AMD的R7-4800都是x86架构,手机使用的骁龙8Gen2芯片使用的则是ARM架构。 SoC是指具体的芯片架构实现,芯片厂商针对不同的应用场景开发出的芯片各不相同,但要符合架构定义,比如STM32F470就会有不同的定制版本,有些Flash会大一些,有些则是芯片封装或者引脚数
[单片机]
<font color='red'>OpenHarmony</font>瘦设备<font color='red'>内核</font><font color='red'>移植</font>实战(一)
什么是电机电驱适配流程适配流程通常包括哪些步骤?
电机电驱适配流程指的是将电机与电驱动系统相匹配的过程。在实际应用中,电机和电驱动器可能具有不同的特性,例如电压、功率、转速范围等。 因此,为了实现最佳性能、效率和稳定性,需要对它们进行适当的匹配和配置。 适配流程通常包括以下步骤: 规格分析 评估电机和电驱的技术规格,包括额定功率、额定电压、额定转速、最大扭矩等。 匹配电气特性 确保电机和电驱的电气参数相匹配,如电压、电流、频率等。 机械适配 确认机械接口和尺寸匹配,包括轴的尺寸和连接方式等。 控制匹配 确保电机参数与电驱控制系统相兼容,包括通讯协议、控制算法、传感方式等方面的匹配。 为什么电机电驱需要适配呢? 因为电机和电驱往往是一个系统中的关键部件,它们之间的适配程度直接影
[嵌入式]
ALINX技术教程:Zynq UltraScale+ MPSoC平台PYNQ 3.1.2系统移植指南
本教程于 Ubuntu22.04.1 虚拟机中搭建 Xilinx 2024.1 开发环境,并基于此环境从源码构建 PYNQ 3.1.2 工程,最终生成适用于 ALINX AXU15EGB 开发板的 PYNQ 系统镜像。 Zynq US+ oC + 10G 光纤 开发板AXU15EGB AXU15EGB 开发板: www.alinx.com/detail/261 资源链接: https://pan.baidu.com/s/1J1KnN_z404Skze42CUj7gQ 提取码: in8s 环境配置 提示: ubuntu、vis 和 vivo 安装的部分可以参考 ALINX 的教程文档《coue_s0
[嵌入式]
ALINX技术教程:Zynq UltraScale+ MPSoC平台PYNQ 3.1.2系统<font color='red'>移植</font>指南
STM32F407VET6开发板移植基于HAL库的正点原子LCD屏幕驱动
up的开发板长这个样子: 比较便宜XD 屏幕的话是2.8寸带触摸的TFT LCD屏幕,驱动是ILI9341。 首先,在CubeMX中创建初始化配置文件需要配置的选项如下图, (LED0,LED1与Key1,2,3,4与LCD驱动无关): 需要对RCC,SYS的固定配置以及时钟树的改动此处不作介绍。可看最后的参考文章链接。 首先配置LCD_BL,即背光控制相关的GPIO。管脚脚位选择需要看开发板的原理图。我的原理图是这样的: 可以看到需要将PB1配置为LCD_BL。 具体配置如下图: 之后配置FSMC: 此处LCD Register Select信号也需要看你的开发板原理图。我的是这样的: 可以
[单片机]
STM32F407VET6开发板<font color='red'>移植</font>基于HAL库的正点原子LCD屏幕驱动
STM32上移植nuttx操作系统
操作系统(Operating System),简称OS,是管理计算机硬件与软件资源的计算机程序,同时也是计算机系统的内核与基石。 根据计算机组成原理,计算机由CPU(运算器+控制器),存储器,输入,输出设备组成。 根据操作系统原理,OS由调度,内存管理,文件系统,进程间通信,计算机网络组成。 CPU对应OS的调度(Schedule); 内存对应OS的内存管理(Memory Management); 存储器对应OS的文件系统(File System); 输入/输出设备对应OS的驱动,也可以认为是文件系统(一切皆文件); 进程间通信(Internal Process communacation)是OS提供给应用程序的通信方式。 OS的
[单片机]
STM32上<font color='red'>移植</font>nuttx操作系统
freeRTOS V10.0.1移植到STM32F407标准库 - 环境Keil5
最近因为工作需要用到FreeRTOS,其实开始本人内心是拒绝的因为自己只学习过UCOSIII还没实际上过什么大又复杂的工程,但是谁让FreeRTOS他是Free的呢公司成本考虑肯定是不会选择USOS的,这个道理就像公司内心深处不想给你涨工资一样。好了跑偏了言归正传,既然要用自然是要熟悉一下这个实时操作的内核的工作过程了,说道到里想起来自己当初学USOC时是把代码几乎进行了逐行的走读,最后因为各种原因都没能实际使用最后还是忘记了,所以我建议对于这一类的操作系统的学习还是重在API函数的用法学习上,不需要太对代码集体实现细节进行研究,时间成本高有这个时间建议移植一个系统进行一些应用实践是最有实际效果的。因此我现在就在践行自己的经验移植
[单片机]
freeRTOS V10.0.1<font color='red'>移植</font>到STM32F407标准库 - 环境Keil5
STM32F407工程移植--STM32F401,F400
最近做的项目,遇到问题以及解决方法 1、jlink总是下载失败,PC可以识别,但是keil不识别 解决办法:将工程中的和jlink相关的文件删掉,keil魔术棒中set键,弹出框,重新选择芯片型号,还有的时候是没有上电(囧) 2、stm32f407改为stm32f401步骤 (1)改启动文件,将工程中的启动文件.s文件修改,点击魔术棒--C/C++--Define中对应修改名称(将STM32F40-41xxx改为STM32F401xxx,和启动文件名一致) (2)更改器件型号,点击魔术棒-device中修改器件型号 (3)修改stm32f4xx.h中搜索#ifdef STM32F40xx后面 #define STM32F40-41
[单片机]
玩玩littlevgl移植到stm32
一,前言 周日下午没事儿做,那么继续我的图形图像学习之路,之前弄了一段时间上位机开发,还是回归老本行,嵌入式开发吧~从游戏引擎(HMI)部分来说,我觉得他们设计的核心思路应该是一样的。所以我继续先研究小而精的c代码。毕竟cocos2dx是游戏行业专属,我所在的汽车行业要用HMI引擎,貌似用的也是公司自己开发,或QT或Kanzi等。那么我想先看小而精的代码,从而学习其底层设计思路,所以选择littlevgl继续进行源码进阶学习。 二,lvgl在stm32F4开发板上移植 之前蜻蜓点水的方式,在PC上使用过了lvgl,然后简单的分析了下代码。 GUI库lvgl应用及分析--Apple的学习笔记 和 GUI库lvgl源码分析--Appl
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved