提交 86673b15 编写于 作者: N NEEN

!134 Docs Update 0924

* Description: update docs 0924
上级 03766390
文件模式从 100755 更改为 100644
# 组件开发 # 组件开发
- [组件开发指南](组件开发指南.md)
- [概述](概述.md)
- [准备工作](准备工作.md)
- [组件开发](组件开发.md)
- [组件开发规范](组件开发规范.md) - [组件开发规范](组件开发规范.md)
- [概述](概述-0.md) - [概述](概述.md)
- [组件构成](组件构成.md) - [组件构成](组件构成.md)
- [组件管理](组件管理.md) - [组件管理](组件管理.md)
- [组件版本](组件版本.md) - [组件版本](组件版本.md)
- [发行版](发行版.md) - [发行版](发行版.md)
- [环境变量说明](环境变量说明.md) - [环境变量说明](环境变量说明.md)
- [组件开发指南](组件开发指南.md)
- [概述](概述-0.md)
- [准备工作](准备工作.md)
- [组件开发](组件开发.md)
...@@ -62,7 +62,7 @@ hpm-cli的命令介绍可以参考:[hpm操作命令](组件管理.md#table1051 ...@@ -62,7 +62,7 @@ hpm-cli的命令介绍可以参考:[hpm操作命令](组件管理.md#table1051
## 下载OpenHarmony代码<a name="section102338221707"></a> ## 下载OpenHarmony代码<a name="section102338221707"></a>
参考[《源码获取》](zh-cn_topic_0000001050769927.md) 参考[《源码获取》](../get-code/源码获取.md)
## 安装开发依赖的组件<a name="section19233183315020"></a> ## 安装开发依赖的组件<a name="section19233183315020"></a>
......
# 概述<a name="ZH-CN_TOPIC_0000001051452141"></a> # 概述<a name="ZH-CN_TOPIC_0000001051452100"></a>
本文档将介绍组件的基本概念以及如何按照规范定义组件。 本章节将简要介绍如何开发OpenHarmony组件和发行版,并通过命令行工具方式完成组件创建、开发、编译、烧录、调试等开发过程。
## 定义<a name="section177563344911"></a> - 一个组件(bundle)通常和一个代码仓库对应,在代码的基础上增加bundle.json、README文件、LICENSE描述文件。
- 一个发行版(distribution)是由多个组件构成的。发行版中集合了一个完整系统的各种组件(如驱动、内核、框架、应用),可以用于设备的烧录。
OpenHarmony软件以组件\(bundle\)作为基本单元,从系统角度看,凡是运行在OpenHarmony上的软件都可以定义为组件;一般来讲,根据组件的应用范围,可以分为:
**表 1** 组件和发行版的差异对比
- 板级组件:如board、arch、mcu这些与设备硬件相关的组件。
- 系统组件:一组独立功能的集合,如内核、文件系统、框架等。 <a name="table6287133615412"></a>
- 应用组件:直接面向用户提供服务的应用\(如wifi\_iot,ip\_camera\) <table><thead align="left"><tr id="row17288183614415"><th class="cellrowborder" valign="top" width="16.24162416241624%" id="mcps1.2.4.1.1"><p id="p528818361545"><a name="p528818361545"></a><a name="p528818361545"></a>异同点</p>
</th>
从形式上看,组件是为复用而生,一切可以复用的模块都可以定义为组件,可以分为: <th class="cellrowborder" valign="top" width="33.31333133313331%" id="mcps1.2.4.1.2"><p id="p1288836247"><a name="p1288836247"></a><a name="p1288836247"></a>组件</p>
</th>
- 源代码 <th class="cellrowborder" valign="top" width="50.44504450445044%" id="mcps1.2.4.1.3"><p id="p112885362418"><a name="p112885362418"></a><a name="p112885362418"></a>发行版</p>
- 二进制 </th>
- 代码片段 </tr>
- 发行版 </thead>
<tbody><tr id="row1728813361848"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p2010613564815"><a name="p2010613564815"></a><a name="p2010613564815"></a>应用场景</p>
## 组件划分原则<a name="section2487162541016"></a> </td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1910555184818"><a name="p1910555184818"></a><a name="p1910555184818"></a>面向功能特性开发</p>
原则上应尽可能划分为细颗粒度的组件,以满足最大限度的复用。主要考虑以下几点: </td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p13871955484"><a name="p13871955484"></a><a name="p13871955484"></a>面向系统开发</p>
- 独立性:组件的功能应该相对独立,支持独立编译,可以单独对外提供接口和服务; </td>
- 耦合性:如果组件必须依赖其他的组件,才能对外提供服务,应考虑和被依赖的组件合并为一个组件。 </tr>
- 相关性:如果一组组件共同完成一项功能,且没有被其他组件依赖,未来也没有被依赖的可能,则可以考虑合并为一个组件。 <tr id="row676745614472"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p1028816365414"><a name="p1028816365414"></a><a name="p1028816365414"></a>内容</p>
</td>
## 组件依赖<a name="section185955409107"></a> <td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p428812361042"><a name="p428812361042"></a><a name="p428812361042"></a>功能或特性的实现代码或二进制库</p>
</td>
组件的依赖关系分为两种:必选依赖和可选依赖。 <td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p328817366417"><a name="p328817366417"></a><a name="p328817366417"></a>依赖的组件清单及编译构建脚本</p>
</td>
- 必选依赖:是指组件A在完成某个功能时,必须引入组件B,调用B的接口或服务配合才能完成。称B为A的必选依赖。 </tr>
- 可选依赖:是在组件A在完成某个功能时,可以引入组件C,也可以引入组件D。C和D可以相互替换,称C和D为A的可选依赖。 <tr id="row95114356"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p184894513517"><a name="p184894513517"></a><a name="p184894513517"></a>完整程度</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1951741155"><a name="p1951741155"></a><a name="p1951741155"></a>操作系统的一部分</p>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p20521542512"><a name="p20521542512"></a><a name="p20521542512"></a>一个完整操作系统版本</p>
</td>
</tr>
<tr id="row13581419518"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p859171059"><a name="p859171059"></a><a name="p859171059"></a>编译后结果</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p259201355"><a name="p259201355"></a><a name="p259201355"></a>组件包</p>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p459414519"><a name="p459414519"></a><a name="p459414519"></a>系统镜像</p>
</td>
</tr>
</tbody>
</table>
**图 1** 组件和发行版的构成<a name="fig85033524124"></a>
![](figures/zh-cn_image_0000001054663940.png)
# 概述<a name="ZH-CN_TOPIC_0000001051452100"></a> # 概述<a name="ZH-CN_TOPIC_0000001051452141"></a>
本章节将简要介绍如何开发OpenHarmony组件和发行版,并通过命令行工具方式完成组件创建、开发、编译、烧录、调试等开发过程。 本文档将介绍组件的基本概念以及如何按照规范定义组件。
- 一个组件(bundle)通常和一个代码仓库对应,在代码的基础上增加bundle.json、README文件、LICENSE描述文件。 ## 定义<a name="section177563344911"></a>
- 一个发行版(distribution)是由多个组件构成的。发行版中集合了一个完整系统的各种组件(如驱动、内核、框架、应用),可以用于设备的烧录。
OpenHarmony软件以组件\(bundle\)作为基本单元,从系统角度看,凡是运行在OpenHarmony上的软件都可以定义为组件;一般来讲,根据组件的应用范围,可以分为:
**表 1** 组件和发行版的差异对比
- 板级组件:如board、arch、mcu这些与设备硬件相关的组件。
<a name="table6287133615412"></a> - 系统组件:一组独立功能的集合,如内核、文件系统、框架等。
<table><thead align="left"><tr id="row17288183614415"><th class="cellrowborder" valign="top" width="16.24162416241624%" id="mcps1.2.4.1.1"><p id="p528818361545"><a name="p528818361545"></a><a name="p528818361545"></a>异同点</p> - 应用组件:直接面向用户提供服务的应用\(如wifi\_iot,ip\_camera\)
</th>
<th class="cellrowborder" valign="top" width="33.31333133313331%" id="mcps1.2.4.1.2"><p id="p1288836247"><a name="p1288836247"></a><a name="p1288836247"></a>组件</p> 从形式上看,组件是为复用而生,一切可以复用的模块都可以定义为组件,可以分为:
</th>
<th class="cellrowborder" valign="top" width="50.44504450445044%" id="mcps1.2.4.1.3"><p id="p112885362418"><a name="p112885362418"></a><a name="p112885362418"></a>发行版</p> - 源代码
</th> - 二进制
</tr> - 代码片段
</thead> - 发行版
<tbody><tr id="row1728813361848"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p2010613564815"><a name="p2010613564815"></a><a name="p2010613564815"></a>应用场景</p>
</td> ## 组件划分原则<a name="section2487162541016"></a>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1910555184818"><a name="p1910555184818"></a><a name="p1910555184818"></a>面向功能特性开发</p>
</td> 原则上应尽可能划分为细颗粒度的组件,以满足最大限度的复用。主要考虑以下几点:
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p13871955484"><a name="p13871955484"></a><a name="p13871955484"></a>面向系统开发</p>
</td> - 独立性:组件的功能应该相对独立,支持独立编译,可以单独对外提供接口和服务;
</tr> - 耦合性:如果组件必须依赖其他的组件,才能对外提供服务,应考虑和被依赖的组件合并为一个组件。
<tr id="row676745614472"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p1028816365414"><a name="p1028816365414"></a><a name="p1028816365414"></a>内容</p> - 相关性:如果一组组件共同完成一项功能,且没有被其他组件依赖,未来也没有被依赖的可能,则可以考虑合并为一个组件。
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p428812361042"><a name="p428812361042"></a><a name="p428812361042"></a>功能或特性的实现代码或二进制库</p> ## 组件依赖<a name="section185955409107"></a>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p328817366417"><a name="p328817366417"></a><a name="p328817366417"></a>依赖的组件清单及编译构建脚本</p> 组件的依赖关系分为两种:必选依赖和可选依赖。
</td>
</tr> - 必选依赖:是指组件A在完成某个功能时,必须引入组件B,调用B的接口或服务配合才能完成。称B为A的必选依赖。
<tr id="row95114356"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p184894513517"><a name="p184894513517"></a><a name="p184894513517"></a>完整程度</p> - 可选依赖:是在组件A在完成某个功能时,可以引入组件C,也可以引入组件D。C和D可以相互替换,称C和D为A的可选依赖。
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1951741155"><a name="p1951741155"></a><a name="p1951741155"></a>操作系统的一部分</p>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p20521542512"><a name="p20521542512"></a><a name="p20521542512"></a>一个完整操作系统版本</p>
</td>
</tr>
<tr id="row13581419518"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p859171059"><a name="p859171059"></a><a name="p859171059"></a>编译后结果</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p259201355"><a name="p259201355"></a><a name="p259201355"></a>组件包</p>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p459414519"><a name="p459414519"></a><a name="p459414519"></a>系统镜像</p>
</td>
</tr>
</tbody>
</table>
**图 1** 组件和发行版的构成<a name="fig85033524124"></a>
![](figures/zh-cn_image_0000001054663940.png)
# 组件开发指南<a name="ZH-CN_TOPIC_0000001053617944"></a> # 组件开发指南<a name="ZH-CN_TOPIC_0000001053617944"></a>
- **[概述](概述.md)** - **[概述](概述-0.md)**
- **[准备工作](准备工作.md)** - **[准备工作](准备工作.md)**
......
# 组件开发规范<a name="ZH-CN_TOPIC_0000001053017947"></a> # 组件开发规范<a name="ZH-CN_TOPIC_0000001053017947"></a>
- **[概述](概述-0.md)** - **[概述](概述.md)**
- **[组件构成](组件构成.md)** - **[组件构成](组件构成.md)**
......
...@@ -214,14 +214,14 @@ hpm dependencies ...@@ -214,14 +214,14 @@ hpm dependencies
</td> </td>
<td class="cellrowborder" valign="top" width="30.623062306230626%" headers="mcps1.2.4.1.2 "><p id="p9291492204"><a name="p9291492204"></a><a name="p9291492204"></a>hpm gen-keys</p> <td class="cellrowborder" valign="top" width="30.623062306230626%" headers="mcps1.2.4.1.2 "><p id="p9291492204"><a name="p9291492204"></a><a name="p9291492204"></a>hpm gen-keys</p>
</td> </td>
<td class="cellrowborder" valign="top" width="48.42484248424842%" headers="mcps1.2.4.1.3 "><p id="p429249182012"><a name="p429249182012"></a><a name="p429249182012"></a>生成公钥/私钥对,将公钥配置到HPM服务端,可以实现hpm-cli</p> <td class="cellrowborder" valign="top" width="48.42484248424842%" headers="mcps1.2.4.1.3 "><p id="p429249182012"><a name="p429249182012"></a><a name="p429249182012"></a>生成公钥/私钥对,将公钥配置到HPM服务端,可以实现hpm-cli 免密登录,发布组件。</p>
</td> </td>
</tr> </tr>
<tr id="row3556450102011"><td class="cellrowborder" valign="top" width="20.95209520952095%" headers="mcps1.2.4.1.1 "><p id="p35561850172015"><a name="p35561850172015"></a><a name="p35561850172015"></a>生成第三方开源说明</p> <tr id="row3556450102011"><td class="cellrowborder" valign="top" width="20.95209520952095%" headers="mcps1.2.4.1.1 "><p id="p35561850172015"><a name="p35561850172015"></a><a name="p35561850172015"></a>生成第三方开源说明</p>
</td> </td>
<td class="cellrowborder" valign="top" width="30.623062306230626%" headers="mcps1.2.4.1.2 "><p id="p1155625018209"><a name="p1155625018209"></a><a name="p1155625018209"></a>hpm gen-notice</p> <td class="cellrowborder" valign="top" width="30.623062306230626%" headers="mcps1.2.4.1.2 "><p id="p1155625018209"><a name="p1155625018209"></a><a name="p1155625018209"></a>hpm gen-notice</p>
</td> </td>
<td class="cellrowborder" valign="top" width="48.42484248424842%" headers="mcps1.2.4.1.3 "><p id="p11557175015205"><a name="p11557175015205"></a><a name="p11557175015205"></a>根据每个组件的说明,生成一份合并后的第三方开源说明的合并文件</p> <td class="cellrowborder" valign="top" width="48.42484248424842%" headers="mcps1.2.4.1.3 "><p id="p11557175015205"><a name="p11557175015205"></a><a name="p11557175015205"></a>根据每个组件的说明,生成一份合并后的第三方开源说明的合并文件</p>
</td> </td>
</tr> </tr>
</tbody> </tbody>
......
# Bundle Development # Bundle Development
- [Development Guidelines](development-guidelines.md)
- [Overview](overview.md)
- [Preparations](preparations.md)
- [Bundle Development](bundle-development.md)
- [Development Specifications](development-specifications.md) - [Development Specifications](development-specifications.md)
- [Overview](overview-0.md) - [Overview](overview.md)
- [Bundle Composition](bundle-composition.md) - [Bundle Composition](bundle-composition.md)
- [Bundle Management](bundle-management.md) - [Bundle Management](bundle-management.md)
- [Bundle Version](bundle-version.md) - [Bundle Version](bundle-version.md)
- [Distribution](distribution.md) - [Distribution](distribution.md)
- [Environment Variables](environment-variables.md) - [Environment Variables](environment-variables.md)
- [Development Guidelines](development-guidelines.md)
- [Overview](overview-0.md)
- [Preparations](preparations.md)
- [Bundle Development](bundle-development.md)
...@@ -214,7 +214,7 @@ You can use the hpm-cli tool to manage the lifecycle of a bundle. The following ...@@ -214,7 +214,7 @@ You can use the hpm-cli tool to manage the lifecycle of a bundle. The following
</td> </td>
<td class="cellrowborder" valign="top" width="30.623062306230626%" headers="mcps1.2.4.1.2 "><p id="p9291492204"><a name="p9291492204"></a><a name="p9291492204"></a>hpm gen-keys</p> <td class="cellrowborder" valign="top" width="30.623062306230626%" headers="mcps1.2.4.1.2 "><p id="p9291492204"><a name="p9291492204"></a><a name="p9291492204"></a>hpm gen-keys</p>
</td> </td>
<td class="cellrowborder" valign="top" width="48.42484248424842%" headers="mcps1.2.4.1.3 "><p id="p429249182012"><a name="p429249182012"></a><a name="p429249182012"></a>Generates a public-private key pair and configures the public key on the hpm server to enable <strong id="b139191811163315"><a name="b139191811163315"></a><a name="b139191811163315"></a>hpm-cli</strong>.</p> <td class="cellrowborder" valign="top" width="48.42484248424842%" headers="mcps1.2.4.1.3 "><p id="p429249182012"><a name="p429249182012"></a><a name="p429249182012"></a>Generates a public-private key pair and configures the public key on the hpm server, achieving password-free <strong id="b139191811163315"><a name="b139191811163315"></a><a name="b139191811163315"></a>hpm-cli</strong> login for bundle publishing.</p>
</td> </td>
</tr> </tr>
<tr id="row3556450102011"><td class="cellrowborder" valign="top" width="20.95209520952095%" headers="mcps1.2.4.1.1 "><p id="p35561850172015"><a name="p35561850172015"></a><a name="p35561850172015"></a>Generating third-party open source notice</p> <tr id="row3556450102011"><td class="cellrowborder" valign="top" width="20.95209520952095%" headers="mcps1.2.4.1.1 "><p id="p35561850172015"><a name="p35561850172015"></a><a name="p35561850172015"></a>Generating third-party open source notice</p>
......
# Development Guidelines<a name="EN-US_TOPIC_0000001053617944"></a> # Development Guidelines<a name="EN-US_TOPIC_0000001053617944"></a>
- **[Overview](overview.md)** - **[Overview](overview-0.md)**
- **[Preparations](preparations.md)** - **[Preparations](preparations.md)**
......
# Development Specifications<a name="EN-US_TOPIC_0000001053017947"></a> # Development Specifications<a name="EN-US_TOPIC_0000001053017947"></a>
- **[Overview](overview-0.md)** - **[Overview](overview.md)**
- **[Bundle Composition](bundle-composition.md)** - **[Bundle Composition](bundle-composition.md)**
......
# Overview<a name="EN-US_TOPIC_0000001051452141"></a> # Overview<a name="EN-US_TOPIC_0000001051452100"></a>
This document describes the basic concepts of a bundle and how to define it in compliance with specifications. This document describes how to develop OpenHarmony bundles and distributions, and how to create, develop, and build code, as well as burn and debug devices by using a command line tool.
## Definition<a name="section177563344911"></a> - A bundle usually maps onto a code repository, which is a code archive with the **bundle.json**, **README**, and **LICENSE** files.
- A distribution consists of multiple bundles. Each distribution integrates various bundles of a comprehensive system, such as the driver, kernel, framework, and applications. These bundles can be used for device burning.
OpenHarmony software is developed on a per-bundle basis. In terms of the operating system, all software running on OpenHarmony are bundles. Generally, bundles are classified into the following types based on their application scopes:
**Table 1** Differences between a bundle and a distribution
- Board-level bundles: device hardware-specific bundles, such as **board**, **arch**, and **mcu**
- System-level bundles: a set of bundles with independent features, such as the kernel, file system, and framework <a name="table6287133615412"></a>
- Application-level bundles: applications that provide services to users, such as **wifi\_iot** and **ip\_camera** <table><thead align="left"><tr id="row17288183614415"><th class="cellrowborder" valign="top" width="16.24162416241624%" id="mcps1.2.4.1.1"><p id="p528818361545"><a name="p528818361545"></a><a name="p528818361545"></a>Aspect</p>
</th>
Bundles are designed for the reuse purpose. Any reusable modules can be defined as bundles. They are classified into the following types based on their forms: <th class="cellrowborder" valign="top" width="33.31333133313331%" id="mcps1.2.4.1.2"><p id="p1288836247"><a name="p1288836247"></a><a name="p1288836247"></a>Bundle</p>
</th>
- Source code <th class="cellrowborder" valign="top" width="50.44504450445044%" id="mcps1.2.4.1.3"><p id="p112885362418"><a name="p112885362418"></a><a name="p112885362418"></a>Distribution</p>
- Binary system </th>
- Code snippet </tr>
- Distribution </thead>
<tbody><tr id="row1728813361848"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p2010613564815"><a name="p2010613564815"></a><a name="p2010613564815"></a>Application scenario</p>
## Bundle Division Principles<a name="section2487162541016"></a> </td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1910555184818"><a name="p1910555184818"></a><a name="p1910555184818"></a>Feature-oriented</p>
In principle, bundles should be grouped at a fine-grained granularity as much as possible to achieve maximum reuse. The following factors are taken into account regarding bundle division: </td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p13871955484"><a name="p13871955484"></a><a name="p13871955484"></a>System-oriented</p>
- Independence: Bundles provide relatively independent features and can be independently compiled. Each of them is capable of providing its own APIs and services for external systems. </td>
- Coupling: If a bundle must depend on another bundle to provide services, they can be coupled to one bundle. </tr>
- Correlation: If a group of bundles jointly implement a feature, and if other bundles never depend on them, the group of bundles can be combined into one bundle. <tr id="row676745614472"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p1028816365414"><a name="p1028816365414"></a><a name="p1028816365414"></a>Content</p>
</td>
## Bundle Dependency<a name="section185955409107"></a> <td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p428812361042"><a name="p428812361042"></a><a name="p428812361042"></a>Codes or a binary library for implementing features</p>
</td>
A bundle dependency can be mandatory or optional. <td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p328817366417"><a name="p328817366417"></a><a name="p328817366417"></a>List of dependent bundles as well as their compiling and building scripts</p>
</td>
- Mandatory dependency: If bundle A must depend on bundle B to implement a feature, that is, the APIs or services specific to bundle B must be invoked, then bundle B is defined as the mandatory dependency of bundle A. </tr>
- Optional dependency: If either bundle C or bundle D is required for bundle A to implement a feature, and if bundle C and bundle D are interchangeable, then bundle C and bundle D are defined as optional dependencies of bundle A. <tr id="row95114356"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p184894513517"><a name="p184894513517"></a><a name="p184894513517"></a>Integrity</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1951741155"><a name="p1951741155"></a><a name="p1951741155"></a>A part of the operating system</p>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p20521542512"><a name="p20521542512"></a><a name="p20521542512"></a>An entire operating system</p>
</td>
</tr>
<tr id="row13581419518"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p859171059"><a name="p859171059"></a><a name="p859171059"></a>Compilation result</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p259201355"><a name="p259201355"></a><a name="p259201355"></a>Bundles</p>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p459414519"><a name="p459414519"></a><a name="p459414519"></a>System image</p>
</td>
</tr>
</tbody>
</table>
**Figure 1** Composition of bundles and distributions<a name="fig85033524124"></a>
![](figures/en-us_image_0000001054663940.png)
# Overview<a name="EN-US_TOPIC_0000001051452100"></a> # Overview<a name="EN-US_TOPIC_0000001051452141"></a>
This document describes how to develop OpenHarmony bundles and distributions, and how to create, develop, and build code, as well as burn and debug devices by using a command line tool. This document describes the basic concepts of a bundle and how to define it in compliance with specifications.
- A bundle usually maps onto a code repository, which is a code archive with the **bundle.json**, **README**, and **LICENSE** files. ## Definition<a name="section177563344911"></a>
- A distribution consists of multiple bundles. Each distribution integrates various bundles of a comprehensive system, such as the driver, kernel, framework, and applications. These bundles can be used for device burning.
OpenHarmony software is developed on a per-bundle basis. In terms of the operating system, all software running on OpenHarmony are bundles. Generally, bundles are classified into the following types based on their application scopes:
**Table 1** Differences between a bundle and a distribution
- Board-level bundles: device hardware-specific bundles, such as **board**, **arch**, and **mcu**
<a name="table6287133615412"></a> - System-level bundles: a set of bundles with independent features, such as the kernel, file system, and framework
<table><thead align="left"><tr id="row17288183614415"><th class="cellrowborder" valign="top" width="16.24162416241624%" id="mcps1.2.4.1.1"><p id="p528818361545"><a name="p528818361545"></a><a name="p528818361545"></a>Aspect</p> - Application-level bundles: applications that provide services to users, such as **wifi\_iot** and **ip\_camera**
</th>
<th class="cellrowborder" valign="top" width="33.31333133313331%" id="mcps1.2.4.1.2"><p id="p1288836247"><a name="p1288836247"></a><a name="p1288836247"></a>Bundle</p> Bundles are designed for the reuse purpose. Any reusable modules can be defined as bundles. They are classified into the following types based on their forms:
</th>
<th class="cellrowborder" valign="top" width="50.44504450445044%" id="mcps1.2.4.1.3"><p id="p112885362418"><a name="p112885362418"></a><a name="p112885362418"></a>Distribution</p> - Source code
</th> - Binary system
</tr> - Code snippet
</thead> - Distribution
<tbody><tr id="row1728813361848"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p2010613564815"><a name="p2010613564815"></a><a name="p2010613564815"></a>Application scenario</p>
</td> ## Bundle Division Principles<a name="section2487162541016"></a>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1910555184818"><a name="p1910555184818"></a><a name="p1910555184818"></a>Feature-oriented</p>
</td> In principle, bundles should be grouped at a fine-grained granularity as much as possible to achieve maximum reuse. The following factors are taken into account regarding bundle division:
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p13871955484"><a name="p13871955484"></a><a name="p13871955484"></a>System-oriented</p>
</td> - Independence: Bundles provide relatively independent features and can be independently compiled. Each of them is capable of providing its own APIs and services for external systems.
</tr> - Coupling: If a bundle must depend on another bundle to provide services, they can be coupled to one bundle.
<tr id="row676745614472"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p1028816365414"><a name="p1028816365414"></a><a name="p1028816365414"></a>Content</p> - Correlation: If a group of bundles jointly implement a feature, and if other bundles never depend on them, the group of bundles can be combined into one bundle.
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p428812361042"><a name="p428812361042"></a><a name="p428812361042"></a>Codes or a binary library for implementing features</p> ## Bundle Dependency<a name="section185955409107"></a>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p328817366417"><a name="p328817366417"></a><a name="p328817366417"></a>List of dependent bundles as well as their compiling and building scripts</p> A bundle dependency can be mandatory or optional.
</td>
</tr> - Mandatory dependency: If bundle A must depend on bundle B to implement a feature, that is, the APIs or services specific to bundle B must be invoked, then bundle B is defined as the mandatory dependency of bundle A.
<tr id="row95114356"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p184894513517"><a name="p184894513517"></a><a name="p184894513517"></a>Integrity</p> - Optional dependency: If either bundle C or bundle D is required for bundle A to implement a feature, and if bundle C and bundle D are interchangeable, then bundle C and bundle D are defined as optional dependencies of bundle A.
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p1951741155"><a name="p1951741155"></a><a name="p1951741155"></a>A part of the operating system</p>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p20521542512"><a name="p20521542512"></a><a name="p20521542512"></a>An entire operating system</p>
</td>
</tr>
<tr id="row13581419518"><td class="cellrowborder" valign="top" width="16.24162416241624%" headers="mcps1.2.4.1.1 "><p id="p859171059"><a name="p859171059"></a><a name="p859171059"></a>Compilation result</p>
</td>
<td class="cellrowborder" valign="top" width="33.31333133313331%" headers="mcps1.2.4.1.2 "><p id="p259201355"><a name="p259201355"></a><a name="p259201355"></a>Bundles</p>
</td>
<td class="cellrowborder" valign="top" width="50.44504450445044%" headers="mcps1.2.4.1.3 "><p id="p459414519"><a name="p459414519"></a><a name="p459414519"></a>System image</p>
</td>
</tr>
</tbody>
</table>
**Figure 1** Composition of bundles and distributions<a name="fig85033524124"></a>
![](figures/en-us_image_0000001054663940.png)
...@@ -62,7 +62,7 @@ For details about **hpm-cli** commands, see [HPM Commands](bundle-management. ...@@ -62,7 +62,7 @@ For details about **hpm-cli** commands, see [HPM Commands](bundle-management.
## Downloading OpenHarmony Code<a name="section102338221707"></a> ## Downloading OpenHarmony Code<a name="section102338221707"></a>
For details, see [Source Code Acquisition](../get-code/source-code-acquisition.md). For details, see .
## Installing Dependent Bundles<a name="section19233183315020"></a> ## Installing Dependent Bundles<a name="section19233183315020"></a>
......
此差异已折叠。
...@@ -47,7 +47,7 @@ You can download the source code or the corresponding solutions from the image l ...@@ -47,7 +47,7 @@ You can download the source code or the corresponding solutions from the image l
</td> </td>
<td class="cellrowborder" valign="top" width="24.759999999999998%" headers="mcps1.2.5.1.3 "><p id="p592912312511"><a name="p592912312511"></a><a name="p592912312511"></a><a href="https://repo.huaweicloud.com/harmonyos/os/1.0/wifiiot-1.0.tar.gz" target="_blank" rel="noopener noreferrer">Site</a></p> <td class="cellrowborder" valign="top" width="24.759999999999998%" headers="mcps1.2.5.1.3 "><p id="p592912312511"><a name="p592912312511"></a><a name="p592912312511"></a><a href="https://repo.huaweicloud.com/harmonyos/os/1.0/wifiiot-1.0.tar.gz" target="_blank" rel="noopener noreferrer">Site</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="34.1%" headers="mcps1.2.5.1.4 "><p id="p199296318252"><a name="p199296318252"></a><a name="p199296318252"></a><a href="http://tools.harmonyos.com/mirrors/os/1.0/wifiiot-1.0.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA-256 Verification Code</a></p> <td class="cellrowborder" valign="top" width="34.1%" headers="mcps1.2.5.1.4 "><p id="p199296318252"><a name="p199296318252"></a><a name="p199296318252"></a><a href="https://repo.huaweicloud.com/harmonyos/os/1.0/wifiiot-1.0.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA-256 Verification Code</a></p>
</td> </td>
</tr> </tr>
<tr id="row1293014352510"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p692917311258"><a name="p692917311258"></a><a name="p692917311258"></a>Hi3518 solutions (binary)</p> <tr id="row1293014352510"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p692917311258"><a name="p692917311258"></a><a name="p692917311258"></a>Hi3518 solutions (binary)</p>
...@@ -234,7 +234,7 @@ Add the bundle \(**@ohos/demo** as an example\) to your project as follows: ...@@ -234,7 +234,7 @@ Add the bundle \(**@ohos/demo** as an example\) to your project as follows:
Method 1 \(recommended\): Use the **repo** tool to download source code. Method 1 \(recommended\): Use the **repo** tool to download source code.
``` ```
repo init -u https://gitee.com/openharmony/manifest.git -b master repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify
repo sync -c repo sync -c
``` ```
......
...@@ -2,64 +2,76 @@ ...@@ -2,64 +2,76 @@
## Acquiring Compilation Toolchain<a name="section18750162432511"></a> ## Acquiring Compilation Toolchain<a name="section18750162432511"></a>
Download the compilation toolchain from image sites listed in the following table. For details about how to install the compilation toolchain, see the **Environment Setup** section in **Getting Started** of the specific development guide. The following table lists the compilation toolchain downloaded from an image site. For details about how to download and install all compilation tools, see the **Environment Setup** section in **Getting Started** of the specific development board.
**Table 1** Acquiring compilation toolchain **Table 1** Acquiring compilation toolchain
<a name="table167961324122511"></a> <a name="table167961324122511"></a>
<table><thead align="left"><tr id="row87941124202517"><th class="cellrowborder" valign="top" width="11.25%" id="mcps1.2.5.1.1"><p id="p77943248257"><a name="p77943248257"></a><a name="p77943248257"></a>Content</p> <table><thead align="left"><tr id="row87941124202517"><th class="cellrowborder" valign="top" width="16.35%" id="mcps1.2.6.1.1"><p id="p12231193484318"><a name="p12231193484318"></a><a name="p12231193484318"></a>Development Board</p>
</th> </th>
<th class="cellrowborder" valign="top" width="13.74%" id="mcps1.2.5.1.2"><p id="p879422415251"><a name="p879422415251"></a><a name="p879422415251"></a>Version Information</p> <th class="cellrowborder" valign="top" width="10.93%" id="mcps1.2.6.1.2"><p id="p77943248257"><a name="p77943248257"></a><a name="p77943248257"></a>Content</p>
</th> </th>
<th class="cellrowborder" valign="top" width="13.71%" id="mcps1.2.5.1.3"><p id="p1379420242252"><a name="p1379420242252"></a><a name="p1379420242252"></a>Site</p> <th class="cellrowborder" valign="top" width="8.08%" id="mcps1.2.6.1.3"><p id="p879422415251"><a name="p879422415251"></a><a name="p879422415251"></a>Version Information</p>
</th> </th>
<th class="cellrowborder" valign="top" width="61.3%" id="mcps1.2.5.1.4"><p id="p479442462518"><a name="p479442462518"></a><a name="p479442462518"></a>SHA-256 Verification Code</p> <th class="cellrowborder" valign="top" width="7.95%" id="mcps1.2.6.1.4"><p id="p1379420242252"><a name="p1379420242252"></a><a name="p1379420242252"></a>Site</p>
</th>
<th class="cellrowborder" valign="top" width="56.69%" id="mcps1.2.6.1.5"><p id="p479442462518"><a name="p479442462518"></a><a name="p479442462518"></a>SHA-256 Verification Code</p>
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody><tr id="row47957244255"><td class="cellrowborder" valign="top" width="11.25%" headers="mcps1.2.5.1.1 "><p id="p20794162412258"><a name="p20794162412258"></a><a name="p20794162412258"></a>llvm</p> <tbody><tr id="row2795202472514"><td class="cellrowborder" valign="top" width="16.35%" headers="mcps1.2.6.1.1 "><p id="p16361494412"><a name="p16361494412"></a><a name="p16361494412"></a>Hi3861</p>
</td>
<td class="cellrowborder" valign="top" width="10.93%" headers="mcps1.2.6.1.2 "><p id="p479592415257"><a name="p479592415257"></a><a name="p479592415257"></a>gcc_riscv32</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.74%" headers="mcps1.2.5.1.2 "><p id="p47941224122519"><a name="p47941224122519"></a><a name="p47941224122519"></a>9.0.0-34042</p> <td class="cellrowborder" valign="top" width="8.08%" headers="mcps1.2.6.1.3 "><p id="p1679522412514"><a name="p1679522412514"></a><a name="p1679522412514"></a>7.3.0</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.71%" headers="mcps1.2.5.1.3 "><p id="p1379532412256"><a name="p1379532412256"></a><a name="p1379532412256"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-34042/linux/llvm-linux-9.0.0-34042.tar" target="_blank" rel="noopener noreferrer">Site</a></p> <td class="cellrowborder" valign="top" width="7.95%" headers="mcps1.2.6.1.4 "><p id="p13795192412258"><a name="p13795192412258"></a><a name="p13795192412258"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/gcc_riscv32/7.3.0/linux/gcc_riscv32-linux-7.3.0.tar.gz" target="_blank" rel="noopener noreferrer">Site</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="61.3%" headers="mcps1.2.5.1.4 "><p id="p15795112414255"><a name="p15795112414255"></a><a name="p15795112414255"></a>64a518b50422b6f1ba8f6f56a5e303fb8448a311211ba10c385ad307a1d2546f</p> <td class="cellrowborder" valign="top" width="56.69%" headers="mcps1.2.6.1.5 "><p id="p7795124152510"><a name="p7795124152510"></a><a name="p7795124152510"></a>966fd4fda68d9886b828e6eef3ac3620806a34d3bccba4020a2ef07d9b8b8826</p>
</td> </td>
</tr> </tr>
<tr id="row2795202472514"><td class="cellrowborder" valign="top" width="11.25%" headers="mcps1.2.5.1.1 "><p id="p479592415257"><a name="p479592415257"></a><a name="p479592415257"></a>gcc_riscv32</p> <tr id="row37951424102514"><td class="cellrowborder" valign="top" width="16.35%" headers="mcps1.2.6.1.1 "><p id="p9871246124413"><a name="p9871246124413"></a><a name="p9871246124413"></a>Hi3861, Hi3516, and Hi3518</p>
</td>
<td class="cellrowborder" valign="top" width="10.93%" headers="mcps1.2.6.1.2 "><p id="p8795524122517"><a name="p8795524122517"></a><a name="p8795524122517"></a>gn</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.74%" headers="mcps1.2.5.1.2 "><p id="p1679522412514"><a name="p1679522412514"></a><a name="p1679522412514"></a>7.3.0</p> <td class="cellrowborder" valign="top" width="8.08%" headers="mcps1.2.6.1.3 "><p id="p127951624182514"><a name="p127951624182514"></a><a name="p127951624182514"></a>1523</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.71%" headers="mcps1.2.5.1.3 "><p id="p13795192412258"><a name="p13795192412258"></a><a name="p13795192412258"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/gcc_riscv32/7.3.0/linux/gcc_riscv32-linux-7.3.0.tar.gz" target="_blank" rel="noopener noreferrer">Site</a></p> <td class="cellrowborder" valign="top" width="7.95%" headers="mcps1.2.6.1.4 "><p id="p47957245252"><a name="p47957245252"></a><a name="p47957245252"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/gn/1523/linux/gn.1523.tar" target="_blank" rel="noopener noreferrer">Site</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="61.3%" headers="mcps1.2.5.1.4 "><p id="p7795124152510"><a name="p7795124152510"></a><a name="p7795124152510"></a>614ee086ead1a4fd7384332b85dd62707801f323de60dfdb61503f473d470a24</p> <td class="cellrowborder" valign="top" width="56.69%" headers="mcps1.2.6.1.5 "><p id="p9795192402516"><a name="p9795192402516"></a><a name="p9795192402516"></a>50a5a5ba5877dd0ec8afcb23d3dd4d966a16403c29cd80a4002230241d32ef34</p>
</td> </td>
</tr> </tr>
<tr id="row37951424102514"><td class="cellrowborder" valign="top" width="11.25%" headers="mcps1.2.5.1.1 "><p id="p8795524122517"><a name="p8795524122517"></a><a name="p8795524122517"></a>gn</p> <tr id="row10796824122514"><td class="cellrowborder" valign="top" width="16.35%" headers="mcps1.2.6.1.1 "><p id="p1235855210444"><a name="p1235855210444"></a><a name="p1235855210444"></a>Hi3861, Hi3516, and Hi3518</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.74%" headers="mcps1.2.5.1.2 "><p id="p127951624182514"><a name="p127951624182514"></a><a name="p127951624182514"></a>1523</p> <td class="cellrowborder" valign="top" width="10.93%" headers="mcps1.2.6.1.2 "><p id="p379532414251"><a name="p379532414251"></a><a name="p379532414251"></a>ninja</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.71%" headers="mcps1.2.5.1.3 "><p id="p47957245252"><a name="p47957245252"></a><a name="p47957245252"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/gn/1523/linux/gn.1523.tar" target="_blank" rel="noopener noreferrer">Site</a></p> <td class="cellrowborder" valign="top" width="8.08%" headers="mcps1.2.6.1.3 "><p id="p17952245256"><a name="p17952245256"></a><a name="p17952245256"></a>1.9.0</p>
</td> </td>
<td class="cellrowborder" valign="top" width="61.3%" headers="mcps1.2.5.1.4 "><p id="p9795192402516"><a name="p9795192402516"></a><a name="p9795192402516"></a>50a5a5ba5877dd0ec8afcb23d3dd4d966a16403c29cd80a4002230241d32ef34</p> <td class="cellrowborder" valign="top" width="7.95%" headers="mcps1.2.6.1.4 "><p id="p12796172442519"><a name="p12796172442519"></a><a name="p12796172442519"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar" target="_blank" rel="noopener noreferrer">Site</a></p>
</td>
<td class="cellrowborder" valign="top" width="56.69%" headers="mcps1.2.6.1.5 "><p id="p479692492515"><a name="p479692492515"></a><a name="p479692492515"></a>b4a4ba21e94ff77634e1f88697a00b6f498fdbc0b40d7649df1b246b285874f9</p>
</td> </td>
</tr> </tr>
<tr id="row10796824122514"><td class="cellrowborder" valign="top" width="11.25%" headers="mcps1.2.5.1.1 "><p id="p379532414251"><a name="p379532414251"></a><a name="p379532414251"></a>ninja</p> <tr id="row2524115316467"><td class="cellrowborder" valign="top" width="16.35%" headers="mcps1.2.6.1.1 "><p id="p162311934144313"><a name="p162311934144313"></a><a name="p162311934144313"></a>Hi3516 and Hi3518</p>
</td>
<td class="cellrowborder" valign="top" width="10.93%" headers="mcps1.2.6.1.2 "><p id="p20794162412258"><a name="p20794162412258"></a><a name="p20794162412258"></a>llvm</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.74%" headers="mcps1.2.5.1.2 "><p id="p17952245256"><a name="p17952245256"></a><a name="p17952245256"></a>1.9.0</p> <td class="cellrowborder" valign="top" width="8.08%" headers="mcps1.2.6.1.3 "><p id="p47941224122519"><a name="p47941224122519"></a><a name="p47941224122519"></a>9.0.0-34042</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.71%" headers="mcps1.2.5.1.3 "><p id="p12796172442519"><a name="p12796172442519"></a><a name="p12796172442519"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/ninja/1.9.0/linux/ninja.1.9.0.tar" target="_blank" rel="noopener noreferrer">Site</a></p> <td class="cellrowborder" valign="top" width="7.95%" headers="mcps1.2.6.1.4 "><p id="p1379532412256"><a name="p1379532412256"></a><a name="p1379532412256"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-34042/linux/llvm-linux-9.0.0-34042.tar" target="_blank" rel="noopener noreferrer">Site</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="61.3%" headers="mcps1.2.5.1.4 "><p id="p479692492515"><a name="p479692492515"></a><a name="p479692492515"></a>b4a4ba21e94ff77634e1f88697a00b6f498fdbc0b40d7649df1b246b285874f9</p> <td class="cellrowborder" valign="top" width="56.69%" headers="mcps1.2.6.1.5 "><p id="p15795112414255"><a name="p15795112414255"></a><a name="p15795112414255"></a>64a518b50422b6f1ba8f6f56a5e303fb8448a311211ba10c385ad307a1d2546f</p>
</td> </td>
</tr> </tr>
<tr id="row1179642422512"><td class="cellrowborder" valign="top" width="11.25%" headers="mcps1.2.5.1.1 "><p id="p127962247255"><a name="p127962247255"></a><a name="p127962247255"></a>hc-gen</p> <tr id="row1179642422512"><td class="cellrowborder" valign="top" width="16.35%" headers="mcps1.2.6.1.1 "><p id="p172311534134318"><a name="p172311534134318"></a><a name="p172311534134318"></a>Hi3516 and Hi3518</p>
</td>
<td class="cellrowborder" valign="top" width="10.93%" headers="mcps1.2.6.1.2 "><p id="p127962247255"><a name="p127962247255"></a><a name="p127962247255"></a>hc-gen</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.74%" headers="mcps1.2.5.1.2 "><p id="p8796424152514"><a name="p8796424152514"></a><a name="p8796424152514"></a>0.65</p> <td class="cellrowborder" valign="top" width="8.08%" headers="mcps1.2.6.1.3 "><p id="p8796424152514"><a name="p8796424152514"></a><a name="p8796424152514"></a>0.65</p>
</td> </td>
<td class="cellrowborder" valign="top" width="13.71%" headers="mcps1.2.5.1.3 "><p id="p7796624192517"><a name="p7796624192517"></a><a name="p7796624192517"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/hc-gen/0.65/linux/hc-gen-0.65-linux.tar" target="_blank" rel="noopener noreferrer">Site</a></p> <td class="cellrowborder" valign="top" width="7.95%" headers="mcps1.2.6.1.4 "><p id="p7796624192517"><a name="p7796624192517"></a><a name="p7796624192517"></a><a href="https://repo.huaweicloud.com/harmonyos/compiler/hc-gen/0.65/linux/hc-gen-0.65-linux.tar" target="_blank" rel="noopener noreferrer">Site</a></p>
</td> </td>
<td class="cellrowborder" valign="top" width="61.3%" headers="mcps1.2.5.1.4 "><p id="p679682402514"><a name="p679682402514"></a><a name="p679682402514"></a>fcfee489371947a464fe41a4b45a897b9a44155891a957f15bad2e157c750162</p> <td class="cellrowborder" valign="top" width="56.69%" headers="mcps1.2.6.1.5 "><p id="p679682402514"><a name="p679682402514"></a><a name="p679682402514"></a>fcfee489371947a464fe41a4b45a897b9a44155891a957f15bad2e157c750162</p>
</td> </td>
</tr> </tr>
</tbody> </tbody>
...@@ -98,7 +110,7 @@ HUAWEI DevEco Device Tool \(DevEco Device Tool for short\) is a one-stop integra ...@@ -98,7 +110,7 @@ HUAWEI DevEco Device Tool \(DevEco Device Tool for short\) is a one-stop integra
## Tool Introduction<a name="section17935101224620"></a> ## Tool Introduction<a name="section17935101224620"></a>
HUAWEI DevEco Studio \(DevEco Studio for short\) is a one-stop IDE oriented to OpenHarmony-based devices in all scenarios. It allows you to create project templates, and develop, build, debug, and release OpenHarmony applications from end to end. DevEco Studio enables you to efficiently develop applications with OpenHarmony distributed capabilities, thereby empowering you to innovate applications. HUAWEI DevEco Studio \(DevEco Studio for short\) is a one-stop IDE oriented to Huawei devices in all scenarios. It allows you to create project templates, and develop, build, debug, and release OpenHarmony applications from end to end. DevEco Studio enables you to efficiently develop applications with OpenHarmony distributed capabilities, thereby empowering you to innovate applications.
## Website<a name="section1572093543613"></a> ## Website<a name="section1572093543613"></a>
......
文件模式从 100755 更改为 100644
# Adding Pages<a name="EN-US_TOPIC_0000001052938450"></a>
## Creating the Home Page \(Creating a Project\)<a name="section16935511143715"></a>
After the project is created, the **index** page is generated by default. The following figure shows the project directory.
**Figure 1** Project directory<a name="fig16545205773718"></a>
![](figures/project-directory-1.png "project-directory-1")
## Creating Detail and History Pages<a name="section122131729173819"></a>
Perform the following steps twice to create the rest two pages:
1. Right-click **pages** and choose **New** \> **JS Page** from the shortcut menu.
**Figure 2** Adding a page<a name="fig18740145216410"></a>
![](figures/adding-a-page-2.png "adding-a-page-2")
2. Enter the page name.
**Figure 3** Entering the page name<a name="fig48491266714"></a>
![](figures/entering-the-page-name-3.png "entering-the-page-name-3")
3. Confirm the creation.
The following figure shows the application project directory after the **detail** page and **history** page are created. Each page contains a **.hml** layout file, a **.css** file, and a **.js** file \(containing service logic code\).
**Figure 4** Complete project directory<a name="fig103015177819"></a>
![](figures/complete-project-directory-4.png "complete-project-directory-4")
文件模式从 100755 更改为 100644
# Building the Detail Page<a name="EN-US_TOPIC_0000001053577188"></a>
The **detail** page displays air quality data, such as CO, NO2, PM10, PM2.5, and SO2. Use multiple **<text\>** components to display the information, and use the **<list\>** component to continuously swipe up and down on the page. Note that **<list-item\>** can have multiple child components, which must be **<list\>**. For the **detail** page, you need to develop for the page typesetting and styles. The detailed code is as follows:
## detail.hml<a name="section1039826103212"></a>
```
<list style="top:67px;left:320px;width:321px;height:350px;">
<list-item style="width:321px;height:300px;">
<div style="width: 321px;height:300px;background-color:#000000;flex-direction:column;align-items:flex-start;">
<text style="width:321px;height:40px; color:#dcdcdc;">{{location}}</text>
<div class="line-div"></div>
<!- Display all indicator values. -->
<div class="info-div-width-height" style="margin-top:10px;">
<text class="gas-name">CO</text>
<text class="gas-value">{{airData[0]}}</text>
</div>
<div class="info-div-width-height" style="margin-top:10px;">
<text class="gas-name">NO2</text>
<text class="gas-value">{{airData[1]}}</text>
</div>
<div class="info-div-width-height" style="margin-top:10px;">
<text class="gas-name">PM10</text>
<text class="gas-value">{{airData[2]}}</text>
</div>
<div class="info-div-width-height" style="margin-top:10px;">
<text class="gas-name">PM2.5</text>
<text class="gas-value">{{airData[3]}}</text>
</div>
<div class="info-div-width-height" style="margin-top:10px;">
<text class="gas-name">SO2</text>
<text class="gas-value">{{airData[4]}}</text>
</div>
</div>
</list-item>
<list-item style="width:321px;height:220px;">
<div style="width:321px;height:220px;background-color:#000000;flex-direction:column;align-items:flex-start;">
<!-- Update time -->
<text class="config-info">{{updated}}:{{updateStatus}}</text>
<!- Data source -->
<text class="config-info">{{dataSourceName}}:{{dataSource}}</text>
<div class="line-div"></div>
<!- Page switching button -->
<div style="width:321px; height:55px;align-items:center; margin-top:20px;">
<input type="button" value="History" style="border-width: 3px;margin-left:10px; border-color: #90ee90;width:146px;height:50;" onclick="openHistory"/>
<input type="button" value="Close" style="border-width: 3px;margin-left:5px; border-color:#ff0000;width:146px;height:50;" onclick="backMain"/>
</div>
</div>
</list-item>
</list>
```
## detail.css<a name="section4931125119322"></a>
```
.line-div{
background-color:#f5fffa;
height:2px;
width:454px;
}
.info-div-width-height{
width:321px;
height:60px;
margin-top: 20px;
}
.gas-name{
color:#f5fffa;
width:160px;
height:30px;
}
.gas-value{
text-align:right;
color:#00fa9a;
width:160px;
height:30px;
}
.config-info {
height:40px;
width:321px;
color:#f5fffa;
}
```
## detail.js<a name="section1547613143337"></a>
```
import router from '@system.router'
export default {
data:{// Initialization information
location:"HangZhou",
udpateStatus:"1h ago",
dataSource:"tianqi.com",
updateTime:"15:13",
updated:'Updated',
dataSourceName:'Data Source',
sampledOn:'Sampled on',
cityIndex:0,
airData:['100', '90', '120', '50', '150', '40', '25']
},
onInit(){
// Process information in multiple languages.
this.location = this.$t(this.location);
this.updated = this.$t("updated");
this.dataSourceName = this.$t("dataSourceName");
this.sampledOn = this.$t("sampledOn");
this.monitoringStation = this.$t("monitoringStation");
if(this.selectedCityIndex != null){ // Save city information sent from the home page.
this.cityIndex= this.selectedCityIndex;
}
},
openHistroy(){// Switch to the history page.
router.replace({
uri:'pages/history/history'
});
},
backMain(){ // Go back to the home page and return the information about the selected city.
router.replace({
uri:'pages/index/index',
params:{selectedCityIndex:this.cityIndex}
});
}
}
```
文件模式从 100755 更改为 100644
# Building the History Page<a name="EN-US_TOPIC_0000001052977201"></a>
The **history** page displays the air quality data of a week in a chart. On this page, multiple **<div\>** components are used to replace the **<chart\>** component to display the chart. The sample code is as follows:
## history.hml<a name="section275215487291"></a>
```
<list style="width:321px;height:321px;top:67px;left:320px;">
<list-item class="info-list-item">
<div style="width:321px;height:80px;flex-direction:column;align-items:flex-start;">
<text class="div-info-historical-data">{{historicalData}}</text>
</div>
</list-item>
<!-- Use the for attribute to dynamically generate listitem. The {{datasets}} corresponds to the datasets variable in history.js. Create components based on the number of elements in the variable array. -->
<list-item style="width:321px;height:160px;" for="{{datasets}}">
<div style="width:321px;height:160px;flex-direction:column;">
<div style="width:321px;height:2px;background-color:#f5fffa;"></div>
<!-- $item is an element of datasets. -->
<text class="gas-name">{{$item}}</text>
<div style="width:321px;height:100px;margin-top:4px;justify-content:flex-start;align-items:flex-end;">
<!-- The color in the code example is a fixed value. You can use dynamic binding. -->
<div style="width:21px;margin-left:21px;height:10px;backgroundColor:#00ff00;"></div>
<div style="width:21px;margin-left:21px;height:20px;;backgroundColor:#00ff00;"></div>
<div style="width:21px;margin-left:21px;height:90px;backgroundColor:#ff0000;"></div>
<div style="width:21px;margin-left:21px;height:80px;backgroundColor:#ff0000;"></div>
<div style="width:21px;margin-left:21px;height:60px;backgroundColor:#999999;"></div>
<div style="width:21px;margin-left:21px;height:50px;backgroundColor:#999999;"></div>
<div style="width:21px;margin-left:21px;height:100px;backgroundColor:#ff0000;"></div>
</div>
<!-- The x-axis icons of the chart are images. -->
<image style="width:321px;height:20px;" src="common/week.png"></image>
</div>
</list-item>
<list-item class="info-list-item">
<!-- Button for returning to the detail page -->
<input type="button" value="Back" style="border-width:2px;border-color:#90ee90;width:256px;height:60px;margin-left: 30px;" onclick="backDetail"/>
</list-item>
</list>
```
## history.css<a name="section2589154215301"></a>
```
.div-info-location{
color:#dcdcdc;
width:321px;
height:40px;
}
.div-info-historical-data{
color:#f5fffa;
width:321px;
height:40px;
}
.gas-name{
color:#f0ffff;
text-align:right;
width:321px;
height:32px;
}
.info-list-item{
width:321px;
height:80px;
}
```
## history.js<a name="section163410883117"></a>
```
import router from '@system.router'
module.exports = {
data: {
historicalData:"historicalData",
datasets:["CO","O3","NO2","NO","PM25","SO2"]
},
onInit(){
// Process information in multiple languages.
this.historicalData = this.$t(this.historicalData);
},
backDetail(){
router.replace({ // Return to the detail page.
uri:'pages/detail/detail'
});
}
}
```
文件模式从 100755 更改为 100644
# Building the Home Page<a name="EN-US_TOPIC_0000001053417188"></a>
The application home page displays air quality information of the current city. There are two screens on the home page. Each screen displays the air quality information of a city, including the AQI and city name. The AQI value can be displayed in the form of a ring progress bar with animation.
1. The **<swiper\>** component is required to implement switching between the two screens.
Add a root **<swiper\>** to the **.hml** file. Note that each **.hml** file can contain only one root component. The code snippet is as follows:
```
<swiper class="container" style="left:253px;" index="{{swiperPage}}" duration="500" onchange="swiperChange">
</swiper>
```
- **class="container"** indicates the style used by the component. The **container** is a style class in the **index.css** file. The code snippet is as follows:
```
.container{
height: 454px;
width: 454px;
}
```
This style class sets the height and width of the component. For device development, the component height and width must be explicitly specified. Otherwise, the component may fail to be displayed.
- **index="\{\{swiperPage\}\}" duration="500" onchange="swiperChange"** sets the component attribute and event. **duration="500"** indicates that the duration of the swiping animation is 500 ms.
- **index="\{\{swiperPage\}\}"** specifies the index of the child component of **<swiper\>**. **\{\{swiperPage\}\}** indicates that the index value is dynamically bound to the **swiperPage** variable in the JavaScript code. The index value changes with the **swiperPage** value.
- **onchange="swiperChange"** binds the change event of the **<swiper\>** component to the **swiperChange** function. The JavaScript code is as follows:
```
// Import the router module for page switching.
import router from '@system.router'
export default {
// Define parameters.
data: {
swiperPage:0 // The first page is displayed by default.
},
onInit () {
},
// Swiping event, which saves the index value of the current <swiper>. The index value is saved to the swiperPage variable each time a swiping occurs.
swiperChange (e) {
this.swiperPage = e.index;
}
}
```
2. Set the information about each city to be displayed on a screen. In each screen, four types of information needs to be displayed using different components.
Add two child components \(**<stack\>**\) to the **<swiper\>**. Add the **<text\>**, **<image\>**, and **<progress\>** components to each **<stack\>** to display the information. Code example in the **.hml** file is as follows:
```
<!-- The root component is <swiper>. Only one root component is supported. -->
<swiper class="container" style="left:253px;" index="{{swiperPage}}" duration="500" onchange="swiperChange">
<!-- The first screen -->
<stack class="container">
<text></text>------City
<text></text>------Air quality
<progress></progress>-----Progress bar
<image></image>-------A cloud image
<text></text>--------AQI value
<text>AQI</text>------AQI
</stack>
<!-- The second screen -->
<stack class="container">
<text></text>
<text></text>
<progress></progress>
<image></image>
<text></text>
<text></text>
</stack>
</swiper>
```
3. Set the style, animation effect, and dynamic data binding for all components. The complete example code is as follows:
- **index.hml**
```
<!-- The root component is <swiper>. Only one root component is supported. -->
<swiper class="container" style="left:253px;" index="{{swiperPage}}" duration="500" onchange="swiperChange">
<!-- The first screen -->
<stack class="container">
<!-- Display air quality and the current city -->
<text class="airquality" style="color:{{textColor1}};">{{airData[0].airQuality}}</text>
<text class="location-text">{{airData[0].location}}</text>
<!-- Display the animation effect based on the AQI value. To achieve this, you need to implement dynamic percent1 value changes in the .js file.-->
<progress class="circleProgress" style="color:{{textColor1}};background-Color:{{bgColor1}};" type="arc" onclick="openDetail" percent="{{percent1}}"></progress>
<image class="image" src="{{src1}}"></image>
<!-- AQI, which is obtained dynamically -->
<text class="pm25-value">{{airData[0].detailData}}</text>
<text class="pm25-name">AQI</text>
</stack>
<!-- The second screen -->
<stack class="container">
<text class="airquality" style="color:{{textColor2}};">{{airData[1].airQuality}}</text>
<text class="location-text">{{airData[1].location}}</text>
<progress class="circleProgress" style="color: {{textColor2}};background-Color:{{bgColor2}};" type="arc" onclick="openDetail" percent="{{percent2}}"></progress>
<image class="image"src="{{src2}}"></image>
<text class="pm25-value">{{airData[1].detailData}}</text>
<text class="pm25-name">AQI</text>
</stack>
</swiper>
```
- **index.css**
A **.css** file contains many classes. Each class defines the position, size, font, color, and background color of a component. Each child component is added to its parent component, and the style file of the parent component affects how the child component will be displayed.
```
.pm25-value{
text-align:center;
font-size:38px;
color:#f0ffff;
width:454px;
height:50px;
top:275px;
}
.pm25-name{
text-align:center;
color:#a2c4a2;
width:454px;
height:50px;
top:335px;
}
.location-text{
text-align:center;
color:#f0ffff;
width:454px;
height:50px;
top:20px;
}
.container{
height: 454px;
width: 454px;;
}
.circleProgress{
centerX:227px;
centerY:250px;
radius:180px;
startAngle:198;
totalAngle:320;
strokeWidth:45;
width:454px;
height:454px;
}
.image{
top:390px;
left:217px;
width:32px;
height:32px;
}
.airquality{
top:220px;
text-align: center;
width:454px;
height:40px;
}
```
- **index.js**
A **.js** file is used to implement interaction logic of your application. In the **.js** file of the home page, the following features need to be implemented: dynamic changes of the text content and progress bar color based on numbers, multiple languages, page switching, and animation playback.
```
// Import the router module for page switching.
import router from '@system.router'
export default {
// Define parameters.
data: {
textColor1:'#00ff00',// Text color
textColor2:'#00ff00',
bgColor1:'#669966',// Background color
bgColor2:'#669966',
swiperPage:0,
percent1:0,// Progress bar
percent2:0,
src1:'common/cloud_green.png',
src2:'common/cloud_green.png',
airData: [{
location: 'HangZhou',
airQuality: 'Good',
detailData: 10
}, {
location: 'ShangHai',
airQuality: 'Unhealth',
detailData:90
}]
},
onInit () {
// Multi-language feature. Use the $t function to obtain content in the required language.
this.airData[0].location = this.$t(this.airData[0].location);
this.airData[1].location = this.$t(this.airData[1].location);
this.airData[0].airQuality = this.$t(this.airData[0].airQuality);
this.airData[1].airQuality = this.$t(this.airData[1].airQuality);
if(this.airData[0].detailData > 100){ // Display different colors and images based on indicator values.
this.src1 = "common/cloud_red.png";
this.textColor1 = '#ff0000';// Display the text in red.
this.bgColor1 = '#9d7462';
} else if(50 < this.airData[0].detailData && this.airData[0].detailData <= 100){
this.src1 = "common/cloud_yellow.png";
this.textColor1 = '#ecf19a';// Display the text in yellow.
this.bgColor1 = '#9d9d62';
}
if(this.airData[1].detailData > 100){
this.src2 = "common/cloud_red.png";
this.textColor2 = '#ff0000';
this.bgColor2 = '#9d7462';
} else if(50 < this.airData[1].detailData && this.airData[1].detailData <= 100){
this.src2 = "common/cloud_yellow.png";
this.textColor2 = '#ecf19a';
this.bgColor2 = '#9d9d62';
}
if(this.selectedCityIndex){
this.swiperPage = this.selectedCityIndex;
}
},
onShow () { // Processing logic during page display
var self = this;
var time = 1000/(self.airData[self.swiperPage].detailData);// Complete animation playback in 1s.
if(time == 0){
time = 100;
}
// Animation effect of the ring progress bar. Start a timer and change the progress bar at a certain interval (calculated based on the AQI value). The animation playback is completed within 1s.
var interval = setInterval(function () {
if ((self.swiperPage==0?self.percent1:self.percent2) >= self.airData[self.swiperPage].detailData) {
clearInterval(interval);
return;
}
if(self.swiperPage == 0){
self.percent1++;
}else{
self.percent2++
}
}, time)
},
// Switch to the detail page.
openDetail () {
router.replace({
uri:'pages/detail/detail',
params:{selectedCityIndex:this.swiperPage}// Selected city
});
},
// Swiping event, which saves the index value of the current <swiper> and directly switches to the specified <swiper> screen from the detail page.
swiperChange (e) {
this.swiperPage = e.index;
var self = this;
var time = 1000/(self.airData[self.swiperPage].detailData);
if(time == 0){
time = 100;
}
// Play the animation if the user swipes to the page for the first time.
var interval = setInterval(function () {
let percent = (self.swiperPage==0?self.percent1:self.percent2);
if (percent >= self.airData[self.swiperPage].detailData) {
clearInterval(interval);
return;
}
if(self.swiperPage==0){
self.percent1++;
}else{
self.percent2++;
}
}, time)
}
}
```
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
# Debugging and verification<a name="EN-US_TOPIC_0000001054370931"></a>
For details about the burning process, see the Hi3861 Quick Start - Burning. The following describes the verification process of the power distribution network.
## Non-perceptive network distribution function verification<a name="section17434165181917"></a>
1. Start the module with the power distribution sample service to enable the module to enter the to-be-distributed state, as shown in the following figure.
```
sdk ver:Hi3861V100R001C00SPC023 2020-06-09 13:30:00
FileSystem mount ok.
wifi init success!
app_main test
[sample] main biz.
ap start succ
Nan Init Success
nan state(0)->(1)
wait STA join AP
[sample] main biz.
[sample] main biz.
wait STA join AP
```
2. Start the app on the mobile phone. \(This app is an internal debugging demo. Developers need to develop FAs by themselves. The following describes only the network configuration process.\) Click Login Authorization \> Login Authorization \> NAN Device, and place the mobile phone close to the module, a new device is found. \(In the following figure, the product icon is changed to 1, and the SN is changed to 0123456789012345.\)
**Figure 1** Discovering a new device<a name="fig1937218217356"></a>
![](figures/en-us_image_0000001054570953.png)
3. Click the device to enter the configuration page. Select the hotspot SSID, enter the password, and click the button for network configuration \(...\), as shown in the following figure.
**Figure 2** Wi-Fi network configuration page<a name="fig1430415418710"></a>
![](figures/en-us_image_0000001054850904.png)
4. Click Next. On the second control page that is displayed, click the power button. The device receives the control message, as shown in the following figure.
**Figure 3** Control page<a name="fig1942486371"></a>
![](figures/en-us_image_0000001054370936.png)
5. On the second control page, click the disconnection button. After you click the button, the device receives a message indicating that it will exit the NAN.
**Figure 4** Exiting the Control Interface<a name="fig4607161183917"></a>
![](figures/en-us_image_0000001054132279.png)
## SoftAP network configuration mode verification<a name="section1939531372015"></a>
1. Start the module with the power distribution sample service to enable the module to enter the to-be-distributed state, as shown in the following figure.
```
sdk ver:Hi3861V100R001C00SPC023 2020-06-09 13:30:00
FileSystem mount ok.
wifi init success!
app_main test
[sample] main biz.
ap start succ
Nan Init Success
nan state(0)->(1)
wait STA join AP
[sample] main biz.
[sample] main biz.
wait STA join AP
```
2. Start the app on the mobile phone. \(This app is an internal debugging demo. Developers need to develop FAs by themselves. The following describes only the network configuration process.\) Choose Authorization Login \> Authorization and Login \> SoftAP Device to discover new devices \(Hi-xxx-Switchs-xxxxx in the following figure\).
**Figure 5** Discover Device page<a name="fig14593216174012"></a>
![](figures/en-us_image_0000001054132216.png)
3. Tap the device icon and wait for the app to automatically switch to the page for selecting a Wi-Fi hotspot. Select a hotspot, enter the password, and click.... The device receives the network configuration data, as shown in the following figure.
**Figure 6** Device configuration page<a name="fig3100125717408"></a>
![](figures/en-us_image_0000001054452241.png)
## FAQs<a name="section43521923135514"></a>
None
# Developing the First Application Program running on the Hi3516 Development Board<a name="EN-US_TOPIC_0000001052906247"></a>
This section describes how to modify, compile, burn, and run the first application on the board.
## Obtaining the Source Code<a name="section215953714245"></a>
You need to download a set of source code from the Linux server. For details, see [Source Code Acquisition](en-us_topic_0000001050769927.md).
## Modifying an application<a name="s8efc1952ebfe4d1ea717182e108c29bb"></a>
The **helloworld.c** code in the **applications/sample/camera/app/src** directory is as following. You can customize the content to be printed. For example, you can change OHOS to World. The current applications can be developed using standard ISO C and C++.
```
#include <stdio.h>
#include "los_sample.h"
int main(int argc, char **argv)
{
printf("\n************************************************\n");
printf("\n\t\tHello OHOS!\n");
printf("\n************************************************\n\n");
LOS_Sample(g_num);
return 0;
}
```
## Compiling<a name="section1077671315253"></a>
On the Linux server, go to the root directory of the source code package. The build.py compilation script is stored in the directory. Run the following script to compile the source code package:
Run the following script in the root directory of the source code package to compile the source code package. The result file is generated in the out/ipcamera\_hi3516dv300 directory.
```
python build.py ipcamera_hi3516dv300 -b debug
```
## Burning<a name="section18061240152520"></a>
Network Burning Mode
This method applies only to the board \(such as Hi3516D V300\) that supports the network port. In addition, the PC and the board must be connected by using a network cable and configured on the same network.
>![](public_sys-resources/icon-notice.gif) **NOTICE:**
>The Visual Studio Code software connects the board to the network. If the board cannot connect to the computer network, check the firewall settings. For details, see FAQ 2.
1. Install the USB-to-serial adapter driver and obtain the serial port number.
**Figure 1** Successful driver installation<a name="fig87951742181717"></a>
![](figures/successful-driver-installation.png "successful-driver-installation")
1. Power on the board and connect the serial port cable of the board to the Windows console.
2. Install the driver and obtain the driver link.
3. Open Device Manager, then check and record the value of **Prolific USB-to-Serial Comm Port**.
After the driver is successfully installed, if a warning icon is displayed on the device icon, right-click the device, uninstall the driver, reinstall the driver, and restart the computer as prompted.
2. On the Windows console, add the IP address 192.168.1.3 for the interconnection network port of the board. The method is as follows:
**Figure 2** Adding a Windows host IP address<a name="fig1438112431779"></a>
![](figures/adding-a-windows-host-ip-address.png "adding-a-windows-host-ip-address")
1. Choose Control Panel \> Network and Internet-\> Network Connections, right-click the network adapter connected to the board, and choose Properties from the shortcut menu.
2. Double-click Internet 协议版本4(TCP/IPv4).
3. Configure the IP address and gateway according to the preceding figure.
4. Click OK to save the configuration.
3. hi3516dv300 is added to the board list. After you choose Board Configure and enable a board, the board configuration table is automatically added.
**Figure 3** Add a board.<a name="fig152451448203711"></a>
![](figures/add-a-board.png "add-a-board")
4. Start the IDE and click the icons in sequence to configure the contents to be burnt over the network.
**Figure 4** Network configuration diagram of the IDE tool<a name="fig79672366813"></a>
![](figures/ide.png)
1. Select Hi3516 as the board type.
2. Click Burn.
3. Set Burning Mode to "network".
4. Host IP Address: Click to refresh the page and select 192.168.1.3 from the drop-down list box.
5. Select the chip to be burnt to the flash memory and the burning address.
**Figure 5** Setting the parameters for burning files<a name="fig11902195416418"></a>
![](figures/ide2.png)
1. Select emmc from the Memory Type drop-down list box as the flash memory type.
2. Click New to add three files. Enter the OHOS\_Image.bin, rootfs.img, and userfs.img files in the file path in sequence. Set the start address and file length as shown in the following figure, obtain the file from the out/ipcamera\_hi3516dv300 directory.
3. Click <cf id="Bold"\>Save</cf\> to save the changes.
4. Click Burn on the left to start burning.
6. Select a serial port number from the drop-down list box displayed in the upper part, for example, COM11.
**Figure 6** Selecting the serial port to be connected to the board<a name="fig73452316549"></a>
![](figures/selecting-the-serial-port-to-be-connected-to-the-board.png "selecting-the-serial-port-to-be-connected-to-the-board")
7. The burning starts. If a message is displayed, you need to manually restart the board \(by powering off and then powering on the board\).
**Figure 7** The system prompts you to power off the board and power on the board again.<a name="fig3421920185520"></a>
![](figures/reset2.png)
8. Burning is complete.
**Figure 8** Successful burning<a name="fig88368374585"></a>
![](figures/successful-burning.png "successful-burning")
## Running an Image<a name="section380511712615"></a>
1. Connect a serial port cable.
**Figure 9** Connect the serial port cables.<a name="fig056645018495"></a>
![](figures/chuankou1.png)
1. Click Serial port to enable the serial port.
2. Enter the serial port number of the "com11" and press Enter until hisillicon is displayed.
3. If the board is started for the first time or the startup parameters are modified, go to step 2. Otherwise, go to step 3.
2. \(Mandatory when the board is started for the first time\) Modify the bootcmd and bootargs of the U-boot. This step is a fixed operation. If the parameters are not modified, you need to perform this step only once. The system automatically enters the system each time the board is reset.
>![](public_sys-resources/icon-notice.gif) **NOTICE:**
>By default, the U-boot boot program waits for two seconds. You can press Enter to interrupt the waiting and the message "hisillicon" is displayed. You can run the reset command to restart the system.
**Table 1** U-boot startup parameters
<a name="table432481061214"></a>
<table><tbody><tr id="row532461021219"><th class="firstcol" valign="top" width="8.39%" id="mcps1.2.3.1.1"><p id="p1238114718129"><a name="p1238114718129"></a><a name="p1238114718129"></a>Command</p>
</th>
<td class="cellrowborder" valign="top" width="91.61%" headers="mcps1.2.3.1.1 "><p id="p93816470127"><a name="p93816470127"></a><a name="p93816470127"></a><strong id="b143728351609"><a name="b143728351609"></a><a name="b143728351609"></a>setenv bootcmd "sf probe 0;mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";</strong></p>
<p id="p83904761218"><a name="p83904761218"></a><a name="p83904761218"></a><strong id="b14389193520014"><a name="b14389193520014"></a><a name="b14389193520014"></a>setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=15M rw";</strong></p>
<p id="p7399470123"><a name="p7399470123"></a><a name="p7399470123"></a><strong id="b1041015359012"><a name="b1041015359012"></a><a name="b1041015359012"></a>saveenv</strong></p>
<p id="p14391747131219"><a name="p14391747131219"></a><a name="p14391747131219"></a><strong id="b84127351701"><a name="b84127351701"></a><a name="b84127351701"></a>reset</strong></p>
</td>
</tr>
<tr id="row6324410171216"><th class="firstcol" valign="top" width="8.39%" id="mcps1.2.3.2.1"><p id="p203915473129"><a name="p203915473129"></a><a name="p203915473129"></a>Description</p>
</th>
<td class="cellrowborder" valign="top" width="91.61%" headers="mcps1.2.3.2.1 "><p id="p439134715129"><a name="p439134715129"></a><a name="p439134715129"></a><strong id="b14391847171211"><a name="b14391847171211"></a><a name="b14391847171211"></a>setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800;go 0x80000000";</strong></p>
<p id="p1439184741218"><a name="p1439184741218"></a><a name="p1439184741218"></a>This command indicates that flash 0 is selected, and the contents with the start address of 0x800 (unit: 512 bytes, that is, 1 MB) and the size of 0x4800 (unit: 512 bytes, that is, 9 MB) are read to the memory address 0x80000000.</p>
<p id="p7391347101215"><a name="p7391347101215"></a><a name="p7391347101215"></a><strong id="b0397473129"><a name="b0397473129"></a><a name="b0397473129"></a>setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=15M rw";</strong></p>
<p id="p939547151215"><a name="p939547151215"></a><a name="p939547151215"></a>This command sets the boot parameters to serial port output, baud rate to 115200, data bit to 8, rootfs to be mounted to the eMMC, and file system type to vfat,</p>
<p id="p8402475121"><a name="p8402475121"></a><a name="p8402475121"></a>Enter the start burning position and length of rootfs.img in rootaddr=10M rootsize=15M rw. The size must be the same as that of the rootfs.img file added in the IDE.</p>
<p id="p54034712120"><a name="p54034712120"></a><a name="p54034712120"></a><strong id="b2600155013264"><a name="b2600155013264"></a><a name="b2600155013264"></a>saveenv</strong> indicates that the current configuration is saved.</p>
<p id="p2401247131212"><a name="p2401247131212"></a><a name="p2401247131212"></a><strong id="b1427444612265"><a name="b1427444612265"></a><a name="b1427444612265"></a>reset</strong> indicates that the board is reset.</p>
<p id="p1440164791213"><a name="p1440164791213"></a><a name="p1440164791213"></a><strong id="b725515390267"><a name="b725515390267"></a><a name="b725515390267"></a>(Optional) go 0x40000000</strong> indicates that the command is fixed in the startup parameters by default and the board automatically starts after it is reset. If you want to manually start the board, you can press <strong id="b1420714384268"><a name="b1420714384268"></a><a name="b1420714384268"></a>Enter</strong> in the countdown phase of the U-Boot startup to interrupt the automatic startup.</p>
</td>
</tr>
</tbody>
</table>
3. Enter reset and press Enter to restart the board. After the board is restarted successfully, press Enter. OHOS is displayed.
**Figure 10** Start the system<a name="fig10181006376"></a>
![](figures/qi1.png)
## Run the program.<a name="section5276734182615"></a>
In the root directory, run the **./bin/hello\_uart** command line to operate the demo program. The following figure shows the compilation result.
**Figure 11** Why are apps on my phone launching slowly?<a name="fig36537913815"></a>
![](figures/qidong.png)
# Development and Compilation<a name="EN-US_TOPIC_0000001054690948"></a>
The examples of the insensitive network configuration are stored in the applications/sample/wifi-iot/app/network\_config/network\_config\_sample.c file. According to, the service process of the non-sense distribution network can be divided into two parts: distribution network service life cycle management and distribution network service callback event processing.
**Figure 1** Sample flowchart of the non-sensitive power distribution network<a name="fig484117862220"></a>
![](figures/en-us_image_0000001054690925.png)
**Table 1** Event Function Description
<a name="table1663195102710"></a>
<table><thead align="left"><tr id="row96641751172718"><th class="cellrowborder" valign="top" width="23.330000000000002%" id="mcps1.2.3.1.1"><p id="p666412518277"><a name="p666412518277"></a><a name="p666412518277"></a><strong id="b1189877390111025"><a name="b1189877390111025"></a><a name="b1189877390111025"></a>Event Type</strong></p>
</th>
<th class="cellrowborder" valign="top" width="76.67%" id="mcps1.2.3.1.2"><p id="p12664165117270"><a name="p12664165117270"></a><a name="p12664165117270"></a>Function</p>
</th>
</tr>
</thead>
<tbody><tr id="row7371114142512"><td class="cellrowborder" valign="top" width="23.330000000000002%" headers="mcps1.2.3.1.1 "><p id="p11371101411253"><a name="p11371101411253"></a><a name="p11371101411253"></a>GetPinCode</p>
</td>
<td class="cellrowborder" valign="top" width="76.67%" headers="mcps1.2.3.1.2 "><p id="p83711414132520"><a name="p83711414132520"></a><a name="p83711414132520"></a>This interface is used to establish a secure channel between a device and a mobile phone. It is used for callback during encryption key negotiation. The security PIN must be preset.</p>
</td>
</tr>
<tr id="row17664185116276"><td class="cellrowborder" valign="top" width="23.330000000000002%" headers="mcps1.2.3.1.1 "><p id="p0664251192719"><a name="p0664251192719"></a><a name="p0664251192719"></a>ParseNetCfgData</p>
</td>
<td class="cellrowborder" valign="top" width="76.67%" headers="mcps1.2.3.1.2 "><p id="p116642051192713"><a name="p116642051192713"></a><a name="p116642051192713"></a>After a connection is set up between the device and mobile phone, the mobile app can send the SSID password to the device. After receiving an SSID password message from a mobile phone, the device invokes this interface to notify the device application.</p>
</td>
</tr>
<tr id="row1766465120271"><td class="cellrowborder" valign="top" width="23.330000000000002%" headers="mcps1.2.3.1.1 "><p id="p9664135118277"><a name="p9664135118277"></a><a name="p9664135118277"></a>OnDisconnect</p>
</td>
<td class="cellrowborder" valign="top" width="76.67%" headers="mcps1.2.3.1.2 "><p id="p14481135185914"><a name="p14481135185914"></a><a name="p14481135185914"></a>The device is disconnected from the mobile phone in the following scenarios:</p>
<a name="ol88722338115"></a><a name="ol88722338115"></a><ol id="ol88722338115"><li>After sending the SSID password, the mobile app sends a disconnection command to the device.</li><li>The heartbeat between the device and the NAN channel of the mobile phone times out, and the device proactively disconnects from the NAN channel.</li></ol>
</td>
</tr>
<tr id="row5664175192720"><td class="cellrowborder" valign="top" width="23.330000000000002%" headers="mcps1.2.3.1.1 "><p id="p3664165114278"><a name="p3664165114278"></a><a name="p3664165114278"></a>RecvRawData</p>
</td>
<td class="cellrowborder" valign="top" width="76.67%" headers="mcps1.2.3.1.2 "><p id="p1766495116277"><a name="p1766495116277"></a><a name="p1766495116277"></a>After the device establishes a connection to the mobile phone, the mobile phone app may send a custom message (for example, a control message) to the device. After receiving such a message, the device transfers the message to the device application through this interface. The device application calls the SendRawData API to send a response to the application.</p>
</td>
</tr>
<tr id="row5585164917297"><td class="cellrowborder" valign="top" width="23.330000000000002%" headers="mcps1.2.3.1.1 "><p id="p3586149102911"><a name="p3586149102911"></a><a name="p3586149102911"></a>NotifyNetCfgStatus</p>
</td>
<td class="cellrowborder" valign="top" width="76.67%" headers="mcps1.2.3.1.2 "><p id="p11586194992912"><a name="p11586194992912"></a><a name="p11586194992912"></a>After a device is successfully connected to a mobile phone, this interface is used to instruct the device application to blink or light the indicator to notify the device that the device is in the network configuration state.</p>
</td>
</tr>
</tbody>
</table>
## Distribution network service lifecycle management<a name="section114323217503"></a>
Distribution network service life cycle management includes creation and release of distribution network services.
1. Before the network distribution starts, complete network distribution event registration \(configure the callback function\), set the SoftAp hotspot parameters, and start the network distribution service.
The network configuration callback event consists of four callback functions: GetPinCode, ParseNetCfgData, OnDisconnect, RecvRawData and NotifyNetCfgStatus. This interface is invoked when the network configuration service receives the SSID message, connection release message, second control message, and connection setup message from the mobile phone. You are advised to register all event callback interfaces. If you do not need to pay attention to an event callback interface, you can implement an empty function or set it to NULL, and then register the event by using the RegNetCfgCallback function.
When setting the hotspot parameters of the SoftAP, pay attention to the input parameters of the int SetSoftAPParameter\(const struct SoftAPParam \*param\) function. For details, see the API description of the NetcfgService module. Note: If the SoftAP does not need to be enabled for the network configuration service, set all the values of the ssid field to 0.
When starting the network configuration service, pay attention to the three input parameters of the int StartNetCfg\(const struct DevInfo \*devInfoList, unsigned int listSize, enum NetCfgType mode\) function.
**Table 2** Parameter structure of the int StartNetCfg type
<a name="table0623181212572"></a>
<table><thead align="left"><tr id="row12624141285711"><th class="cellrowborder" valign="top" width="13.41%" id="mcps1.2.3.1.1"><p id="p7624181255719"><a name="p7624181255719"></a><a name="p7624181255719"></a>Input Parameter</p>
</th>
<th class="cellrowborder" valign="top" width="86.59%" id="mcps1.2.3.1.2"><p id="p1062451285719"><a name="p1062451285719"></a><a name="p1062451285719"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row136241912185720"><td class="cellrowborder" valign="top" width="13.41%" headers="mcps1.2.3.1.1 "><p id="p2624171213579"><a name="p2624171213579"></a><a name="p2624171213579"></a>devInfoList</p>
</td>
<td class="cellrowborder" valign="top" width="86.59%" headers="mcps1.2.3.1.2 "><p id="p116243127579"><a name="p116243127579"></a><a name="p116243127579"></a>Indicates the device information list. Currently, the device information to be configured includes productId and sn. The device information is configured in the format of key|value. Example:</p>
<p id="p72329935618"><a name="p72329935618"></a><a name="p72329935618"></a>struct DevInfo devInfo[2];</p>
<p id="p132323985613"><a name="p132323985613"></a><a name="p132323985613"></a>memset(&amp;devInfo, 0, sizeof(devInfo));</p>
<p id="p1623219105610"><a name="p1623219105610"></a><a name="p1623219105610"></a>devInfo[0].key = "productId";</p>
<p id="p1825117171578"><a name="p1825117171578"></a><a name="p1825117171578"></a>devInfo[0].value = "1";</p>
<p id="p142325955618"><a name="p142325955618"></a><a name="p142325955618"></a>devInfo[1].key = "sn";</p>
<p id="p102322945618"><a name="p102322945618"></a><a name="p102322945618"></a>devInfo[1].value = "01234567890123456";</p>
</td>
</tr>
<tr id="row4624201265712"><td class="cellrowborder" valign="top" width="13.41%" headers="mcps1.2.3.1.1 "><p id="p7624101235711"><a name="p7624101235711"></a><a name="p7624101235711"></a>listSize</p>
</td>
<td class="cellrowborder" valign="top" width="86.59%" headers="mcps1.2.3.1.2 "><p id="p1262418129576"><a name="p1262418129576"></a><a name="p1262418129576"></a>Number of parameters in the device information list, that is, the size of the devInfo array. Ensure that the size of the devInfo array is correct.</p>
</td>
</tr>
<tr id="row762410128574"><td class="cellrowborder" valign="top" width="13.41%" headers="mcps1.2.3.1.1 "><p id="p156242122577"><a name="p156242122577"></a><a name="p156242122577"></a>mode</p>
</td>
<td class="cellrowborder" valign="top" width="86.59%" headers="mcps1.2.3.1.2 "><p id="p11624612145711"><a name="p11624612145711"></a><a name="p11624612145711"></a>Indicates the network configuration mode. Currently, two network configuration modes are provided: single SoftAP network configuration mode and both SoftAP and non-sensitive network configuration mode. Device application developers can select a network configuration mode as required.</p>
</td>
</tr>
</tbody>
</table>
>![](public_sys-resources/icon-caution.gif) **CAUTION:**
>To ensure the normal use of the perception-free network configuration mode, ensure that the enabled AP interface works on channel 6, which complies with the NAN protocol.
Set SoftAp parameters, register the network configuration event, and start the network configuration service. The following is the code for starting the network configuration service \(using the simultaneous NAN and SoftAp network configuration mode as an example\):
```
static void *SampleBizTask(const char *arg)
{
(void)arg;
int ret;
LedInit();
/*Set the transmit power for the NAN safe distance.*/
ret = SetSafeDistancePower(POWER_NUM);
if (ret != 0) {
printf("[sample] Set safe distance power failed\n");
return NULL;
}
/* Set the SoftAP hotspot configuration parameters. In the example, the SSID and encryption type are set to open. */
struct SoftAPParam config = {0};
memset_s(&config, sizeof(struct SoftAPParam), 0, sizeof(struct SoftAPParam));
strncpy_s(config.ssid, sizeof(config.ssid), g_ssid, strlen(g_ssid));
config.authType = WIFI_SECURITY_OPEN;
ret = SetSoftAPParameter(&config);
if (ret != 0) {
printf("[sample] Set softAP parameters failed\n");
return NULL;
}
/* Register the network configuration event callback function. */
NetCfgCallback hook;
memset_s(&hook, sizeof(NetCfgCallback), 0, sizeof(NetCfgCallback));
hook.GetPinCode = GetPinCode;
hook.ParseNetCfgData = ParseNetCfgData;
hook.RecvRawData = RecvRawData;
hook.NotifyNetCfgStatus = NotifyNetCfgStatus;
ret = RegNetCfgCallback(&hook);
if (ret != 0) {
printf("[sample] Regist config callback failed\n");
return NULL;
}
/* Construct device information parameters. */
struct DevInfo devInfo[DEVICE_INFO_NUM];
memset_s(&devInfo, sizeof(devInfo), 0, sizeof(devInfo));
devInfo[0].key = "productId";
devInfo[1].key = "sn";
devInfo[0].value = g_productId;
devInfo[1].value = g_sn;
/*Start the distribution network service.*/
ret = StartNetCfg(devInfo, DEVICE_INFO_NUM, NETCFG_SOFTAP_NAN);
if (ret != 0) {
printf("[sample] Start config wifi fail.\n");
return NULL;
}
while (1) {
printf("[sample] main biz.\n");
usleep(SAMPLE_BIZ_SLEEP_TIME_US * SAMPLE_TIME_COUNT);
}
return NULL;
}
```
2. After the network configuration is complete, stop the network configuration service.
When a user does not need to configure the network, the int StopNetCfg\(void\) interface is used to release services and resources.
```
StopNetCfg();
```
## Processing of distribution network service callback events<a name="section5942133715548"></a>
After the distribution network service is successfully started in the previous step, the user program needs to wait for the event callback of the distribution network service.
1. ParseNetCfgData event callback indicates that after receiving the SSID and password information from the mobile phone, the network configuration service notifies the user program by using the function pointer. The following figure shows the process of processing SSID information in the sample.
```
int ParseNetCfgData(const struct WifiInfo *wifiInfo, const unsigned char *vendorData, unsigned int len)
{
printf("[NetCfgService] ParseWifiData vendorData len:%d\n", len);
if (wifiInfo == NULL) {
printf("[NetCfgService] wifiInfo is NULL\n");
return -1;
}
WifiDeviceConfig netConfig;
memset_s(&netConfig, sizeof(netConfig), 0, sizeof(netConfig));
if (memcpy_s(netConfig.ssid, WIFI_MAX_SSID_LEN, wifiInfo->ssid, strlen(wifiInfo->ssid)) != 0) {
printf("[NetCfgService] copy ssid failed\n");
return -1;
}
if (memcpy_s(netConfig.preSharedKey, WIFI_MAX_KEY_LEN, wifiInfo->pwd, strlen(wifiInfo->pwd)) != 0) {
printf("[NetCfgService] copy pwd failed\\n");
return -1;
}
if (vendorData != NULL) {
/* Developer-defined data, which is parsed and processed by the developer */
}
DealSsidPwd(&netConfig);
return 0;
}
```
2. OnDisconnect indicates that the application is notified that the mobile phone is disconnected from the device. This sample is not processed. You can plan it based on your service requirements.
```
static void DisconnectEventProc(void)
{
/* In the sample, only printing is performed. You can add service logic as required. */
printf("[sample] oncall disconnect event.\n");
}
```
3. RecvRawData: The mobile phone sends a customized message to the device. The message content is defined by developers. The distribution network service is responsible for end-to-end message transmission and secure encryption and decryption.
```
int RecvRawData(const char *data)
{
if (data == NULL) {
return -1;
}
printf("RecvRawData data : %s \n", data);
return 0;
}
```
4. NotifyNetCfgStatus indicates that the mobile phone is successfully connected to the network configuration service on the device.
```
void NotifyNetCfgStatus (enum NetCfgStatus status)
{
printf("[sample]Recv NetCfg Status : %d \n", status);
return;
}
```
## Compilation construction<a name="section87851752104812"></a>
1. The service macro HARMONY\_SUPPORT is defined in the /vendor/hisi/wifi-iot/hi3861/app/demo/src/app\_main.c file. At the end of the app\_main\(\) function, the entry function NetCfgSampleBiz\(\) of the non-sense distribution network sample is called to start the service of the non-sense distribution network sample.
```
#define HARMONY_SUPPORT
hi_void app_main(hi_void)
{
...
...
extern void NetCfgSampleBiz(void);
NetCfgSampleBiz();
}
```
2. Open the encryption and decryption module TEEHUKS, run the sh build.sh menuconfig command in the code directory /vendor/hisi/wifi-iot/hi3861/, and select and save the TEEHUKS support configuration under Security Settings, as shown in the following figure.
```
(Top)
Main menu
Target Chip --->
Security Settings --->
Factory Test Settings --->
BSP Settings --->
WiFi Settings --->
Third Party library --->
Lwip Settings --->
OTA Settings --->
Link Settings --->
Debug Log Settings --->
```
```
(Top) → Security Settings
Main menu
Signature Algorithm for bootloader and upgrade file (SHA256) --->
(0) boot ver(value form 0 to 16)
(0) kernel ver(value form 0 to 48)
[*] TEE HUKS support
[ ] TEE HUKS demo support
[ ] FLASH ENCRYPT support(only apply in WIFI CHIP_PKT_32K)
```
3. For details about how to compile the source code, see the Hi3861 Quick Start - Compilation.
# Development Guidelines<a name="EN-US_TOPIC_0000001054903130"></a> # Development Guidelines<a name="EN-US_TOPIC_0000001054903130"></a>
For details about basic concepts for camera development, see the camera development [Overview](en-us_topic_0000001051690589.md).
If you want to view the development sample effect first, skip this section and see [Use Case](use-case-5.md) for video preview. To customize application behavior, modify the sample code by referring to APIs described in this section.
- **[Photographing](photographing-3.md)** - **[Photographing](photographing-3.md)**
- **[Video Recording](video-recording-4.md)** - **[Video Recording](video-recording-4.md)**
......
# Development Guidelines<a name="EN-US_TOPIC_0000001055086133"></a> # Development Guidelines<a name="EN-US_TOPIC_0000001055086133"></a>
For details about basic concepts for camera development, see the camera development [Overview](en-us_topic_0000001051690589.md).
If you want to view the development sample effect first, skip this section and see [Use Case](use-case.md). To customize application behavior, modify the sample code by referring to APIs described in this section.
- **[Photographing](photographing.md)** - **[Photographing](photographing.md)**
- **[Video Recording](video-recording.md)** - **[Video Recording](video-recording.md)**
......
文件模式从 100755 更改为 100644
# FAQs<a name="EN-US_TOPIC_0000001054708517"></a>
1. Is there a global variable that can be accessed by all pages?
No such global variable is available for all pages.
2. How do I obtain DOM elements?
You can obtain DOM elements via the **ref** attribute. You can only use methods of the obtained elements and cannot change their attributes. The following figure shows an example.
```
<!--index.hml-->
<div class="container">
<!-- Set the ref attribute of the component to animator -->.
<image-animator class="image-player" ref="ainmator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator>
</div>
/* index.js */
export default {
data: {
images:[
{src:"common/frame1.png"},
{src:"common/frame2.png"},
{src:"common/frame3.png"}
]
},
handleClick(){
// Obtain the component through the $refs attribute. (The ref attribute of the component has been set to animator in the HML file.)
const animator = this.$refs.animator;
const state = animator.getState();
if(state == "paused"){
animator.resume();
}else if(state == "stopped"){
animator.start();
}else{
animator.pause();
}
}
}
```
3. How do I pass values between pages?
You can pass values through **params** of the **router.replace** method. The sample code is as follows:
Set **params** to the values to be passed on a page.
```
router.replace({
uri:'pages/detail/detail', // URI of the page to be redirected to.
params:{transferData:this.data} // Data to be transferred. You need to define the data amount and name.
});
```
Receive the passed values on another page.
```
onInit(){
const data = this.transferData; // Receive the transferred data by the onInit function.
}
```
4. How do I scroll a list to an item?
Call the **scrollTo** method of the list. The input parameter of this method is the index of the target item. You can specify an item index, or obtain the index through the **scrollend** event.
5. Does the **<text\>** component support multiple lines?
Yes. You can use the Enter key to start a new line. Alternatively, you can choose not to set the height attribute of the text, and the component automatically starts a new line based on the content.
6. Why is a component not displayed?
**Description**
The component added to the **.hml** file cannot be displayed.
**Possible Causes**
- The width and height of the component may not be set.
- The style setting may be incorrect.
**Solution**
\(1\) Check whether the width and height values are set explicitly.
\(2\) Check whether the style of the component is set correctly.
7. How do I implement scrolling on a page?
There are three ways to implement page scrolling: **scroll**, **<list\>**, or **<swiper\>**. For a root component with **scroll** set, the scrolling effect is automatically implemented when the component size exceeds the screen size. For details, see the _HarmonyOS Development Specifications_.
8. Why do not the **left** and **top** attributes take effect?
In addition to the root component, **left** and **top** attributes must work with the **<stack\>** component.
9. Why does dynamic binding not take effect?
The object or its attributes are not defined before dynamic binding.
10. How do I implement relative and absolute positioning?
You can use the **<div\>** and **<stack\>** \(with **top** and **left** attributes\) components.
11. How do I set component transparency?
For the **<image\>** component, set the **opacity** attribute to adjust the transparency. For other components, set the alpha value \(in RGBA color channels\) of a component.
12. How do I display or hide a component?
You can use **display**, **show**, or **if**. When an **if** clause evaluates to **false**, the corresponding component will be removed from the VDOM. When **show** is set to **false**, the component will be invisible during rendering, but will not be removed from the VDOM.
13. What are the precautions for using the **margin** attribute?
The **margin** attribute cannot be set for child components of the **<stack\>** component.
14. What are the precautions for event subscription?
Only one page exists when the application is running. Therefore, the **router.replace** function destroys the previous page and then creates a new one. For event subscription pages, the event should be subscribed every time a page is created, and unsubscribed before a page switch.
15. What are the precautions for using dynamic binding?
Do not use too many dynamic bindings because they consume too much memory.
16. How does the **loop** attribute take effect for **<swiper\>**?
If the total length of the child components, except for the first and last ones, is greater than the length of **<swiper\>**, the **loop** attribute takes effect.
17. What are the precautions for using an array?
Do not include too many elements in an array. Avoid frequent operations on a large array.
# FAQs<a name="EN-US_TOPIC_0000001051371841"></a>
1. Is there a global variable that can be accessed by all pages?
There is no such a global variable.
2. How do I obtain DOM elements?
You can obtain DOM elements via the **ref** attribute. You can use methods of the obtained elements but cannot change their attributes. The sample code is as follows:
```
<!--index.hml-->
<div class="container">
<!-- Set the ref attribute of the component to animator -->.
<image-animator class="image-player" ref="ainmator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator>
</div>
/* index.js */
export default {
data: {
images:[
{src:"common/frame1.png"},
{src:"common/frame2.png"},
{src:"common/frame3.png"}
]
},
handleClick(){
// Obtain the component through the $refs attribute. (The ref attribute of the component has been set to animator in the HML file.)
const animator = this.$refs.animator;
const state = animator.getState();
if(state == "paused"){
animator.resume();
}else if(state == "stopped"){
animator.start();
}else{
animator.pause();
}
}
}
```
3. How do I pass values between pages?
You can pass values through **params** of the **router.replace** method. The sample code is as follows:
Set **params** to the values to be passed on a page.
```
router.replace({
uri:'pages/detail/detail', // URI of the page to switch to.
params:{transferData:this.data} // Data to be transferred. You need to define the data amount and name.
});
```
Receive the passed values on another page.
```
onInit(){
const data = this.transferData; // Receive the transferred data by the onInit function.
}
```
4. How do I scroll a list to an item?
Call the **scrollTo** method of the list. The input parameter of this method is the index of the target item. You can specify an item index, or obtain the index through the **scrollend** event.
5. Does the **<text\>** component support multiple lines?
Yes. You can use the Enter key to start a new line. Alternatively, the component automatically starts a new line based on the content, without the need to set the height attribute of the text.
6. Why is the component added to the **.hml** file not displayed?
The width and height of the component may not be set, or the style setting may be incorrect.
Verify that the width and height values are set explicitly and the style of the component is set correctly.
7. How do I implement scrolling on a page?
There are three ways to implement page scrolling: **scroll**, **<list\>**, or **<swiper\>**. For a root component with **scroll** set, the scrolling effect is automatically implemented when the component size exceeds the screen size. For details, see the development specifications.
8. Why do not the **left** and **top** attributes take effect?
**left** and **top** attributes must work with the **<stack\>** component in addition to the root component.
9. Why does not dynamic binding take effect?
The object or its attributes are not defined before dynamic binding.
10. How do I implement relative and absolute positioning?
You can use the **<div\>** and **<stack\>** \(with **top** and **left** attributes\) components.
11. How do I set component opacity?
For the **<image\>** component, set the **opacity** attribute. For other components, set the alpha value \(in RGBA color channels\).
12. How do I display or hide a component?
You can use **display**, **show**, or **if**. When an **if** clause evaluates to **false**, the corresponding component will be removed from the VDOM. When **show** is set to **false**, the component will be invisible during rendering, but will not be removed from the VDOM.
13. What are the precautions for using the **margin** attribute?
The **margin** attribute cannot be set for child components of the **<stack\>** component.
14. What are the precautions for event subscription?
Only one page exists when the application is running. Therefore, the **router.replace** function destroys the previous page and then creates a new one. For event subscription pages, the event should be subscribed every time a page is created, and unsubscribed before page switching.
15. What are the precautions for using dynamic binding?
Do not use too many dynamic bindings because they consume too much memory.
16. How does the **loop** attribute take effect for **<swiper\>**?
If the total length of child components, except for the first and last ones, is greater than the length of **<swiper\>**, the **loop** attribute takes effect.
17. What are the precautions for using an array?
Do not include too many elements in an array. Avoid frequent operations on a large array.
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
此差异已折叠。
此差异已折叠。
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
此差异已折叠。
此差异已折叠。
此差异已折叠。
文件模式从 100755 更改为 100644
此差异已折叠。
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
此差异已折叠。
文件模式从 100755 更改为 100644
此差异已折叠。
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
此差异已折叠。
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
此差异已折叠。
文件模式从 100755 更改为 100644
此差异已折叠。
此差异已折叠。
此差异已折叠。
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
文件模式从 100755 更改为 100644
文件模式从 100644 更改为 100755
文件模式从 100644 更改为 100755
文件模式从 100644 更改为 100755
文件模式从 100755 更改为 100644
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册