OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)

zh_ff
发布于 2023-3-17 10:58
浏览
0收藏

版本:v3.2 Beta

安装Hi3861开发板特有环境

除上述​​安装库和工具集​​​和​​安装编译工具​​外,针对Hi3861开发板还需要安装特定的编译工具。

工具要求

表1 Hi3861 WLAN模组需要安装的编译工具

开发工具

用途

SCons3.0.4+

编译构建工具

python模块:setuptools、kconfiglib、pycryptodome、six、ecdsa

编译构建工具

gcc riscv32

编译构建工具

操作步骤

相关操作在Ubuntu环境下进行。

安装Scons

1.运行如下命令,安装SCons安装包。

python3 -m pip install scons

2.运行如下命令,查看是否安装成功。如果安装成功,查询结果下图所示。

scons -v

图1 SCons安装成功界面,版本要求3.0.4以上

安装python模块

1.运行如下命令,安装python模块setuptools。

pip3 install setuptools

2.安装GUI menuconfig工具(Kconfiglib),建议安装Kconfiglib 13.2.0+版本,任选如下一种方式。

●   命令行方式:

sudo pip3 install kconfiglib

●   安装包方式:

●   下载.whl文件(例如:kconfiglib-13.2.0-py2.py3-none-any.whl)。 下载路径:“​​https://pypi.org/project/kconfiglib#files​​”

●   运行如下命令,安装.whl文件。

sudo pip3 install kconfiglib-13.2.0-py2.py3-none-any.whl

3.安装pycryptodome,任选如下一种方式。
安装升级文件签名依赖的Python组件包,包括:pycryptodome、six、ecdsa。安装ecdsa依赖six,请先安装six,再安装ecdsa。

●   命令行方式:

sudo pip3 install pycryptodome

●   安装包方式:

●    下载.whl文件(例如:pycryptodome-3.9.9-cp38-cp38-manylinux1_x86_64.whl)。 下载路径:“​​https://pypi.org/project/pycryptodome/#files​​”。

●   运行如下命令,安装.whl文件。

sudo pip3 install pycryptodome-3.9.9-cp38-cp38-manylinux1_x86_64.whl

4.安装six,任选如下一种方式。

●   命令行方式:

sudo pip3 install six --upgrade --ignore-installed six

●   安装包方式:

●   下载.whl文件(例如:six-1.12.0-py2.py3-none-any.whl)。 下载路径:“​​https://pypi.org/project/six/#files​​”

●   运行如下命令,安装.whl文件。

sudo pip3 install six-1.12.0-py2.py3-none-any.whl

4.安装ecdsa,任选如下一种方式。

●   命令行方式:

sudo pip3 install ecdsa

●   安装包方式:

●   下载.whl文件(例如:ecdsa-0.14.1-py2.py3-none-any.whl)。 下载路径:“​​https://pypi.org/project/ecdsa/#files​​”

●   运行如下命令,安装.whl文件。

sudo pip3 install ecdsa-0.14.1-py2.py3-none-any.whl

安装gcc_riscv32(WLAN模组类编译工具链) 

须知:●   Hi3861开发板平台仅支持使用libgcc运行时库的静态链接,不建议开发者使用libgcc运行时库的动态链接,以免产品需遵从GPLV3许可证。

●   通过下述步骤2-14,编译好了gcc_riscv32镜像,提供给开发者​​直接下载​​使用。直接下载gcc_riscv32镜像的开发者可省略下述2-14步。

1.打开Linux编译服务器终端。

2.下载riscv-gnu-toolchain交叉编译工具链。

git clone --recursive https://gitee.com/mirrors/riscv-gnu-toolchain.git

3.打开文件夹riscv-gnu-toolchain,先删除空文件夹,以防止下载newlib,binutils,gcc时冲突。

cd riscv-gnu-toolchain && rm -rf riscv-newlib && rm -rf riscv-binutils && rm -rf riscv-gcc

4.下载riscv-newlib-3.0.0。

git clone -b riscv-newlib-3.0.0 https://github.com/riscv/riscv-newlib.git

5.下载riscv-binutils-2.31.1。

git clone -b riscv-binutils-2.31.1 https://github.com/riscv/riscv-binutils-gdb.git

6.下载riscv-gcc-7.3.0。

git clone -b riscv-gcc-7.3.0 https://github.com/riscv/riscv-gcc

7.添加riscv-gcc-7.3.0补丁。 访问gcc官方补丁链接​​89411​​​,​​86724​​,按照补丁链接中要求的修改,手动将变更添加到对应的.c和.h文件中,注意由于patch版本与下载的gcc版本有所偏差,行数有可能对应不上,请自行查找patch中的关键字定位到对应行。

8.下载​​GMP 6.1.2​​,并解压安装。

