香橙派(OrangePi)折腾笔记
docker镜像编译环境(最大限度做到开箱即用)
docker镜像
docker pull swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:1.0.0
挂载镜像
也可以挂载本地镜像
docker load -i xxxx.tar
挂载镜像并启动容器
docker image
这里我的image_id为31f50584dab1
名称为
docker run -it -p 8070:8070 -v /Users/workspace/Downloads/inner:/tmp --privileged=true swr.cn-south-1.myhuaweicloud.com/openharmony-docker/openharmony-docker:1.0.0 /bin/bash
核对清单
- 交叉编译工具链:(ohos-docker自带的)
arm-linux-gnueabi-addr2line arm-linux-gnueabi-gcov arm-linux-gnueabi-strings arm-none-eabi-gcov-dump
arm-linux-gnueabi-ar arm-linux-gnueabi-gcov-7 arm-linux-gnueabi-strip arm-none-eabi-gcov-tool
arm-linux-gnueabi-as arm-linux-gnueabi-gcov-dump arm-none-eabi-addr2line arm-none-eabi-gprof
arm-linux-gnueabi-c++filt arm-linux-gnueabi-gcov-dump-7 arm-none-eabi-ar arm-none-eabi-ld
arm-linux-gnueabi-cpp arm-linux-gnueabi-gcov-tool arm-none-eabi-as arm-none-eabi-ld.bfd
arm-linux-gnueabi-cpp-7 arm-linux-gnueabi-gcov-tool-7 arm-none-eabi-c++ arm-none-eabi-nm
arm-linux-gnueabi-dwp arm-linux-gnueabi-gprof arm-none-eabi-c++filt arm-none-eabi-objcopy
arm-linux-gnueabi-elfedit arm-linux-gnueabi-ld arm-none-eabi-cpp arm-none-eabi-objdump
arm-linux-gnueabi-gcc arm-linux-gnueabi-ld.bfd arm-none-eabi-elfedit arm-none-eabi-ranlib
arm-linux-gnueabi-gcc-7 arm-linux-gnueabi-ld.gold arm-none-eabi-g++ arm-none-eabi-readelf
arm-linux-gnueabi-gcc-ar arm-linux-gnueabi-nm arm-none-eabi-gcc arm-none-eabi-size
arm-linux-gnueabi-gcc-ar-7 arm-linux-gnueabi-objcopy arm-none-eabi-gcc-6.3.1 arm-none-eabi-strings
arm-linux-gnueabi-gcc-nm arm-linux-gnueabi-objdump arm-none-eabi-gcc-ar arm-none-eabi-strip
arm-linux-gnueabi-gcc-nm-7 arm-linux-gnueabi-ranlib arm-none-eabi-gcc-nm
arm-linux-gnueabi-gcc-ranlib arm-linux-gnueabi-readelf arm-none-eabi-gcc-ranlib
arm-linux-gnueabi-gcc-ranlib-7 arm-linux-gnueabi-size arm-none-eabi-gcov
全志H3为Cortex-A7,类比I.MX6U-ALPHA(https://www.cnblogs.com/zhaipanger/p/12811546.html),
交叉编译器选择4.9版本的arm-linux-gnueabihf用于编译uboot(ohos-docker).
显然需要安装一份4.9的交叉编译器。下载地址[https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/arm-linux-gnueabihf/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz].
mkdir ./arm-gcc
传送文件到/tmp/arm-gcc目录(挂载到本地计算机上了)
cd /tmp/arm-gcc
tar -vxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz
vi /etc/profile
export PATH=$PATH:/tmp/arm-gcc/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin
source /etc/profile
验证安装
arm-linux-gnueabihf-gcc -v
TODO:打包一份配置好的镜像
小贴士
ctrl+c 退出容器并关闭容器
ctrl+p+q 退出不关闭容器
git拉取“开鸿3.1标准版”系统源码
定义开发板
[https://zhuanlan.zhihu.com/p/451023889]
名词解释
product“嵌入式产品名” | device“SoC名称” | vendor“嵌入式制造商” | socvendor“SoC制造商” |
---|---|---|---|
orangepi-one | AllwinnnerH3 | orangepi | Allwinner |
DDR | Double Data Rate(DDR SDRAM) | 是一种SDRAM |
大致移植步骤
bootloader(u-boot)
定义SoC
新建文件OpenHarmony/productdefine/common/device/allwinner-h3.json
{
"device_name": "allwinner-h3",
"device_company": "allwinner",
"target_os": "ohos",
"target_cpu": "arm",
"kernel_version": "",
"device_build_path": "device/allwinner/build"
}
定义产品
新建文件OpenHarmony/productdefine/common/products/orangepi-one.json
{
"product_name": "orangepi-one",
"product_company": "orangepi",
"product_device": "allwinner-h3",
"version": "2.0",
"type": "standard",
"product_build_path": "device/allwinner/build",
"parts": {
...
"allwinner_products:allwinner_products":{},
...
}
}
定义键值对
修改文件OpenHarmony/build/subsystem_config.json
加入键值对
"allwinner_products":{
"project": "hmf/allwinner_products",
"path": "device/allwinner/allwinner-h3/build",
"name": "allwinner_products",
"dir": "device/allwinner"
},
TODO:屏幕、hdmi、声音、麦克风、按钮驱动,参考香橙派写法,uboot
bootloader(u-boot)移植
笔者使用香橙派提供的2020.04版本uboot进行移植。
[https://www.cnblogs.com/zengjfgit/p/5139546.html]
mkdir /tmp/uboot
解压缩uboot源码到该目录
cd /tmp/uboot
修改/tmp/uboot/configs/orangepi_one_defconfig
CONFIG_ARM=y
CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=624
CONFIG_DRAM_ZQ=3881979
CONFIG_DRAM_ODT_EN=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-one"
CONFIG_SUN8I_EMAC=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_VIDEO_DE2=n
CONFIG_USE_BOOTARGS=y
CONFIG_CMDLINE=y #命令行模式
CONFIG_SYS_PROMPT=y #命令行模式提示符
# CONFIG_HUSH_PARSER=y #使用hush shell 来对命令进行解析
CONFIG_CMD_HDMIDETECT=y
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="run distro_bootcmd"
CONFIG_LED=y #可用于点亮版载的两个LED灯
CONFIG_BOOTARGS="console=ttymxc0,115200 init=/init video=mxcfb1:dev=hdmi,1024x768M@30\0"
(注.config文件中有所有的CONFIG_选项)
笔者的HDMI显示器是1024x768,因而通过BOOTARGS设置分辨率而不用启动时手动设置。
[https://blog.csdn.net/hanmengaidudu/article/details/16983263]
如果通过上面两步,在环境变量中没有正确地解析出参数,代码会到bootargs(也就是传递给内核的cmdline)中找相关参数,在bootargs中的格式必须是:
video=ctfb❌800,y:480,depth:16,le:2,ri:2,up:2,lo:2,hs:41,vs:4,pclk:50000,vmode:0,sync:0
加粗的字体是必须的,这个看了 video_get_params 函数你就明白了。
这种情况可以灵活配置,并且这些参数会通过tagged-list--->cmdline主动传递给内核,适用于uboot和内核共享ENV区参数的情况。
而对于在上面我在mini6410中实现的代码,其实可以移植到别的芯片启动中去,只要将参数解析到struct ctfb_res_modes 中去,其中的数据就可以用于初始化LCD控制器等初始化代码中了
让LED闪烁[https://blog.csdn.net/u012577474/article/details/102808798]
orangepi-one的PA15引脚为STATUS-LED
编译uboot为.img文件
(备注:SUNXI指的就是全志的SoC)
生成.config文件
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- orangepi_one_defconfig
()[https://img-blog.csdnimg.cn/20200620190426798.png]
然后输入
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
报错scripts/dtc/pylibfdt/libfdt_wrap.c:149:11: fatal error: Python.h: No such file or directory
apt-get update
python -V
apt install python3.8-dev
[http://nano.lichee.pro/step_by_step/three_uboot.html]
报错没有swig
apt-get install swig
测试uboot文件
编译生产的文件在/tmp/uboot/u-boot.img还有u-boot-dtb.img
u-boot对设备树的支持: 传递dtb给内核[https://www.cnblogs.com/tureno/articles/14723488.html]
TODO:启动时显示logo,板载LED闪烁
linux内核移植
[https://blog.csdn.net/qq_41943585/article/details/124132737]
概述(一下用OH简称OpenHarmony)
OH内核态层 = 标准LTS Linux内核 + 三方SoC芯片平台代码 + OH内核态基础代码 + OH内核态特性
但是我们知道直接是同OH Linux内核 支持的第三方芯片不够丰富,我们可以借助已经有的第三方Linux内核来移植OpenHarmony
本文用香橙派提供的linux内核来移植。
内核态的基础代码移植
拷贝/tmp/ohos/kernel/linux/linux-5.10/drivers/staging/hievent和/tmp/ohos/kernel/linux/linux-5.10/drivers/staging/hilog到/tmp/orangepi-one-linux/drivers/staging目录下
在同目录下的Kconfig文件内增加代码:
source "drivers/staging/hilog/Kconfig"
source "drivers/staging/hievent/Kconfig"
必选特性HDF移植
打HDF补丁
./patch_hdf.sh [工程根目录路径] [内核目录路径] [hdf补丁文件]
patch_hdf.sh位置/tmp/ohos/drivers/adapter/khdf/linux/patch_hdf.sh
工程根目录路径/tmp/ohos
内核目录路径/tmp/orangepi-one-linux
hdf补丁文件/tmp/ohos/kernel/linux/patches/linux-5.10/hi3516dv300_patch/hdf.patch
注意:这里orangepi给的是linux-5.4的内核,而补丁是针对linux-5.10的
/tmp/ohos/drivers/adapter/khdf/linux/patch_hdf.sh /tmp/ohos /tmp/orangepi-one-linux /tmp/ohos/kernel/linux/patches/linux-5.10/hi3516dv300_patch/hdf.patch
执行结果为
patching file arch/arm64/kernel/vmlinux.lds.S
Hunk #1 succeeded at 193 with fuzz 2 (offset -8 lines).
patching file arch/arm/kernel/vmlinux.lds.S
Hunk #1 succeeded at 121 (offset -10 lines).
patching file drivers/Kconfig
Hunk #1 FAILED at 234.
1 out of 1 hunk FAILED -- saving rejects to file drivers/Kconfig.rej
patching file drivers/Makefile
Hunk #1 FAILED at 188.
1 out of 1 hunk FAILED -- saving rejects to file drivers/Makefile.rej
patching file drivers/hdf/Makefile
patching file drivers/hid/Makefile
patching file drivers/hid/hid-core.c
Hunk #2 succeeded at 1515 (offset -10 lines).
Hunk #3 succeeded at 1926 (offset -10 lines).
Hunk #4 succeeded at 2090 (offset -13 lines).
Hunk #5 succeeded at 2108 (offset -13 lines).
Hunk #6 succeeded at 2196 (offset -13 lines).
patching file drivers/hid/hid-input.c
Hunk #2 succeeded at 1414 (offset -8 lines).
Hunk #3 succeeded at 1863 (offset -18 lines).
Hunk #4 succeeded at 1983 (offset -18 lines).
patching file drivers/input/mousedev.c
patching file include/linux/hid.h
Hunk #1 succeeded at 618 (offset -4 lines).
可以看到有两个失败的,我们需要一一处理。
错误的提示在/tmp/orangepi-one-linux/drivers/Kconfig.rej及Makfile.rej
Kconfig.rej提示:
+source "drivers/hdf/khdf/Kconfig"
+
手动对比/tmp/ohos及/tmp/orangepi-one-linux中的相应文件,然后作对应修改。
然后/tmp/orangepi-one-linux/drivers/hdf/Kconfig
添加如下项:
# 需要配置的选项如下
#CONFIG_DRIVERS_HDF=y
#CONFIG_HDF_SUPPORT_LEVEL=2
#CONFIG_DRIVERS_HDF_PLATFORM=y
#CONFIG_DRIVERS_HDF_PLATFORM_MIPI_DSI=y
#CONFIG_DRIVERS_HDF_PLATFORM_GPIO=y
#CONFIG_DRIVERS_HDF_PLATFORM_I2C=y
#CONFIG_DRIVERS_HDF_PLATFORM_UART=y
#CONFIG_DRIVERS_HDF_TEST=y
以上移植HDF方法行不通
必选特性HDF移植(2)
待续
移植轻开鸿OpenHarmonyLite(未完待续)
另一种方案是直接修改ohos的linux5.10内核,添加orangepi-one的驱动。
[https://blog.csdn.net/aa120515692/article/details/122854618]移植"轻开鸿"
移植思路
- ARCH移植
- SoC移植
- board移植
ARCH架构移植
orangepi-one的全志H3为ARM Cortex-A7架构
/tmp/ohos/kernel/liteos_m/arch/arm
可以看到没有Cortex-A7文件夹,但是IoT Studio中有提供Cortex-A7的架构.
[https://www.cnblogs.com/huaweiyun/p/15402904.html]
[https://www.jianshu.com/p/9e2b189d0b20]
[https://gitee.com/LiteOS/LiteOS/blob/master/doc/LiteOS_Code_Info.md]
[https://blog.51cto.com/harmonyos/5166573]
(嵌入式移植)[https://www.100ask.net/detail/p_5fcf586ae4b04db7c0939c82/8?product_id=p_5fcf586ae4b04db7c0939c82]
cortex-a7的位数
[https://blog.csdn.net/baidu_31437863/article/details/82944521]
[https://tech.hqew.com/news_1360941]
cortex-a7应该是32位
lite-os提供帮助
[https://gitee.com/LiteOS/LiteOS/tree/master/arch/arm/cortex_a_r]
liteos提供了有关cortex-a系列的架构
liteos_a和linux对标,因而移植具有一定复杂度,本文针对liteos_m移植芯片架构.
(ARCH移植)[https://www.huoban.com/news/post/18492.html]
(指令集移植指北)[https://zhuanlan.zhihu.com/p/431519224]
新增文件
新增/tmp/ohos/kernel/liteos_m/arch/arm/cortex-a7目录
在/tmp/ohos/kernel/liteos_m/arch/arm/Kconfig对应地方新增:
config ARCH_CORTEX_A7
bool
select ARCH_ARM_V7A
select ARCH_ARM_AARCH32
select ARCH_FPU_VFP_V4
select ARCH_FPU_VFP_D32
select ARCH_FPU_VFP_NEON
对应地方新增:
config ARCH_ARM_V7A
bool
修改为:
config ARCH_ARM_VER
string
default "armv7-m" if ARCH_ARM_V7M
default "armv5te" if ARCH_ARM_V5TE
default "armv7-a" if ARCH_ARM_V7A
修改为:
config ARCH_CPU
string
default "cortex-m3" if ARCH_CORTEX_M3
default "cortex-m4" if ARCH_CORTEX_M4
default "cortex-m7" if ARCH_CORTEX_M7
default "cortex-m33" if ARCH_CORTEX_M33
default "cortex-m55" if ARCH_CORTEX_M55
default "arm9" if ARCH_ARM9
default "cortex-a7" if ARCH_CORTEX_A7
依据:
指令集选择:
VFP Hardware选择:
NEON选择:
(备注:全志H3是双核arm cortex-a7,而有些SoC是异构多核,对于异构多核SoC,需要通过OpenAMP来进行分解成多个同构多核的部分)
照葫芦画瓢
(arm参考文献)[https://developer.arm.com/documentation/ddi0464/f/]
对照隔壁文件夹cortex-m7修改cortex-a7文件夹.
首先开始检查BUILD.gn文件,看看引用了哪些文件.
- a.异常文件-los_exc.S
- b.调度代码-los_dispatch.S
- c.系统中断文件-los_interrupt.c
- d.定时器文件-los_timer.c
- e.任务上下文(内核任务栈)-los_context.c
f.内存保护单元(MPU)-los_mpu.c
名词:Floating-Point Unit (FPU)
(FPU)[https://developer.arm.com/documentation/ddi0463/f/?lang=en]
(NEON)[https://developer.arm.com/documentation/ddi0462/f/?lang=en]
cortex-a7/gcc/los_arch_context.h
TODO:核对寄存器
cortex-a7/gcc/los_context.c
TODO:核对地址
cortex-a7/gcc/los_arch_interrupt.h
TODO:核对寄存器地址
cortex-a7/gcc/los_exc.S
TODO:核对
.arch armv7a
.fpu fpv4-d32-neon
cortex-a7/gcc/los_dispatch.S
TODO:核对
.arch armv7a
.fpu fpv4-d32-neon
添加一个SoC
新建/tmp/ohos/device/soc/allwinner
仿照bestechnic文件夹构造文件
TODO:全志标准库文件下载
/tmp/ohos/device/soc/allwinner/Kconfig.liteos_m.soc
config SOC_COMPANY_Allwinner
bool
if SOC_COMPANY_Allwinner
config SOC_COMPANY
default "allwinner"
rsource "*/Kconfig.liteos_m.soc"
endif # SOC_COMPANY_Allwinner
allwinner/Kconfig.liteos_m.series
rsource "*/Kconfig.liteos_m.series"
allwinner/Kconfig.liteos_m.defconfig
rsource "*/Kconfig.liteos_m.defconfig.series"
allwinner/allwinner-h3/Kconfig.liteos_m.series
config SOC_SERIES_Allwinner_H
bool "Allwinner H chip"
select ARM
select SOC_COMPANY_Allwinner
select CPU_CORTEX_A7
help
Enable support for Allwinner H series
allwinner/allwinner-h3/Kconfig.liteos_m.defconfig.series
if SOC_SERIES_Allwinner_H
rsource "Kconfig.liteos_m.defconfig.allwinner-h3"
config SOC_SERIES
string
default "allwinner-h3"
config NUM_IRQS
int
default 960
# Enables a Cortex-A7 MPCore processor to access the status of IRQS[479:0] signals on the Distributor.
config SYS_CLOCK_HW_CYCLES_PER_SEC
int
default 48000000
endif
# TODO:检查时钟频率
allwinner/allwinner-h3/Kconfig.liteos_m.defconfig.allwinner-h3
config SOC
string
default "allwinner-h3"
depends on SOC_Allwinner_H3
allwinner/allwinner-h3/liteos_m/target_config.h
import("//kernel/liteos_m/liteos.gni")
module_name = get_path_info(rebase_path("."), "name")
module_group(module_name) {
modules = [
"sdk",
"components",
]
}
TODO:完善这里
添加一个board
新建/tmp/ohos/device/board/orangepi
仿造fnlink文件夹构造文件
board/orangepi/BUILD.gn
文件夹board/orangepi/orangepi-one
board/orangepi/orangepi-one/Kconfig.liteos_m.board
config BOARD_ORANGEPI_ONE
bool "select board orangepi-one"
depends on SOC_Allwinner_H3
同目录下的Kconfig.liteos_m.defconfig.board
if BOARD_ORANGEPI_ONE
config BOARD
string
default "orangepi-one"
endif #BOARD_ORANGEPI_ONE
同目录下的orangepi-one_defconfig
LOSCFG_BOARD_ORANGEPI_ONE=y
LOSCFG_SOC_Allwinner_H3=y
同目录下的liteos_m/config.gni
kernel_type = "liteos_m"
kernel_version = "3.0.0"
board_cpu = "cortex-a7"
board_arch = "armv7-a"
board_toolchain = "arm-none-eabi-gcc"
board_toolchain_path = ""
board_toolchain_prefix = "arm-none-eabi-"
board_toolchain_type = "gcc"
添加hb编译选项
新建/tmp/ohos/vendor/orangepi
仿照bearpi的文件夹新建文件
/tmp/ohos/vendor/orangepi/orangepi-one/config.json
{
"product_name": "orangepi-one",
"type": "mini",
"version": "1.0",
"device_company": "orangepi",
"board": "orangepi-one",
"kernel_type": "liteos_m",
"kernel_version": "",
"subsystems": [
{
"subsystem": "kernel",
"components": [
{ "component": "liteos_m",
"features":[
]
}
]
}
],
"third_party_dir": "",
"product_adapter_dir": ""
}
orangepi-one/BUILD.gn
group("orangepi-one") {
}
cd /tmp/ohos
输入hb set可以看到orangepi-one的编译选项了,选择orangepi-one选项
cd /tmp/ohos/kernel/liteos_m
make menuconfig
退出保存
配置启动文件与链接
[https://qidicloud.blog.csdn.net/article/details/122854549]
对于全志H3,无片内flash,代码存放在外部。由香橙派原理图,tf卡连接到了H3芯片的SD0(SDC0_D1等)接口,对应地址为0x01C0F000---0x01C0FFFF,size:4KB.香橙派one的RAM有两片(256+256 DDR3),接在H3的DRAMC0接口,映射到了0x40000000---0xBFFFFFFF,size:2GB.SRAM A1地址0x00000000---0x0000FFFF,size:64KB.SRAM A2地址0x00044000---0x0004BFFF,size:32KB.SRAM C地址0x00010000---0x0001AFFF,size:44KB.
启动文件orangepi/orangepi-one/sdk/startup.s
TODO:检查
链接脚本orangepi/orangepi-one/hrst.ld
摘要:
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0K
FLASH (rx) : ORIGIN = 0x01C0F000, LENGTH = 4K
}
TODO:检查
指定链接参数
orangepi/orangepi-one/liteos_m/config.gni
摘要:
board_ld_flags = [ "-L${ohos_root_path}out/${board_name}/${product_name}/hrst.ld" ] #指定链接脚本
newlib库(C库)移植
[https://qidicloud.blog.csdn.net/article/details/122854565]
cd /tmp/ohos/kernel/liteos_m
make menuconfig选择Compat选择Choose libc implementation选择newlibc。
malloc适配实现 _malloc_r, _realloc_r, _reallocf_r, _free_r, _memalign_r, 和 _malloc_usable_size_r。这种方法中,内存分配函数可以使用内核的.
内核的实现为/tmp/ohos/kernel/liteos_m/kal/libc/newlib/porting/src/malloc.c,在ohos/device/board/orangepi/orangepi-one/liteos_m/config.gni新增对这些函数的wrap链接.
if (wrap_fs_api == "true") {
board_ld_flags += [
"-Wl,--wrap=_calloc_r",
"-Wl,--wrap=_malloc_r",
"-Wl,--wrap=_realloc_r",
"-Wl,--wrap=_reallocf_r",
"-Wl,--wrap=_free_r",
"-Wl,--wrap=_memalign_r",
"-Wl,--wrap=_malloc_usable_size_r",
"-Wl,--wrap=printf",
"-Wl,--wrap=sprintf",
"-Wl,--wrap=snprintf",
"-Wl,--wrap=vsnprintf",
"-Wl,--wrap=vprintf",
]
}
新建device/soc/allwinner/allwinner-h3/liteos_m/components/printf.c
TODO:参考 https://sourceware.org/newlib/libc.html#vfprintf ,实现 vprintf, vfprintf, printf, snprintf 和sprintf。
函数调用关系:printf调用_out_char调用__io_putchar
新建device/soc/allwinner/allwinner-h3/liteos_m/components/uart.c
TODO:实现__io_putchar函数
原型:
int __io_putchar(int ch){
usart_data_transmit(USART0,(uint8_t)ch);
while(RESET==usart_flag_get(USART0,USART_FLAG_TBE));
return ch;
}
内核初始化和启动
device/board/orangepi/orangepi-one/sdk/main.c
TODO:检查文件
#include "los_config.h"
#include "los_debug.h"
#include "los_interrupt.h"
#include "los_task.h"
#include "los_tick.h"
VOID TaskSample(VOID);
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
UINT32 ret;
//GPIO初始化
GPIO_Init();
//串口初始化
USART1_UART_Init();
//内核初始化
ret = LOS_KernelInit();
printf("Lian Zhian 13510979604\r\n");
printf("Open Harmony 3.3 start ...\r\n\r\n");
if (ret == LOS_OK) {
#if (LOSCFG_USE_SHELL == 1)
LosShellInit();
OsShellInit();
#endif
//创建自己的线程
TaskSample();
//启动OpenHarmony OS 内核
LOS_Start();
}
while (1)
{
}
/* USER CODE END 3 */
}
//线程2,用于点灯和打印
VOID TaskSampleEntry2(VOID)
{
printf("______>>>>>>>>> %s %d\r\n", __FILE__, __LINE__);
led_init();
while (1) {
printf("___>>>>>> %s %d\r\n", __FILE__, __LINE__);
led_on(0);
led_on(1);
led_on(2);
led_on(3);
LOS_TaskDelay(1000);
led_off(0);
led_off(1);
led_off(2);
led_off(3);
LOS_TaskDelay(1000);
}
}
//线程1,用于打印
VOID TaskSampleEntry1(VOID)
{
printf("______>>>>>>>>> %s %d\r\n", __FILE__, __LINE__);
while (1) {
printf("___>>>>>> %s %d\r\n", __FILE__, __LINE__);
LOS_TaskDelay(1000);
}
}
//创建线程
VOID TaskSample(VOID)
{
UINT32 uwRet;
UINT32 taskID1;
UINT32 taskID2;
UINT32 taskID3;
TSK_INIT_PARAM_S stTask = {0};
stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry1;
stTask.uwStackSize = 0x1000;
stTask.pcName = "TaskSampleEntry1";
stTask.usTaskPrio = 6; /* Os task priority is 6 */
uwRet = LOS_TaskCreate(&taskID1, &stTask);
if (uwRet != LOS_OK) {
printf("Task1 create failed\r\n");
}
stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskSampleEntry2;
stTask.uwStackSize = 0x1000;
stTask.pcName = "TaskSampleEntry2";
stTask.usTaskPrio = 7; /* Os task priority is 7 */
uwRet = LOS_TaskCreate(&taskID2, &stTask);
if (uwRet != LOS_OK) {
printf("Task2 create failed\r\n");
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
编译
hb build -f
烧录和测试
编译输出文件在/tmp/ohos/out/orangepi/orangepi-one/OHOS_Image.bin
参考香橙派烧录tf卡教程
orangepi-one的linux内核的驱动移植到OHOS Linux
dts设备树文件
[https://zhuanlan.zhihu.com/p/425420889]
设备树文件是关于硬件的描述性信息(板级文件代码),可以方便地描述寄存器、中断号和上一层gpio节点。
文档位置documentation/devicetree/bingdings/arm
dtsi文件为类似c语言.h文件的头文件
板级设备树文件
/tmp/orangepi-one-linux/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts为orangepi-one的设备树文件
而在/tmp/ohos/kernel/linux/linux-5.10/arch/arm/boot/dts也本来就有sun8i-h3-orangepi-one.dts的设备树文件.
leds {
compatible = "gpio-leds";
pwr_led {
label = "orangepi:green:pwr";
gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
status_led {
label = "orangepi:red:status";
gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>;
};
};
可以看到已经完全配置好了。
[https://zhuanlan.zhihu.com/p/458598879]
配置ohos编译选项(ohos-standard-orangepi-one)
/tmp/ohos/vendor/orangepi/orangepi-one/config.json
{
"product_name": "orangepi-one",
"type": "standard",
"version": "3.0",
"device_company": "orangepi",
"board": "orangepi-one",
"target_cpu":"arm",
"build_selinux":true,
"inherit": [ "productdefine/common/inherit/rich.json", "productdefine/common/inherit/chipset_common.json" ],
"subsystems": [
{
"subsystem": "security",
"components": [
{
"component": "selinux",
"features": []
}
]
},
{
"subsystem": "arkui",
"components": [
{
"component": "ace_engine",
"features": [
"ace_engine_feature_enable_accessibility = true",
"ace_engine_feature_enable_web = true"
]
}
]
}
]
}
编译orangepi-one-linux系统
安装官方build环境
Ubuntu18.04
zsync是一个基于 HTTP协议的文件同步(rsync)工具,通过它可以从远程的Web服务器上同步文件的改动。它可以仅下载 ISO 镜像新的部分。
链接:https://pan.baidu.com/s/1vWQmCmSYdH7iCDFyKpJtVw 提取码:zero
百度云盘上的orangepi-build.tar.gz压缩包除了包含orangepi-build编译系统的代 码外,还缓存了交叉编译工具链,u-boot 和 linux 内核的源码。所以在编译镜像的过 程中就不会去 github 服务器上从头开始下载 u-boot 和 linux 内核的源码以及交叉编 译工具链,这样可以节省大量的时间。orangepi-build 编译系统开始运行时,默认会 自动从 github 同步 u-boot 和 linux 内核的源码,以确保代码为最新状态,所以无需 手动同步 u-boot 和 linux 内核的源码
其他说明详见官方手册