香橙派(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

核对清单

  1. 交叉编译工具链:(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]移植"轻开鸿"

移植思路

  1. ARCH移植
  2. SoC移植
  3. 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文件,看看引用了哪些文件.

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 内核的源码
其他说明详见官方手册

posted @ 2022-08-17 02:51  qsBye  阅读(2081)  评论(0编辑  收藏  举报