tar -xvf gmp-6.1.2.tar.bz2 && mkdir build_gmp && cd build_gmp && ../gmp-6.1.2/configure --prefix=/usr/local/gmp-6.1.2 --disable-shared --enable-cxx && make && make install

9.下载​​mpfr-4.0.2 ​​,并解压安装。

tar -xvf mpfr-4.0.2.tar.gz && mkdir build_mpfr && cd build_mpfr && ../mpfr-4.0.2/configure --prefix=/usr/local/mpfr-4.0.2 --with-gmp=/usr/local/gmp-6.1.2 --disable-shared && make && make install

10.下载​​mpc-1.1.0​​ ,并解压安装。

tar -xvf mpc-1.1.0.tar.gz && mkdir build_mpc && cd build_mpc && ../mpc-1.1.0/configure --prefix=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 --disable-shared && make && make install

11.打开文件夹riscv-gnu-toolchain,新建工具链输出目录。

cd /opt && mkdir gcc_riscv32

12.编译binutils。

mkdir build_binutils && cd build_binutils && ../riscv-binutils-gdb/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32/riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd ..

13.编译newlib。

mkdir build_newlib && cd build_newlib && ../riscv-newlib/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" \CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --bindir=/opt/gcc_riscv32/bin --libexecdir=/opt/gcc_riscv32 --libdir=/opt/gcc_riscv32 --includedir=/opt/gcc_riscv32 && make -j16 && make install && cd ..

14.编译gcc。

mkdir build_gcc && cd build_gcc && ../riscv-gcc/configure --prefix=/opt/gcc_riscv32 --target=riscv32-unknown-elf --with-arch=rv32imc --with-abi=ilp32 --disable-__cxa_atexit --disable-libgomp --disable-libmudflap --enable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-multilib --enable-poison-system-directories --enable-languages=c,c++ --with-gnu-as --with-gnu-ld --with-newlib --with-system-zlib CFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" CXXFLAGS="-fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack -fPIE" LDFLAGS="-Wl,-z,relro,-z,now,-z,noexecstack" CXXFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" CFLAGS_FOR_TARGET="-Os -mcmodel=medlow -Wall -fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -fno-short-enums -fno-short-wchar" --with-headers="/opt/gcc-riscv32/riscv32-unknown-elf/include" --with-mpc=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp-6.1.2 --with-mpfr=/usr/local/mpfr-4.0.2 && make -j16 && make install

15.设置环境变量。

说明:

 如果直接采用编译好的riscv32 gcc包,请先执行以下命令将压缩包解压到根目录:

tar -xvf gcc_riscv32-linux-7.3.0.tar.gz -C ~

vim ~/.bashrc

将以下命令拷贝到.bashrc文件的最后一行,保存并退出。

export PATH=~/gcc_riscv32/bin:$PATH

16.生效环境变量。

source ~/.bashrc

17.Shell命令行中输入如下命令,如果能正确显示编译器版本号,表明编译器安装成功。

riscv32-unknown-elf-gcc -v

编写“Hello World”程序

下方将通过修改源码的方式展示如何编写简单程序,输出“Hello world”。请在下载的源码目录中进行下述操作。

1.确定目录结构。
开发者编写业务时,务必先在./applications/sample/wifi-iot/app路径下新建一个目录(或一套目录结构),用于存放业务源码文件。
例如:在app下新增业务my_first_app,其中hello_world.c为业务代码,BUILD.gn为编译脚本,具体规划目录结构如下:

.
└── applications
    └── sample
        └── wifi-iot
            └── app
                └── my_first_app
                  │── hello_world.c
                  └── BUILD.gn

2.编写业务代码。
新建./applications/sample/wifi-iot/app/my_first_app下的hello_world.c文件,在hello_world.c中新建业务入口函数HelloWorld,并实现业务逻辑。并在代码最下方,使用OpenHarmony启动恢复模块接口SYS_RUN()启动业务。(SYS_RUN定义在ohos_init.h文件中)

#include <stdio.h>
#include "ohos_init.h"
#include "ohos_types.h"

void HelloWorld(void)
{
    printf("[DEMO] Hello world.\n");
}
SYS_RUN(HelloWorld);

3.编写用于将业务构建成静态库的BUILD.gn文件。
新建./applications/sample/wifi-iot/app/my_first_app下的BUILD.gn文件,并完成如下配置。
如步骤1所述,BUILD.gn文件由三部分内容(目标、源文件、头文件路径)构成,需由开发者完成填写。

static_library("myapp") {
    sources = [
        "hello_world.c"
    ]
    include_dirs = [
        "//utils/native/lite/include"
    ]
}

●   static_library中指定业务模块的编译结果,为静态库文件libmyapp.a,开发者根据实际情况完成填写。

●   sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//“则表示绝对路径(此处为代码根路径),若不包含”//"则表示相对路径。

●   include_dirs中指定source所需要依赖的.h文件路径。

4.添加新组件。
修改文件build/lite/components/communication.json,添加组件hello_world_app的配置,如下所示为communication.json文件片段,"##start##“和”##end##“之间为新增配置(”##start##“和”##end##"仅用来标识位置,添加完配置后删除这两行):

{
  "components": [
    {
      "component": "camera_sample_communication",
      "description": "Communication related samples.",
      "optional": "true",
      "dirs": [
        "applications/sample/camera/communication"
      ],
      "targets": [
        "//applications/sample/camera/communication:sample"
      ],
      "rom": "",
      "ram": "",
      "output": [],
      "adapted_kernel": [ "liteos_a" ],
      "features": [],
      "deps": {
        "components": [],
        "third_party": []
      }
    },
##start##
    {
      "component": "hello_world_app",
      "description": "hello world samples.",
      "optional": "true",
      "dirs": [
        "applications/sample/wifi-iot/app/my_first_app"
      ],
      "targets": [
        "//applications/sample/wifi-iot/app/my_first_app:myapp"
      ],
      "rom": "",
      "ram": "",
      "output": [],
      "adapted_kernel": [ "liteos_m" ],
      "features": [],
      "deps": {
        "components": [],
        "third_party": []
      }
    },
##end##
    {
      "component": "camera_sample_app",
      "description": "Camera related samples.",
      "optional": "true",
      "dirs": [
        "applications/sample/camera/launcher",
        "applications/sample/camera/cameraApp",
        "applications/sample/camera/setting",
        "applications/sample/camera/gallery",
        "applications/sample/camera/media"
      ],

5.修改单板配置文件。
修改文件vendor/hisilicon/hispark_pegasus/config.json,新增hello_world_app组件的条目,如下所示代码片段为applications子系统配置,"##start##“和”##end##“之间为新增条目(”##start##“和”##end##"仅用来标识位置,添加完配置后删除这两行):


{
        "subsystem": "applications",
        "components": [
##start##
          { "component": "hello_world_app", "features":[] },
##end##
          { "component": "wifi_iot_sample_app", "features":[] }
        ]
      },

编译

OpenHarmony支持hb和build.sh两种编译方式。此处介绍hb方式,build.sh脚本编译方式请参考​​使用build.sh脚本编译源码​​。

想要详细了解OpenHarmony编译构建模块功能的开发者可参考​​编译构建指南​​。

前提条件

操作步骤

在Ubuntu环境下进入源码根目录,执行如下命令进行编译:

1.设置编译路径。

hb set

2.选择当前路径。

.

3.在hisilicon下选择wifiiot_hispark_pegasus并回车。

说明:

同样的开发板在适配不同的场景时,要采用的编译形态不同(即此处要选择的product不同),请参考​​编译形态整体说明​​。

图1 Hi3861编译设置图例

OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)-鸿蒙开发者社区

4.执行编译。

说明:

  • 单独编译一个部件(例如hello),可使用“hb build -T目标名称”进行编译。
  • 增量编译整个产品,可使用“hb build”进行编译。
  • 完整编译整个产品,可使用“hb build -f”进行编译。

此处以完整编译整个产品为例进行说明。

hb build -f

5.编译结束后,出现“build success”字样,则证明构建成功。 

须知:

 编译结果文件及编译日志获取路径:out/hispark_pegasus/wifiiot_hispark_pegasus。

烧录

针对Hi3861开发板,除了DevEco Device Tool(操作方法请参考​​烧录​​)外,还可以使用Hiburn进行烧录。

前提条件

  • 开发板相关源码已编译完成,已形成烧录文件。
  • 客户端(操作平台,例如Windows系统)已下载并安装​​HiBurn工具​​。
  • 客户端(操作平台,例如Windows系统)已安装USB驱动,可参考​​USB驱动安装指导​​。
  • 客户端已安装串口终端工具(例如IPOP)。
  • 使用USB线缆连接客户端与开发板。

操作步骤

1.准备烧录相关文件。

1.在客户端新建用于保存烧录文件的文件夹,例如“D:\hi3861”。

2.将编译完成的源码包下载至客户端并解压,将烧录相关文件拷贝至步骤1中新建的文件夹。 烧写所需文件为:Hi3861_wifiiot_app_allinone.bin、Hi3861_loader_signed.bin

2.使用HiBurn烧录。

1.打开HiBurn。

      2.设置HiBurn参数,根据实际情况选择COM口,勾选“Select all”和“Auto burn”。
图1 HiBurn烧写界面参数设置

OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)-鸿蒙开发者社区

    3.单击Select file在步骤1创建的文件夹中选择烧写文件Hi3861_wifiiot_app_allinone.bin。
图2 hiburn文件选择完成

OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)-鸿蒙开发者社区

      4.确保COM口选择正确,然后单击Connect后,按一下开发板上串口旁的按钮(Reset键)开始烧写。 烧录开始后,可以在HiBurn工具下方的控制台区域观察到烧录过程中的打印信息。
烧录完成后,控制台区域会打印提示"Execution Successful"。
图3 单击"Connect"后

OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)-鸿蒙开发者社区

  • 图4单击开发板重置按键后,烧写中

OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)-鸿蒙开发者社区

  • 图5烧写完成


OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)-鸿蒙开发者社区

5.单击Disconnect断开连接。

运行

联网配置

由于Hi3861为WLAN模组,您可以在版本编译及烧录后,通过如下操作,使开发板实现联网功能。

1.保持Windows工作台和Hi3861 WLAN模组的连接状态,确认串口终端显示正常。

2.复位Hi3861 WLAN模组,终端界面显示“ready to OS start”,则启动成功。
图1 Hi3861 WLAN模组复位成功示意图

OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)-鸿蒙开发者社区

3.依次执行如下AT命令,启动STA模式,连接指定AP热点,并开启DHCP功能。

AT+STARTSTA                             # 启动STA模式
AT+SCAN                                 # 扫描周边AP
AT+SCANRESULT                           # 显示扫描结果
AT+CONN="SSID",,2,"PASSWORD"            # 连接指定AP,其中SSID/PASSWORD为待连接的热点名称和密码
AT+STASTAT                              # 查看连接结果
AT+DHCP=wlan0,1                         # 通过DHCP向AP请求wlan0的IP地址

4.查看Hi3861 WLAN模组与网关联通是否正常,如下图所示。

AT+IFCFG                                # 查看模组接口IP
AT+PING=X.X.X.X                         # 检查模组与网关的联通性,其中X.X.X.X需替换为实际的网关地址

图2 Hi3861 WLAN模组联网成功示意图   

OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)-鸿蒙开发者社区

调测验证

完成烧录及联网之后,用户可根据需要进行调试验证。目前调试验证的方法有以下两种,开发者可以根据具体业务情况选择。

  1. 通过printf打印日志
  2. 通过asm文件定位panic问题

由于本示例业务简单,采用printf打印日志的调试方式即可。下方将介绍这两种调试手段的使用方法。

printf打印

代码中增加printf维测,信息会直接打印到串口上。开发者可在业务关键路径或业务异常位置增加日志打印,如下所示:

void HelloWorld(void)
{
    printf("[DEMO] Hello world.\n");
}
根据asm文件进行问题定位

系统异常退出时,会在串口上打印异常退出原因调用栈信息,如下文所示。通过解析异常栈信息可以定位异常位置。

=======KERNEL PANIC=======
**Call Stack*
Call Stack 0 -- 4860d8 addr:f784c
Call Stack 1 -- 47b2b2 addr:f788c
Call Stack 2 -- 3e562c addr:f789c
Call Stack 3 -- 4101de addr:f78ac
Call Stack 4 -- 3e5f32 addr:f78cc
Call Stack 5 -- 3f78c0 addr:f78ec
Call Stack 6 -- 3f5e24 addr:f78fc
Call Stack end***

为解析上述调用栈信息,需要使用到Hi3861_wifiiot_app.asm文件,该文件记录了代码中函数在Flash上的符号地址以及反汇编信息。asm文件会随版本打包一同构建输出,存放在./out/wifiiot/路径下。

1.将调用栈CallStack信息保存到txt文档中,以便于编辑。(可选)

2.打开asm文件,并搜索CallStack中的地址,列出对应的函数名信息。通常只需找出前几个栈信息对应的函数,就可明确异常代码方向。

Call Stack 0 -- 4860d8 addr:f784c -- WadRecvCB
Call Stack 1 -- 47b2b2 addr:f788c -- wal_sdp_process_rx_data
Call Stack 2 -- 3e562c addr:f789c
Call Stack 3 -- 4101de addr:f78ac
Call Stack 4 -- 3e5f32 addr:f78cc
Call Stack 5 -- 3f78c0 addr:f78ec
Call Stack 6 -- 3f5e24 addr:f78fc

3.根据以上调用栈信息,可以定位WadRecvCB函数中出现了异常。

OpenHarmony设备开发基于命令行开发轻量系统(基于Hi3861开发板)-鸿蒙开发者社区

4.完成代码排查及修改。

运行结果

示例代码编译、烧录、运行、调测后,重启开发板后将自动在界面输出如下结果:

ready to OS start
FileSystem mount ok.
wifi init success!
[DEMO] Hello world.


文章转载自:​​https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/device-dev/quick-start/quickstart-pkg-3861-tool.md/​


收藏
回复
举报
回复
    相关推荐